Merge "Use raw MotionEvent coordinates when tracking velocity"
diff --git a/Android.bp b/Android.bp
index faad6f3..d94bd84 100644
--- a/Android.bp
+++ b/Android.bp
@@ -152,9 +152,10 @@
         ":libcamera_client_framework_aidl",
         "core/java/android/hardware/IConsumerIrService.aidl",
         "core/java/android/hardware/ISerialManager.aidl",
+        "core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl",
+        "core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl",
         "core/java/android/hardware/biometrics/IBiometricService.aidl",
         "core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl",
-        "core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl",
         "core/java/android/hardware/biometrics/IBiometricServiceLockoutResetCallback.aidl",
         "core/java/android/hardware/display/IDisplayManager.aidl",
         "core/java/android/hardware/display/IDisplayManagerCallback.aidl",
@@ -195,6 +196,7 @@
         "core/java/android/hardware/radio/ITunerCallback.aidl",
         "core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl",
         "core/java/android/hardware/usb/IUsbManager.aidl",
+        "core/java/android/hardware/usb/IUsbSerialReader.aidl",
         "core/java/android/net/ICaptivePortal.aidl",
         "core/java/android/net/IConnectivityManager.aidl",
         "core/java/android/net/IIpConnectivityMetrics.aidl",
@@ -558,9 +560,10 @@
         "telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl",
         "telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl",
         "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl",
+        "telephony/java/com/android/internal/telephony/IRcs.aidl",
         "telephony/java/com/android/internal/telephony/ISms.aidl",
         "telephony/java/com/android/internal/telephony/ISub.aidl",
-        "telephony/java/com/android/internal/telephony/IAnas.aidl",
+        "telephony/java/com/android/internal/telephony/IAns.aidl",
         "telephony/java/com/android/internal/telephony/ITelephony.aidl",
         "telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl",
         "telephony/java/com/android/internal/telephony/IWapPushManager.aidl",
@@ -612,6 +615,7 @@
         ":netd_aidl",
         ":vold_aidl",
         ":installd_aidl",
+        ":dumpstate_aidl",
 
         "lowpan/java/android/net/lowpan/ILowpanEnergyScanCallback.aidl",
         "lowpan/java/android/net/lowpan/ILowpanNetScanCallback.aidl",
@@ -658,6 +662,7 @@
         include_dirs: [
             "system/update_engine/binder_bindings",
             "frameworks/native/aidl/binder",
+            "frameworks/native/cmds/dumpstate/binder",
             "frameworks/av/camera/aidl",
             "frameworks/av/media/libaudioclient/aidl",
             "frameworks/native/aidl/gui",
@@ -680,9 +685,6 @@
 
     no_framework_libs: true,
     libs: [
-        "conscrypt",
-        "okhttp",
-        "bouncycastle",
         "ext",
     ],
 
@@ -702,7 +704,9 @@
         "android.hardware.vibrator-V1.2-java",
         "android.hardware.wifi-V1.0-java-constants",
         "android.hardware.radio-V1.0-java",
+        "android.hardware.radio-V1.3-java",
         "android.hardware.usb.gadget-V1.0-java",
+        "netd_aidl_interface-java",
     ],
 
     // Loaded with System.loadLibrary by android.view.textclassifier
@@ -832,7 +836,6 @@
         "cmds/statsd/src/**/*.proto",
         "core/proto/**/*.proto",
         "libs/incident/proto/**/*.proto",
-        "proto/src/stats_enums.proto",
     ],
     proto: {
         include_dirs: ["external/protobuf/src"],
@@ -870,7 +873,6 @@
     srcs: [
         "core/proto/**/*.proto",
         "libs/incident/proto/android/os/**/*.proto",
-        "proto/src/stats_enums.proto",
     ],
     // Protos have lots of MissingOverride and similar.
     errorprone: {
@@ -896,7 +898,6 @@
     srcs: [
         "core/proto/**/*.proto",
         "libs/incident/**/*.proto",
-        "proto/src/stats_enums.proto",
     ],
 
     target: {
@@ -1093,14 +1094,13 @@
      "-federationapi SupportLib $(location current/support-api.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) " +
      // Federate Support Library references against local API file.
      "-federate SupportLib https://developer.android.com " +
      "-federationapi SupportLib $(location current/support-api.txt) "
 
 framework_docs_only_libs = [
-    "conscrypt",
-    "bouncycastle",
     "voip-common",
     "android.test.mock",
     "android-support-annotations",
@@ -1180,7 +1180,8 @@
 
 doc_defaults {
     name: "framework-docs-default",
-    libs: framework_docs_only_libs,
+    libs: framework_docs_only_libs +
+         ["stub-annotations"],
     html_dirs: [
         "docs/html",
     ],
@@ -1220,11 +1221,6 @@
     srcs_lib_whitelist_dirs: frameworks_base_subdirs,
     srcs_lib_whitelist_pkgs: packages_to_document,
     libs: [
-        "core-oj",
-        "core-libart",
-        "conscrypt",
-        "bouncycastle",
-        "okhttp",
         "ext",
         "framework",
         "voip-common",
@@ -1577,7 +1573,6 @@
         "core/java/org/apache/http/params/CoreConnectionPNames.java",
         "core/java/org/apache/http/params/HttpConnectionParams.java",
         "core/java/org/apache/http/params/HttpParams.java",
-        "core/java/android/net/http/HttpResponseCache.java",
         "core/java/android/net/http/SslCertificate.java",
         "core/java/android/net/http/SslError.java",
         "core/java/com/android/internal/util/HexDump.java",
diff --git a/Android.mk b/Android.mk
index d333074..770ec20 100644
--- a/Android.mk
+++ b/Android.mk
@@ -87,6 +87,7 @@
     frameworks/base/tools/hiddenapi/generate_hiddenapi_lists.py \
     frameworks/base/config/hiddenapi-light-greylist.txt \
     frameworks/base/config/hiddenapi-vendor-list.txt \
+    frameworks/base/config/hiddenapi-max-sdk-p-blacklist.txt \
     frameworks/base/config/hiddenapi-force-blacklist.txt \
     $(INTERNAL_PLATFORM_HIDDENAPI_PUBLIC_LIST) \
     $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST) \
@@ -98,6 +99,7 @@
 	    --input-greylists \
 	        frameworks/base/config/hiddenapi-light-greylist.txt \
 	        frameworks/base/config/hiddenapi-vendor-list.txt \
+	        frameworks/base/config/hiddenapi-max-sdk-p-blacklist.txt \
 	        <(comm -12 <(sort $(INTERNAL_PLATFORM_REMOVED_DEX_API_FILE)) \
 	                   $(INTERNAL_PLATFORM_HIDDENAPI_PRIVATE_LIST)) \
 	        $(PRIVATE_GREYLIST_INPUTS) \
@@ -111,6 +113,17 @@
 	$(call commit-change-for-toc,$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST))
 	$(call commit-change-for-toc,$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST))
 
+$(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA): \
+    frameworks/base/tools/hiddenapi/merge_csv.py \
+    $(PRIVATE_METADATA_INPUTS)
+	frameworks/base/tools/hiddenapi/merge_csv.py $(PRIVATE_METADATA_INPUTS) > $@
+
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_WHITELIST))
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST))
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_DARK_GREYLIST))
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST))
+$(call dist-for-goals,droidcore,$(INTERNAL_PLATFORM_HIDDENAPI_GREYLIST_METADATA))
+
 # Include subdirectory makefiles
 # ============================================================
 
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index ff40f75..5c21221 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -5,6 +5,7 @@
                       packages/PrintRecommendationService/
                       packages/PrintSpooler/
                       packages/PackageInstaller/
+                      packages/SystemUI/
                       services/print/
                       services/usb/
                       telephony/
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
index eed1db0..c742df3 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/CanvasPerfTest.java
@@ -17,14 +17,14 @@
 package android.graphics.perftests;
 
 import android.graphics.Bitmap;
-import android.graphics.Color;
 import android.graphics.Bitmap.Config;
+import android.graphics.Color;
 import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.support.test.filters.LargeTest;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -43,7 +43,7 @@
         RenderNode child = RenderNode.create("child", null);
         child.setLeftTopRightBottom(50, 50, 100, 100);
 
-        DisplayListCanvas canvas = node.start(100, 100);
+        RecordingCanvas canvas = node.start(100, 100);
         node.end(canvas);
         canvas = child.start(50, 50);
         canvas.drawColor(Color.WHITE);
@@ -70,7 +70,7 @@
         BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         RenderNode node = RenderNode.create("benchmark", null);
 
-        DisplayListCanvas canvas = node.start(100, 100);
+        RecordingCanvas canvas = node.start(100, 100);
         node.end(canvas);
         Bitmap bitmap = Bitmap.createBitmap(80, 80, Config.ARGB_8888);
         Paint paint = new Paint();
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java
index 3a4fc72..f9c3758 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/OutlinePerfTest.java
@@ -20,7 +20,6 @@
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.support.test.filters.LargeTest;
-import android.view.RenderNode;
 
 import org.junit.Rule;
 import org.junit.Test;
diff --git a/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java b/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
index a283e06..d18aa51 100644
--- a/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
+++ b/apct-tests/perftests/core/src/android/graphics/perftests/RenderNodePerfTest.java
@@ -17,17 +17,15 @@
 package android.graphics.perftests;
 
 import android.graphics.Outline;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.support.test.filters.LargeTest;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 
 import org.junit.Rule;
 import org.junit.Test;
 
-import java.util.ArrayList;
-
 @LargeTest
 public class RenderNodePerfTest {
     @Rule
@@ -73,7 +71,7 @@
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         RenderNode node = RenderNode.create("LinearLayout", null);
         while (state.keepRunning()) {
-            DisplayListCanvas canvas = node.start(100, 100);
+            RecordingCanvas canvas = node.start(100, 100);
             node.end(canvas);
         }
     }
@@ -82,7 +80,7 @@
     public void testStartEndDeepHierarchy() {
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         RenderNode[] nodes = new RenderNode[30];
-        DisplayListCanvas[] canvases = new DisplayListCanvas[nodes.length];
+        RecordingCanvas[] canvases = new RecordingCanvas[nodes.length];
         for (int i = 0; i < nodes.length; i++) {
             nodes[i] = RenderNode.create("LinearLayout", null);
         }
diff --git a/apct-tests/perftests/core/src/android/os/CpuUsageTrackingPerfTest.java b/apct-tests/perftests/core/src/android/os/CpuUsageTrackingPerfTest.java
new file mode 100644
index 0000000..4961b4f
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/os/CpuUsageTrackingPerfTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.os;
+
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+
+/**
+ * Performance tests collecting CPU data different mechanisms.
+ */
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class CpuUsageTrackingPerfTest {
+    @Rule
+    public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+    @Test
+    public void timeSystemThread() {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        Binder b = new Binder();
+        while (state.keepRunning()) {
+            SystemClock.currentThreadTimeMicro();
+        }
+    }
+
+    @Test
+    public void timeReadStatFileDirectly() throws Exception {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        // CPU usage by frequency for this pid. Data is in text format.
+        final String procFile = "/proc/self/stat";
+        while (state.keepRunning()) {
+            byte[] data = Files.readAllBytes(Paths.get(procFile));
+        }
+    }
+
+    @Test
+    public void timeReadPidProcDirectly() throws Exception {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        // CPU usage by frequency for this pid. Data is in text format.
+        final String procFile = "/proc/self/time_in_state";
+        while (state.keepRunning()) {
+            byte[] data = Files.readAllBytes(Paths.get(procFile));
+        }
+    }
+
+    @Test
+    public void timeReadThreadProcDirectly() throws Exception {
+        final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+        // CPU usage by frequency for this UID. Data is in text format.
+        final String procFile = "/proc/self/task/" + android.os.Process.myTid()
+                + "/time_in_state";
+        while (state.keepRunning()) {
+            byte[] data = Files.readAllBytes(Paths.get(procFile));
+        }
+    }
+}
diff --git a/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
index 64f2800..9245c1b 100644
--- a/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/BoringLayoutCreateDrawPerfTest.java
@@ -18,12 +18,12 @@
 import static android.text.Layout.Alignment.ALIGN_NORMAL;
 
 import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.support.test.filters.LargeTest;
 import android.text.NonEditableTextGenerator.TextType;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -120,7 +120,7 @@
         while (state.keepRunning()) {
 
             state.pauseTiming();
-            final DisplayListCanvas canvas = node.start(1200, 200);
+            final RecordingCanvas canvas = node.start(1200, 200);
             final int save = canvas.save();
             if (!mCached) Canvas.freeTextLayoutCaches();
             state.resumeTiming();
diff --git a/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
index ad5a34e..a7972f5 100644
--- a/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/PaintMeasureDrawPerfTest.java
@@ -17,11 +17,11 @@
 
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.support.test.filters.LargeTest;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -107,7 +107,7 @@
         while (state.keepRunning()) {
 
             state.pauseTiming();
-            final DisplayListCanvas canvas = node.start(1200, 200);
+            final RecordingCanvas canvas = node.start(1200, 200);
             final int save = canvas.save();
             if (!mCached) Canvas.freeTextLayoutCaches();
             state.resumeTiming();
diff --git a/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java b/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
index d98df05..00a6267 100644
--- a/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
+++ b/apct-tests/perftests/core/src/android/text/PrecomputedTextMemoryUsageTest.java
@@ -16,32 +16,16 @@
 
 package android.text;
 
-import static android.text.TextDirectionHeuristics.LTR;
-
-import android.perftests.utils.BenchmarkState;
-import android.perftests.utils.PerfStatusReporter;
-
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
-
 import android.app.Activity;
 import android.os.Bundle;
 import android.support.test.InstrumentationRegistry;
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Typeface;
-import android.text.Layout;
-import android.text.style.TextAppearanceSpan;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.nio.CharBuffer;
-import java.util.Random;
 import java.util.Locale;
 
 @LargeTest
diff --git a/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java b/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java
index 1cd0ae1..33b1a47 100644
--- a/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/PrecomputedTextPerfTest.java
@@ -16,30 +16,16 @@
 
 package android.text;
 
-import static android.text.TextDirectionHeuristics.LTR;
-
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-
 import android.support.test.filters.LargeTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Typeface;
-import android.text.Layout;
-import android.text.style.TextAppearanceSpan;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.nio.CharBuffer;
-import java.util.Random;
-
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class PrecomputedTextPerfTest {
diff --git a/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java b/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
index deb2b0a..b40dd6b 100644
--- a/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/StaticLayoutCreateDrawPerfTest.java
@@ -18,12 +18,12 @@
 import static android.text.Layout.Alignment.ALIGN_NORMAL;
 
 import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.support.test.filters.LargeTest;
 import android.text.NonEditableTextGenerator.TextType;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -119,7 +119,7 @@
         while (state.keepRunning()) {
 
             state.pauseTiming();
-            final DisplayListCanvas canvas = node.start(1200, 200);
+            final RecordingCanvas canvas = node.start(1200, 200);
             int save = canvas.save();
             if (!mCached) Canvas.freeTextLayoutCaches();
             state.resumeTiming();
diff --git a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
index e1a38a0..e224fa3 100644
--- a/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java
@@ -16,30 +16,19 @@
 
 package android.text;
 
-import static android.text.TextDirectionHeuristics.LTR;
-
+import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
-
 import android.support.test.filters.LargeTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Typeface;
-import android.text.Layout;
-import android.text.style.TextAppearanceSpan;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.nio.CharBuffer;
-import java.util.Random;
-
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class StaticLayoutPerfTest {
@@ -256,7 +245,7 @@
             state.pauseTiming();
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             state.resumeTiming();
 
             layout.draw(c);
@@ -272,7 +261,7 @@
             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             state.resumeTiming();
 
             layout.draw(c);
@@ -288,7 +277,7 @@
             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             state.resumeTiming();
 
             layout.draw(c);
@@ -304,7 +293,7 @@
             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             Canvas.freeTextLayoutCaches();
             state.resumeTiming();
 
@@ -321,7 +310,7 @@
             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             Canvas.freeTextLayoutCaches();
             state.resumeTiming();
 
@@ -339,7 +328,7 @@
                     mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             state.resumeTiming();
 
             layout.draw(c);
@@ -356,7 +345,7 @@
                     mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             state.resumeTiming();
 
             layout.draw(c);
@@ -373,7 +362,7 @@
                     mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             Canvas.freeTextLayoutCaches();
             state.resumeTiming();
 
@@ -391,7 +380,7 @@
                     mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT);
             final StaticLayout layout =
                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
-            final DisplayListCanvas c = node.start(1200, 200);
+            final RecordingCanvas c = node.start(1200, 200);
             Canvas.freeTextLayoutCaches();
             state.resumeTiming();
 
diff --git a/apct-tests/perftests/core/src/android/text/TextPerfUtils.java b/apct-tests/perftests/core/src/android/text/TextPerfUtils.java
index aa505b5..22e516a 100644
--- a/apct-tests/perftests/core/src/android/text/TextPerfUtils.java
+++ b/apct-tests/perftests/core/src/android/text/TextPerfUtils.java
@@ -16,32 +16,15 @@
 
 package android.text;
 
-import static android.text.TextDirectionHeuristics.LTR;
-
-import android.perftests.utils.BenchmarkState;
-import android.perftests.utils.PerfStatusReporter;
-
-import android.support.test.filters.LargeTest;
-import android.support.test.runner.AndroidJUnit4;
-
 import android.content.res.ColorStateList;
-import android.graphics.Canvas;
 import android.graphics.Typeface;
 import android.icu.text.UnicodeSet;
 import android.icu.text.UnicodeSetIterator;
-import android.text.Layout;
 import android.text.style.TextAppearanceSpan;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
 
 import java.nio.CharBuffer;
-import java.util.Random;
 import java.util.ArrayList;
+import java.util.Random;
 
 public class TextPerfUtils {
 
diff --git a/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java b/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
index 4bbe404..25cc707 100644
--- a/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
+++ b/apct-tests/perftests/core/src/android/text/TextViewSetTextMeasurePerfTest.java
@@ -19,13 +19,13 @@
 import static android.view.View.MeasureSpec.UNSPECIFIED;
 
 import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.text.NonEditableTextGenerator.TextType;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 import android.widget.TextView;
 
 import org.junit.Rule;
@@ -128,7 +128,7 @@
         while (state.keepRunning()) {
 
             state.pauseTiming();
-            final DisplayListCanvas canvas = node.start(1200, 200);
+            final RecordingCanvas canvas = node.start(1200, 200);
             int save = canvas.save();
             textView.setTextLocale(Locale.UK);
             textView.setTextLocale(Locale.US);
diff --git a/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java b/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
index dc34b7f..434b8e5 100644
--- a/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
+++ b/apct-tests/perftests/core/src/android/widget/TextViewPrecomputedTextPerfTest.java
@@ -16,46 +16,29 @@
 
 package android.widget;
 
-import static android.view.View.MeasureSpec.AT_MOST;
-import static android.view.View.MeasureSpec.EXACTLY;
-import static android.view.View.MeasureSpec.UNSPECIFIED;
+import static android.widget.TextView.UNKNOWN_BORING;
 
 import android.content.Context;
-import android.content.res.ColorStateList;
-import android.graphics.Typeface;
 import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.LargeTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.text.PrecomputedText;
-import android.text.Layout;
 import android.text.BoringLayout;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
+import android.text.Layout;
+import android.text.PrecomputedText;
 import android.text.TextPaint;
-import android.text.style.TextAppearanceSpan;
-import android.view.LayoutInflater;
 import android.text.TextPerfUtils;
 import android.view.View.MeasureSpec;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-
-import com.android.perftests.core.R;
-
-import java.util.Random;
-import java.util.Locale;
 
 import org.junit.Before;
-import org.junit.Test;
 import org.junit.Rule;
+import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import static org.junit.Assert.assertTrue;
-
-import static android.widget.TextView.UNKNOWN_BORING;
-
 @LargeTest
 @RunWith(AndroidJUnit4.class)
 public class TextViewPrecomputedTextPerfTest {
@@ -360,7 +343,7 @@
             textView.setText(text);
             textView.measure(width, height);
             textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
-            final DisplayListCanvas c = node.start(
+            final RecordingCanvas c = node.start(
                 textView.getMeasuredWidth(), textView.getMeasuredHeight());
             textView.nullLayouts();
             Canvas.freeTextLayoutCaches();
@@ -386,7 +369,7 @@
             textView.setText(text);
             textView.measure(width, height);
             textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
-            final DisplayListCanvas c = node.start(
+            final RecordingCanvas c = node.start(
                 textView.getMeasuredWidth(), textView.getMeasuredHeight());
             textView.nullLayouts();
             Canvas.freeTextLayoutCaches();
@@ -414,7 +397,7 @@
             textView.setText(text);
             textView.measure(width, height);
             textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
-            final DisplayListCanvas c = node.start(
+            final RecordingCanvas c = node.start(
                 textView.getMeasuredWidth(), textView.getMeasuredHeight());
             textView.nullLayouts();
             Canvas.freeTextLayoutCaches();
@@ -443,7 +426,7 @@
             textView.setText(text);
             textView.measure(width, height);
             textView.layout(0, 0, textView.getMeasuredWidth(), textView.getMeasuredHeight());
-            final DisplayListCanvas c = node.start(
+            final RecordingCanvas c = node.start(
                 textView.getMeasuredWidth(), textView.getMeasuredHeight());
             textView.nullLayouts();
             Canvas.freeTextLayoutCaches();
diff --git a/api/current.txt b/api/current.txt
index e6a31af..870c020 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -17,12 +17,14 @@
     field public static final java.lang.String ACCESS_NOTIFICATION_POLICY = "android.permission.ACCESS_NOTIFICATION_POLICY";
     field public static final java.lang.String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
     field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
+    field public static final java.lang.String ACTIVITY_RECOGNITION = "android.permission.ACTIVITY_RECOGNITION";
     field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
     field public static final java.lang.String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
     field public static final java.lang.String BIND_AUTOFILL_SERVICE = "android.permission.BIND_AUTOFILL_SERVICE";
+    field public static final java.lang.String BIND_CALL_REDIRECTION_SERVICE = "android.permission.BIND_CALL_REDIRECTION_SERVICE";
     field public static final deprecated java.lang.String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
     field public static final java.lang.String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
     field public static final java.lang.String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
@@ -167,6 +169,7 @@
 
   public static final class Manifest.permission_group {
     ctor public Manifest.permission_group();
+    field public static final java.lang.String ACTIVITY_RECOGNITION = "android.permission-group.ACTIVITY_RECOGNITION";
     field public static final java.lang.String CALENDAR = "android.permission-group.CALENDAR";
     field public static final java.lang.String CALL_LOG = "android.permission-group.CALL_LOG";
     field public static final java.lang.String CAMERA = "android.permission-group.CAMERA";
@@ -280,7 +283,6 @@
     field public static final int allowBackup = 16843392; // 0x1010280
     field public static final int allowClearUserData = 16842757; // 0x1010005
     field public static final int allowEmbedded = 16843765; // 0x10103f5
-    field public static final int allowForceDark = 16844171; // 0x101058b
     field public static final int allowParallelSyncs = 16843570; // 0x1010332
     field public static final int allowSingleTap = 16843353; // 0x1010259
     field public static final int allowTaskReparenting = 16843268; // 0x1010204
@@ -635,6 +637,7 @@
     field public static final int fontVariationSettings = 16844144; // 0x1010570
     field public static final int fontWeight = 16844083; // 0x1010533
     field public static final int footerDividersEnabled = 16843311; // 0x101022f
+    field public static final int forceDarkAllowed = 16844172; // 0x101058c
     field public static final int forceHasOverlappingRendering = 16844065; // 0x1010521
     field public static final int foreground = 16843017; // 0x1010109
     field public static final int foregroundGravity = 16843264; // 0x1010200
@@ -774,11 +777,11 @@
     field public static final int isFeatureSplit = 16844123; // 0x101055b
     field public static final int isGame = 16843764; // 0x10103f4
     field public static final int isIndicator = 16843079; // 0x1010147
-    field public static final int isLightTheme = 16844175; // 0x101058f
+    field public static final int isLightTheme = 16844176; // 0x1010590
     field public static final int isModifier = 16843334; // 0x1010246
     field public static final int isRepeatable = 16843336; // 0x1010248
     field public static final int isScrollContainer = 16843342; // 0x101024e
-    field public static final int isSplitRequired = 16844176; // 0x1010590
+    field public static final int isSplitRequired = 16844177; // 0x1010591
     field public static final int isStatic = 16844122; // 0x101055a
     field public static final int isSticky = 16843335; // 0x1010247
     field public static final int isolatedProcess = 16843689; // 0x10103a9
@@ -938,7 +941,7 @@
     field public static final int minSdkVersion = 16843276; // 0x101020c
     field public static final int minWidth = 16843071; // 0x101013f
     field public static final int minimumHorizontalAngle = 16843901; // 0x101047d
-    field public static final int minimumUiTimeout = 16844174; // 0x101058e
+    field public static final int minimumUiTimeout = 16844175; // 0x101058f
     field public static final int minimumVerticalAngle = 16843902; // 0x101047e
     field public static final int mipMap = 16843725; // 0x10103cd
     field public static final int mirrorForRtl = 16843726; // 0x10103ce
@@ -978,10 +981,10 @@
     field public static final int onClick = 16843375; // 0x101026f
     field public static final int oneshot = 16843159; // 0x1010197
     field public static final int opacity = 16843550; // 0x101031e
-    field public static final int opticalInsetBottom = 16844170; // 0x101058a
-    field public static final int opticalInsetLeft = 16844167; // 0x1010587
-    field public static final int opticalInsetRight = 16844169; // 0x1010589
-    field public static final int opticalInsetTop = 16844168; // 0x1010588
+    field public static final int opticalInsetBottom = 16844171; // 0x101058b
+    field public static final int opticalInsetLeft = 16844168; // 0x1010588
+    field public static final int opticalInsetRight = 16844170; // 0x101058a
+    field public static final int opticalInsetTop = 16844169; // 0x1010589
     field public static final int order = 16843242; // 0x10101ea
     field public static final int orderInCategory = 16843231; // 0x10101df
     field public static final int ordering = 16843490; // 0x10102e2
@@ -997,6 +1000,7 @@
     field public static final int overlapAnchor = 16843874; // 0x1010462
     field public static final int overridesImplicitlyEnabledSubtype = 16843682; // 0x10103a2
     field public static final int packageNames = 16843649; // 0x1010381
+    field public static final int packageType = 16844167; // 0x1010587
     field public static final int padding = 16842965; // 0x10100d5
     field public static final int paddingBottom = 16842969; // 0x10100d9
     field public static final int paddingEnd = 16843700; // 0x10103b4
@@ -1195,6 +1199,7 @@
     field public static final deprecated int selectedWeekBackgroundColor = 16843586; // 0x1010342
     field public static final int sessionService = 16843837; // 0x101043d
     field public static final int settingsActivity = 16843301; // 0x1010225
+    field public static final int settingsSliceUri = 16844179; // 0x1010593
     field public static final int setupActivity = 16843766; // 0x10103f6
     field public static final int shadowColor = 16843105; // 0x1010161
     field public static final int shadowDx = 16843106; // 0x1010162
@@ -1306,7 +1311,7 @@
     field public static final int summaryColumn = 16843426; // 0x10102a2
     field public static final int summaryOff = 16843248; // 0x10101f0
     field public static final int summaryOn = 16843247; // 0x10101ef
-    field public static final int supportsAmbientMode = 16844172; // 0x101058c
+    field public static final int supportsAmbientMode = 16844173; // 0x101058d
     field public static final int supportsAssist = 16844016; // 0x10104f0
     field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1
     field public static final int supportsLocalInteraction = 16844047; // 0x101050f
@@ -1399,6 +1404,7 @@
     field public static final int textFilterEnabled = 16843007; // 0x10100ff
     field public static final int textFontWeight = 16844165; // 0x1010585
     field public static final int textIsSelectable = 16843542; // 0x1010316
+    field public static final int textLocale = 16844178; // 0x1010592
     field public static final int textOff = 16843045; // 0x1010125
     field public static final int textOn = 16843044; // 0x1010124
     field public static final int textScaleX = 16843089; // 0x1010151
@@ -5671,6 +5677,7 @@
     method public java.lang.CharSequence getName();
     method public android.net.Uri getSound();
     method public long[] getVibrationPattern();
+    method public boolean hasUserSetImportance();
     method public void setBypassDnd(boolean);
     method public void setDescription(java.lang.String);
     method public void setGroup(java.lang.String);
@@ -6315,6 +6322,7 @@
     method public android.content.pm.ServiceInfo getServiceInfo();
     method public java.lang.String getServiceName();
     method public java.lang.String getSettingsActivity();
+    method public android.net.Uri getSettingsSliceUri();
     method public boolean getShowMetadataInPreview();
     method public java.lang.CharSequence loadAuthor(android.content.pm.PackageManager) throws android.content.res.Resources.NotFoundException;
     method public java.lang.CharSequence loadContextDescription(android.content.pm.PackageManager) throws android.content.res.Resources.NotFoundException;
@@ -6518,6 +6526,8 @@
     method public java.util.List<java.lang.String> getDelegatedScopes(android.content.ComponentName, java.lang.String);
     method public java.lang.CharSequence getDeviceOwnerLockScreenInfo();
     method public java.lang.CharSequence getEndUserSessionMessage(android.content.ComponentName);
+    method public java.lang.String getGlobalPrivateDnsHost(android.content.ComponentName);
+    method public int getGlobalPrivateDnsMode(android.content.ComponentName);
     method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
     method public java.util.List<java.lang.String> getKeepUninstalledPackages(android.content.ComponentName);
     method public int getKeyguardDisabledFeatures(android.content.ComponentName);
@@ -6621,6 +6631,7 @@
     method public void setDelegatedScopes(android.content.ComponentName, java.lang.String, java.util.List<java.lang.String>);
     method public void setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.CharSequence);
     method public void setEndUserSessionMessage(android.content.ComponentName, java.lang.CharSequence);
+    method public void setGlobalPrivateDns(android.content.ComponentName, int, java.lang.String);
     method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
     method public void setKeepUninstalledPackages(android.content.ComponentName, java.util.List<java.lang.String>);
     method public boolean setKeyPairCertificate(android.content.ComponentName, java.lang.String, java.util.List<java.security.cert.Certificate>, boolean);
@@ -6735,14 +6746,21 @@
     field public static final java.lang.String EXTRA_PROVISIONING_SKIP_ENCRYPTION = "android.app.extra.PROVISIONING_SKIP_ENCRYPTION";
     field public static final java.lang.String EXTRA_PROVISIONING_SKIP_USER_CONSENT = "android.app.extra.PROVISIONING_SKIP_USER_CONSENT";
     field public static final java.lang.String EXTRA_PROVISIONING_TIME_ZONE = "android.app.extra.PROVISIONING_TIME_ZONE";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY = "android.app.extra.PROVISIONING_WIFI_ANONYMOUS_IDENTITY";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE = "android.app.extra.PROVISIONING_WIFI_CA_CERTIFICATE";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_DOMAIN = "android.app.extra.PROVISIONING_WIFI_DOMAIN";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_EAP_METHOD = "android.app.extra.PROVISIONING_WIFI_EAP_METHOD";
     field public static final java.lang.String EXTRA_PROVISIONING_WIFI_HIDDEN = "android.app.extra.PROVISIONING_WIFI_HIDDEN";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_IDENTITY = "android.app.extra.PROVISIONING_WIFI_IDENTITY";
     field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PAC_URL = "android.app.extra.PROVISIONING_WIFI_PAC_URL";
     field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PASSWORD = "android.app.extra.PROVISIONING_WIFI_PASSWORD";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PHASE2_AUTH = "android.app.extra.PROVISIONING_WIFI_PHASE2_AUTH";
     field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PROXY_BYPASS = "android.app.extra.PROVISIONING_WIFI_PROXY_BYPASS";
     field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PROXY_HOST = "android.app.extra.PROVISIONING_WIFI_PROXY_HOST";
     field public static final java.lang.String EXTRA_PROVISIONING_WIFI_PROXY_PORT = "android.app.extra.PROVISIONING_WIFI_PROXY_PORT";
     field public static final java.lang.String EXTRA_PROVISIONING_WIFI_SECURITY_TYPE = "android.app.extra.PROVISIONING_WIFI_SECURITY_TYPE";
     field public static final java.lang.String EXTRA_PROVISIONING_WIFI_SSID = "android.app.extra.PROVISIONING_WIFI_SSID";
+    field public static final java.lang.String EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE = "android.app.extra.PROVISIONING_WIFI_USER_CERTIFICATE";
     field public static final int FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY = 1; // 0x1
     field public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 2; // 0x2
     field public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 1; // 0x1
@@ -6790,6 +6808,10 @@
     field public static final int PERMISSION_POLICY_PROMPT = 0; // 0x0
     field public static final java.lang.String POLICY_DISABLE_CAMERA = "policy_disable_camera";
     field public static final java.lang.String POLICY_DISABLE_SCREEN_CAPTURE = "policy_disable_screen_capture";
+    field public static final int PRIVATE_DNS_MODE_OFF = 1; // 0x1
+    field public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2; // 0x2
+    field public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3; // 0x3
+    field public static final int PRIVATE_DNS_MODE_UNKNOWN = 0; // 0x0
     field public static final int RESET_PASSWORD_DO_NOT_ASK_CREDENTIALS_ON_BOOT = 2; // 0x2
     field public static final int RESET_PASSWORD_REQUIRE_ENTRY = 1; // 0x1
     field public static final int SKIP_SETUP_WIZARD = 1; // 0x1
@@ -9149,6 +9171,7 @@
     method public int bulkInsert(android.net.Uri, android.content.ContentValues[]);
     method public android.os.Bundle call(java.lang.String, java.lang.String, android.os.Bundle);
     method public android.net.Uri canonicalize(android.net.Uri);
+    method public final android.content.ContentProvider.CallingIdentity clearCallingIdentity();
     method public abstract int delete(android.net.Uri, java.lang.String, java.lang.String[]);
     method public void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public final java.lang.String getCallingPackage();
@@ -9176,6 +9199,7 @@
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], java.lang.String, java.lang.String[], java.lang.String, android.os.CancellationSignal);
     method public android.database.Cursor query(android.net.Uri, java.lang.String[], android.os.Bundle, android.os.CancellationSignal);
     method public boolean refresh(android.net.Uri, android.os.Bundle, android.os.CancellationSignal);
+    method public final void restoreCallingIdentity(android.content.ContentProvider.CallingIdentity);
     method protected final void setPathPermissions(android.content.pm.PathPermission[]);
     method protected final void setReadPermission(java.lang.String);
     method protected final void setWritePermission(java.lang.String);
@@ -9184,6 +9208,9 @@
     method public abstract int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]);
   }
 
+  public final class ContentProvider.CallingIdentity {
+  }
+
   public static abstract interface ContentProvider.PipeDataWriter<T> {
     method public abstract void writeDataToPipe(android.os.ParcelFileDescriptor, android.net.Uri, java.lang.String, android.os.Bundle, T);
   }
@@ -9298,6 +9325,7 @@
     method public final android.net.Uri insert(android.net.Uri, android.content.ContentValues);
     method public static boolean isSyncActive(android.accounts.Account, java.lang.String);
     method public static boolean isSyncPending(android.accounts.Account, java.lang.String);
+    method public android.graphics.Bitmap loadThumbnail(android.net.Uri, android.util.Size, android.os.CancellationSignal) throws java.io.IOException;
     method public void notifyChange(android.net.Uri, android.database.ContentObserver);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver, boolean);
     method public void notifyChange(android.net.Uri, android.database.ContentObserver, int);
@@ -9976,7 +10004,7 @@
     field public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT";
     field public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
     field public static final java.lang.String ACTION_INSTALL_FAILURE = "android.intent.action.INSTALL_FAILURE";
-    field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
+    field public static final deprecated java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
     field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
     field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
     field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN";
@@ -10049,7 +10077,7 @@
     field public static final java.lang.String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED";
     field public static final deprecated java.lang.String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED";
     field public static final deprecated java.lang.String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED";
-    field public static final java.lang.String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
+    field public static final deprecated java.lang.String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
     field public static final java.lang.String ACTION_USER_BACKGROUND = "android.intent.action.USER_BACKGROUND";
     field public static final java.lang.String ACTION_USER_FOREGROUND = "android.intent.action.USER_FOREGROUND";
     field public static final java.lang.String ACTION_USER_INITIALIZE = "android.intent.action.USER_INITIALIZE";
@@ -13253,6 +13281,7 @@
     method public void setPixels(int[], int, int, int, int, int, int);
     method public void setPremultiplied(boolean);
     method public void setWidth(int);
+    method public static android.graphics.Bitmap wrapHardwareBuffer(android.hardware.HardwareBuffer, android.graphics.ColorSpace);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.graphics.Bitmap> CREATOR;
     field public static final int DENSITY_NONE = 0; // 0x0
@@ -13397,6 +13426,8 @@
     method public void drawCircle(float, float, float, android.graphics.Paint);
     method public void drawColor(int);
     method public void drawColor(int, android.graphics.PorterDuff.Mode);
+    method public void drawDoubleRoundRect(android.graphics.RectF, float, float, android.graphics.RectF, float, float, android.graphics.Paint);
+    method public void drawDoubleRoundRect(android.graphics.RectF, float[], android.graphics.RectF, float[], android.graphics.Paint);
     method public void drawLine(float, float, float, float, android.graphics.Paint);
     method public void drawLines(float[], int, int, android.graphics.Paint);
     method public void drawLines(float[], android.graphics.Paint);
@@ -13748,6 +13779,7 @@
     method public static android.graphics.ImageDecoder.Source createSource(android.content.res.AssetManager, java.lang.String);
     method public static android.graphics.ImageDecoder.Source createSource(java.nio.ByteBuffer);
     method public static android.graphics.ImageDecoder.Source createSource(java.io.File);
+    method public static android.graphics.ImageDecoder.Source createSource(java.util.concurrent.Callable<android.content.res.AssetFileDescriptor>);
     method public static android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source, android.graphics.ImageDecoder.OnHeaderDecodedListener) throws java.io.IOException;
     method public static android.graphics.Bitmap decodeBitmap(android.graphics.ImageDecoder.Source) throws java.io.IOException;
     method public static android.graphics.drawable.Drawable decodeDrawable(android.graphics.ImageDecoder.Source, android.graphics.ImageDecoder.OnHeaderDecodedListener) throws java.io.IOException;
@@ -15287,20 +15319,9 @@
     method public java.nio.ByteBuffer getBuffer();
     method public java.io.File getFile();
     method public android.os.LocaleList getLocaleList();
+    method public int getSlant();
     method public int getTtcIndex();
     method public int getWeight();
-    method public boolean isItalic();
-    field public static final int FONT_WEIGHT_BLACK = 900; // 0x384
-    field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
-    field public static final int FONT_WEIGHT_EXTRA_BOLD = 800; // 0x320
-    field public static final int FONT_WEIGHT_EXTRA_LIGHT = 200; // 0xc8
-    field public static final int FONT_WEIGHT_LIGHT = 300; // 0x12c
-    field public static final int FONT_WEIGHT_MAX = 1000; // 0x3e8
-    field public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
-    field public static final int FONT_WEIGHT_MIN = 1; // 0x1
-    field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
-    field public static final int FONT_WEIGHT_SEMI_BOLD = 600; // 0x258
-    field public static final int FONT_WEIGHT_THIN = 100; // 0x64
   }
 
   public static class Font.Builder {
@@ -15313,7 +15334,7 @@
     method public android.graphics.fonts.Font build() throws java.io.IOException;
     method public android.graphics.fonts.Font.Builder setFontVariationSettings(java.lang.String);
     method public android.graphics.fonts.Font.Builder setFontVariationSettings(android.graphics.fonts.FontVariationAxis[]);
-    method public android.graphics.fonts.Font.Builder setItalic(boolean);
+    method public android.graphics.fonts.Font.Builder setSlant(int);
     method public android.graphics.fonts.Font.Builder setTtcIndex(int);
     method public android.graphics.fonts.Font.Builder setWeight(int);
   }
@@ -15329,6 +15350,26 @@
     method public android.graphics.fonts.FontFamily build();
   }
 
+  public final class FontStyle {
+    ctor public FontStyle();
+    ctor public FontStyle(int, int);
+    method public int getSlant();
+    method public int getWeight();
+    field public static final int FONT_SLANT_ITALIC = 1; // 0x1
+    field public static final int FONT_SLANT_UPRIGHT = 0; // 0x0
+    field public static final int FONT_WEIGHT_BLACK = 900; // 0x384
+    field public static final int FONT_WEIGHT_BOLD = 700; // 0x2bc
+    field public static final int FONT_WEIGHT_EXTRA_BOLD = 800; // 0x320
+    field public static final int FONT_WEIGHT_EXTRA_LIGHT = 200; // 0xc8
+    field public static final int FONT_WEIGHT_LIGHT = 300; // 0x12c
+    field public static final int FONT_WEIGHT_MAX = 1000; // 0x3e8
+    field public static final int FONT_WEIGHT_MEDIUM = 500; // 0x1f4
+    field public static final int FONT_WEIGHT_MIN = 1; // 0x1
+    field public static final int FONT_WEIGHT_NORMAL = 400; // 0x190
+    field public static final int FONT_WEIGHT_SEMI_BOLD = 600; // 0x258
+    field public static final int FONT_WEIGHT_THIN = 100; // 0x64
+  }
+
   public final class FontVariationAxis {
     ctor public FontVariationAxis(java.lang.String, float);
     method public static android.graphics.fonts.FontVariationAxis[] fromFontVariationSettings(java.lang.String);
@@ -15392,6 +15433,69 @@
 
 }
 
+package android.graphics.text {
+
+  public class LineBreaker {
+    method public android.graphics.text.LineBreaker.Result computeLineBreaks(android.graphics.text.MeasuredText, android.graphics.text.LineBreaker.ParagraphConstraints, int);
+    field public static final int BREAK_STRATEGY_BALANCED = 2; // 0x2
+    field public static final int BREAK_STRATEGY_HIGH_QUALITY = 1; // 0x1
+    field public static final int BREAK_STRATEGY_SIMPLE = 0; // 0x0
+    field public static final int HYPHENATION_FREQUENCY_FULL = 2; // 0x2
+    field public static final int HYPHENATION_FREQUENCY_NONE = 0; // 0x0
+    field public static final int HYPHENATION_FREQUENCY_NORMAL = 1; // 0x1
+    field public static final int JUSTIFICATION_MODE_INTER_WORD = 1; // 0x1
+    field public static final int JUSTIFICATION_MODE_NONE = 0; // 0x0
+  }
+
+  public static class LineBreaker.Builder {
+    ctor public LineBreaker.Builder();
+    method public android.graphics.text.LineBreaker build();
+    method public android.graphics.text.LineBreaker.Builder setBreakStrategy(int);
+    method public android.graphics.text.LineBreaker.Builder setHyphenationFrequency(int);
+    method public android.graphics.text.LineBreaker.Builder setIndents(int[]);
+    method public android.graphics.text.LineBreaker.Builder setJustified(int);
+  }
+
+  public static class LineBreaker.ParagraphConstraints {
+    ctor public LineBreaker.ParagraphConstraints();
+    method public int getDefaultTabStop();
+    method public float getFirstWidth();
+    method public int getFirstWidthLineCount();
+    method public int[] getTabStops();
+    method public float getWidth();
+    method public void setIndent(float, int);
+    method public void setTabStops(int[], int);
+    method public void setWidth(float);
+  }
+
+  public static class LineBreaker.Result {
+    method public float getLineAscent(int);
+    method public int getLineBreakOffset(int);
+    method public int getLineCount();
+    method public float getLineDescent(int);
+    method public int getLineHyphenEdit(int);
+    method public float getLineWidth(int);
+    method public boolean hasLineTab(int);
+  }
+
+  public class MeasuredText {
+    method public void getBounds(int, int, android.graphics.Rect);
+    method public float getCharWidthAt(int);
+    method public char[] getChars();
+    method public float getWidth(int, int);
+  }
+
+  public static class MeasuredText.Builder {
+    ctor public MeasuredText.Builder(char[]);
+    method public android.graphics.text.MeasuredText.Builder appendReplacementRun(android.graphics.Paint, int, float);
+    method public android.graphics.text.MeasuredText.Builder appendStyleRun(android.graphics.Paint, int, boolean);
+    method public android.graphics.text.MeasuredText build();
+    method public android.graphics.text.MeasuredText.Builder setComputeHyphenation(boolean);
+    method public android.graphics.text.MeasuredText.Builder setComputeLayout(boolean);
+  }
+
+}
+
 package android.hardware {
 
   public deprecated class Camera {
@@ -15963,7 +16067,11 @@
 package android.hardware.biometrics {
 
   public class BiometricManager {
-    method public boolean hasEnrolledBiometrics();
+    method public int canAuthenticate();
+    field public static final int ERROR_NONE = 0; // 0x0
+    field public static final int ERROR_NO_BIOMETRICS = 11; // 0xb
+    field public static final int ERROR_NO_HARDWARE = 12; // 0xc
+    field public static final int ERROR_UNAVAILABLE = 1; // 0x1
   }
 
   public class BiometricPrompt {
@@ -22554,6 +22662,7 @@
     method public boolean isBluetoothScoOn();
     method public boolean isMicrophoneMute();
     method public boolean isMusicActive();
+    method public static boolean isOffloadedPlaybackSupported(android.media.AudioFormat);
     method public boolean isSpeakerphoneOn();
     method public boolean isStreamMute(int);
     method public boolean isVolumeFixed();
@@ -22875,6 +22984,7 @@
     method public int getUnderrunCount();
     method public void pause() throws java.lang.IllegalStateException;
     method public void play() throws java.lang.IllegalStateException;
+    method public void registerStreamEventCallback(java.util.concurrent.Executor, android.media.AudioTrack.StreamEventCallback);
     method public void release();
     method public int reloadStaticData();
     method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
@@ -22895,6 +23005,7 @@
     method public deprecated int setStereoVolume(float, float);
     method public int setVolume(float);
     method public void stop() throws java.lang.IllegalStateException;
+    method public void unregisterStreamEventCallback(android.media.AudioTrack.StreamEventCallback);
     method public int write(byte[], int, int);
     method public int write(byte[], int, int, int);
     method public int write(short[], int, int);
@@ -22928,6 +23039,7 @@
     method public android.media.AudioTrack.Builder setAudioAttributes(android.media.AudioAttributes) throws java.lang.IllegalArgumentException;
     method public android.media.AudioTrack.Builder setAudioFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException;
     method public android.media.AudioTrack.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
+    method public android.media.AudioTrack.Builder setOffloadedPlayback(boolean);
     method public android.media.AudioTrack.Builder setPerformanceMode(int);
     method public android.media.AudioTrack.Builder setSessionId(int) throws java.lang.IllegalArgumentException;
     method public android.media.AudioTrack.Builder setTransferMode(int) throws java.lang.IllegalArgumentException;
@@ -22951,6 +23063,13 @@
     method public default void onRoutingChanged(android.media.AudioRouting);
   }
 
+  public static abstract class AudioTrack.StreamEventCallback {
+    ctor public AudioTrack.StreamEventCallback();
+    method public void onDataRequest(android.media.AudioTrack, int);
+    method public void onPresentationEnded(android.media.AudioTrack);
+    method public void onTearDown(android.media.AudioTrack);
+  }
+
   public class CamcorderProfile {
     method public static android.media.CamcorderProfile get(int);
     method public static android.media.CamcorderProfile get(int, int);
@@ -25084,6 +25203,7 @@
     method public static android.net.Uri getValidRingtoneUri(android.content.Context);
     method public int inferStreamType();
     method public static boolean isDefault(android.net.Uri);
+    method public static android.content.res.AssetFileDescriptor openDefaultRingtoneUri(android.content.Context, android.net.Uri) throws java.io.FileNotFoundException;
     method public static void setActualDefaultRingtoneUri(android.content.Context, int, android.net.Uri);
     method public deprecated void setIncludeDrm(boolean);
     method public void setStopPreviousRingtone(boolean);
@@ -27356,6 +27476,7 @@
   public static class ConnectivityManager.NetworkCallback {
     ctor public ConnectivityManager.NetworkCallback();
     method public void onAvailable(android.net.Network);
+    method public void onBlockedStatusChanged(android.net.Network, boolean);
     method public void onCapabilitiesChanged(android.net.Network, android.net.NetworkCapabilities);
     method public void onLinkPropertiesChanged(android.net.Network, android.net.LinkProperties);
     method public void onLosing(android.net.Network, int);
@@ -27627,16 +27748,16 @@
 
   public class NetworkInfo implements android.os.Parcelable {
     method public int describeContents();
-    method public android.net.NetworkInfo.DetailedState getDetailedState();
+    method public deprecated android.net.NetworkInfo.DetailedState getDetailedState();
     method public java.lang.String getExtraInfo();
     method public deprecated java.lang.String getReason();
     method public deprecated android.net.NetworkInfo.State getState();
-    method public int getSubtype();
-    method public java.lang.String getSubtypeName();
+    method public deprecated int getSubtype();
+    method public deprecated java.lang.String getSubtypeName();
     method public deprecated int getType();
     method public deprecated java.lang.String getTypeName();
     method public deprecated boolean isAvailable();
-    method public boolean isConnected();
+    method public deprecated boolean isConnected();
     method public deprecated boolean isConnectedOrConnecting();
     method public deprecated boolean isFailover();
     method public deprecated boolean isRoaming();
@@ -29632,6 +29753,67 @@
     field public static final int EGL_WINDOW_BIT = 4; // 0x4
   }
 
+  public class EGL15 {
+    ctor public EGL15();
+    method public static int eglClientWaitSync(android.opengl.EGLDisplay, android.opengl.EGLSync, int, long);
+    method public static android.opengl.EGLImage eglCreateImage(android.opengl.EGLDisplay, android.opengl.EGLContext, int, long, long[], int);
+    method public static android.opengl.EGLSurface eglCreatePlatformPixmapSurface(android.opengl.EGLDisplay, android.opengl.EGLConfig, java.nio.Buffer, long[], int);
+    method public static android.opengl.EGLSurface eglCreatePlatformWindowSurface(android.opengl.EGLDisplay, android.opengl.EGLConfig, java.nio.Buffer, long[], int);
+    method public static android.opengl.EGLSync eglCreateSync(android.opengl.EGLDisplay, int, long[], int);
+    method public static boolean eglDestroyImage(android.opengl.EGLDisplay, android.opengl.EGLImage);
+    method public static boolean eglDestroySync(android.opengl.EGLDisplay, android.opengl.EGLSync);
+    method public static android.opengl.EGLDisplay eglGetPlatformDisplay(int, long, long[], int);
+    method public static boolean eglGetSyncAttrib(android.opengl.EGLDisplay, android.opengl.EGLSync, int, long[], int);
+    method public static boolean eglWaitSync(android.opengl.EGLDisplay, android.opengl.EGLSync, int);
+    field public static final int EGL_CL_EVENT_HANDLE = 12444; // 0x309c
+    field public static final int EGL_CONDITION_SATISFIED = 12534; // 0x30f6
+    field public static final int EGL_CONTEXT_MAJOR_VERSION = 12440; // 0x3098
+    field public static final int EGL_CONTEXT_MINOR_VERSION = 12539; // 0x30fb
+    field public static final int EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT = 2; // 0x2
+    field public static final int EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT = 1; // 0x1
+    field public static final int EGL_CONTEXT_OPENGL_DEBUG = 12720; // 0x31b0
+    field public static final int EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE = 12721; // 0x31b1
+    field public static final int EGL_CONTEXT_OPENGL_PROFILE_MASK = 12541; // 0x30fd
+    field public static final int EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY = 12733; // 0x31bd
+    field public static final int EGL_CONTEXT_OPENGL_ROBUST_ACCESS = 12722; // 0x31b2
+    field public static final long EGL_FOREVER = -1L; // 0xffffffffffffffffL
+    field public static final int EGL_GL_COLORSPACE = 12445; // 0x309d
+    field public static final int EGL_GL_COLORSPACE_LINEAR = 12426; // 0x308a
+    field public static final int EGL_GL_COLORSPACE_SRGB = 12425; // 0x3089
+    field public static final int EGL_GL_RENDERBUFFER = 12473; // 0x30b9
+    field public static final int EGL_GL_TEXTURE_2D = 12465; // 0x30b1
+    field public static final int EGL_GL_TEXTURE_3D = 12466; // 0x30b2
+    field public static final int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X = 12468; // 0x30b4
+    field public static final int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y = 12470; // 0x30b6
+    field public static final int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z = 12472; // 0x30b8
+    field public static final int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X = 12467; // 0x30b3
+    field public static final int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y = 12469; // 0x30b5
+    field public static final int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z = 12471; // 0x30b7
+    field public static final int EGL_GL_TEXTURE_LEVEL = 12476; // 0x30bc
+    field public static final int EGL_GL_TEXTURE_ZOFFSET = 12477; // 0x30bd
+    field public static final int EGL_IMAGE_PRESERVED = 12498; // 0x30d2
+    field public static final int EGL_LOSE_CONTEXT_ON_RESET = 12735; // 0x31bf
+    field public static final android.opengl.EGLContext EGL_NO_CONTEXT;
+    field public static final android.opengl.EGLDisplay EGL_NO_DISPLAY;
+    field public static final android.opengl.EGLImage EGL_NO_IMAGE;
+    field public static final int EGL_NO_RESET_NOTIFICATION = 12734; // 0x31be
+    field public static final android.opengl.EGLSurface EGL_NO_SURFACE;
+    field public static final android.opengl.EGLSync EGL_NO_SYNC;
+    field public static final int EGL_OPENGL_ES3_BIT = 64; // 0x40
+    field public static final int EGL_PLATFORM_ANDROID_KHR = 12609; // 0x3141
+    field public static final int EGL_SIGNALED = 12530; // 0x30f2
+    field public static final int EGL_SYNC_CL_EVENT = 12542; // 0x30fe
+    field public static final int EGL_SYNC_CL_EVENT_COMPLETE = 12543; // 0x30ff
+    field public static final int EGL_SYNC_CONDITION = 12536; // 0x30f8
+    field public static final int EGL_SYNC_FENCE = 12537; // 0x30f9
+    field public static final int EGL_SYNC_FLUSH_COMMANDS_BIT = 1; // 0x1
+    field public static final int EGL_SYNC_PRIOR_COMMANDS_COMPLETE = 12528; // 0x30f0
+    field public static final int EGL_SYNC_STATUS = 12529; // 0x30f1
+    field public static final int EGL_SYNC_TYPE = 12535; // 0x30f7
+    field public static final int EGL_TIMEOUT_EXPIRED = 12533; // 0x30f5
+    field public static final int EGL_UNSIGNALED = 12531; // 0x30f3
+  }
+
   public class EGLConfig extends android.opengl.EGLObjectHandle {
   }
 
@@ -29651,6 +29833,9 @@
     field public static final int EGL_RECORDABLE_ANDROID = 12610; // 0x3142
   }
 
+  public class EGLImage extends android.opengl.EGLObjectHandle {
+  }
+
   public abstract class EGLObjectHandle {
     ctor protected deprecated EGLObjectHandle(int);
     ctor protected EGLObjectHandle(long);
@@ -29661,6 +29846,9 @@
   public class EGLSurface extends android.opengl.EGLObjectHandle {
   }
 
+  public class EGLSync extends android.opengl.EGLObjectHandle {
+  }
+
   public class ETC1 {
     ctor public ETC1();
     method public static void decodeBlock(java.nio.Buffer, java.nio.Buffer);
@@ -32523,7 +32711,7 @@
 
   public class Build {
     ctor public Build();
-    method public static java.util.List<android.os.Build.Partition> getPartitions();
+    method public static java.util.List<android.os.Build.Partition> getFingerprintedPartitions();
     method public static java.lang.String getRadioVersion();
     method public static java.lang.String getSerial();
     field public static final java.lang.String BOARD;
@@ -32554,9 +32742,9 @@
 
   public static class Build.Partition {
     ctor public Build.Partition();
+    method public long getBuildTimeMillis();
     method public java.lang.String getFingerprint();
     method public java.lang.String getName();
-    method public long getTimeMillis();
     field public static final java.lang.String PARTITION_NAME_SYSTEM = "system";
   }
 
@@ -33722,6 +33910,7 @@
     field public static final java.lang.String DISALLOW_CONFIG_LOCALE = "no_config_locale";
     field public static final java.lang.String DISALLOW_CONFIG_LOCATION = "no_config_location";
     field public static final java.lang.String DISALLOW_CONFIG_MOBILE_NETWORKS = "no_config_mobile_networks";
+    field public static final java.lang.String DISALLOW_CONFIG_PRIVATE_DNS = "disallow_config_private_dns";
     field public static final java.lang.String DISALLOW_CONFIG_SCREEN_TIMEOUT = "no_config_screen_timeout";
     field public static final java.lang.String DISALLOW_CONFIG_TETHERING = "no_config_tethering";
     field public static final java.lang.String DISALLOW_CONFIG_VPN = "no_config_vpn";
@@ -36613,6 +36802,7 @@
     ctor public MediaStore();
     method public static android.net.Uri getDocumentUri(android.content.Context, android.net.Uri);
     method public static android.net.Uri getMediaScannerUri();
+    method public static android.net.Uri getMediaUri(android.content.Context, android.net.Uri);
     method public static java.lang.String getVersion(android.content.Context);
     field public static final java.lang.String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
     field public static final java.lang.String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
@@ -36654,7 +36844,7 @@
 
   public static abstract interface MediaStore.Audio.AlbumColumns {
     field public static final java.lang.String ALBUM = "album";
-    field public static final java.lang.String ALBUM_ART = "album_art";
+    field public static final deprecated java.lang.String ALBUM_ART = "album_art";
     field public static final java.lang.String ALBUM_ID = "album_id";
     field public static final java.lang.String ALBUM_KEY = "album_key";
     field public static final java.lang.String ARTIST = "artist";
@@ -36776,7 +36966,7 @@
   }
 
   public static abstract interface MediaStore.Audio.PlaylistsColumns {
-    field public static final java.lang.String DATA = "_data";
+    field public static final deprecated java.lang.String DATA = "_data";
     field public static final java.lang.String DATE_ADDED = "date_added";
     field public static final java.lang.String DATE_MODIFIED = "date_modified";
     field public static final java.lang.String NAME = "name";
@@ -36838,15 +37028,15 @@
 
   public static class MediaStore.Images.Thumbnails implements android.provider.BaseColumns {
     ctor public MediaStore.Images.Thumbnails();
-    method public static void cancelThumbnailRequest(android.content.ContentResolver, long);
-    method public static void cancelThumbnailRequest(android.content.ContentResolver, long, long);
+    method public static deprecated void cancelThumbnailRequest(android.content.ContentResolver, long);
+    method public static deprecated void cancelThumbnailRequest(android.content.ContentResolver, long, long);
     method public static android.net.Uri getContentUri(java.lang.String);
-    method public static android.graphics.Bitmap getThumbnail(android.content.ContentResolver, long, int, android.graphics.BitmapFactory.Options);
-    method public static android.graphics.Bitmap getThumbnail(android.content.ContentResolver, long, long, int, android.graphics.BitmapFactory.Options);
+    method public static deprecated android.graphics.Bitmap getThumbnail(android.content.ContentResolver, long, int, android.graphics.BitmapFactory.Options);
+    method public static deprecated android.graphics.Bitmap getThumbnail(android.content.ContentResolver, long, long, int, android.graphics.BitmapFactory.Options);
     method public static final android.database.Cursor query(android.content.ContentResolver, android.net.Uri, java.lang.String[]);
     method public static final android.database.Cursor queryMiniThumbnail(android.content.ContentResolver, long, int, java.lang.String[]);
     method public static final android.database.Cursor queryMiniThumbnails(android.content.ContentResolver, android.net.Uri, int, java.lang.String[]);
-    field public static final java.lang.String DATA = "_data";
+    field public static final deprecated java.lang.String DATA = "_data";
     field public static final java.lang.String DEFAULT_SORT_ORDER = "image_id ASC";
     field public static final android.net.Uri EXTERNAL_CONTENT_URI;
     field public static final int FULL_SCREEN_KIND = 2; // 0x2
@@ -36861,7 +37051,7 @@
   }
 
   public static abstract interface MediaStore.MediaColumns implements android.provider.BaseColumns {
-    field public static final java.lang.String DATA = "_data";
+    field public static final deprecated java.lang.String DATA = "_data";
     field public static final java.lang.String DATE_ADDED = "date_added";
     field public static final java.lang.String DATE_MODIFIED = "date_modified";
     field public static final java.lang.String DISPLAY_NAME = "_display_name";
@@ -36889,12 +37079,12 @@
 
   public static class MediaStore.Video.Thumbnails implements android.provider.BaseColumns {
     ctor public MediaStore.Video.Thumbnails();
-    method public static void cancelThumbnailRequest(android.content.ContentResolver, long);
-    method public static void cancelThumbnailRequest(android.content.ContentResolver, long, long);
+    method public static deprecated void cancelThumbnailRequest(android.content.ContentResolver, long);
+    method public static deprecated void cancelThumbnailRequest(android.content.ContentResolver, long, long);
     method public static android.net.Uri getContentUri(java.lang.String);
-    method public static android.graphics.Bitmap getThumbnail(android.content.ContentResolver, long, int, android.graphics.BitmapFactory.Options);
-    method public static android.graphics.Bitmap getThumbnail(android.content.ContentResolver, long, long, int, android.graphics.BitmapFactory.Options);
-    field public static final java.lang.String DATA = "_data";
+    method public static deprecated android.graphics.Bitmap getThumbnail(android.content.ContentResolver, long, int, android.graphics.BitmapFactory.Options);
+    method public static deprecated android.graphics.Bitmap getThumbnail(android.content.ContentResolver, long, long, int, android.graphics.BitmapFactory.Options);
+    field public static final deprecated java.lang.String DATA = "_data";
     field public static final java.lang.String DEFAULT_SORT_ORDER = "video_id ASC";
     field public static final android.net.Uri EXTERNAL_CONTENT_URI;
     field public static final int FULL_SCREEN_KIND = 2; // 0x2
@@ -36955,6 +37145,7 @@
     field public static final java.lang.String ACTION_APPLICATION_DEVELOPMENT_SETTINGS = "android.settings.APPLICATION_DEVELOPMENT_SETTINGS";
     field public static final java.lang.String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
     field public static final java.lang.String ACTION_APP_NOTIFICATION_SETTINGS = "android.settings.APP_NOTIFICATION_SETTINGS";
+    field public static final java.lang.String ACTION_APP_SEARCH_SETTINGS = "android.settings.APP_SEARCH_SETTINGS";
     field public static final java.lang.String ACTION_BATTERY_SAVER_SETTINGS = "android.settings.BATTERY_SAVER_SETTINGS";
     field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
     field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
@@ -42955,6 +43146,7 @@
     method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
     method public boolean isActiveSubscriptionId(int);
     method public boolean isNetworkRoaming(int);
+    method public static boolean isUsableSubscriptionId(int);
     method public static boolean isValidSubscriptionId(int);
     method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
     method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
@@ -42968,10 +43160,10 @@
     field public static final java.lang.String ACTION_REFRESH_SUBSCRIPTION_PLANS = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
     field public static final int DATA_ROAMING_DISABLE = 0; // 0x0
     field public static final int DATA_ROAMING_ENABLE = 1; // 0x1
+    field public static final int DEFAULT_SUBSCRIPTION_ID = 2147483647; // 0x7fffffff
     field public static final java.lang.String EXTRA_SUBSCRIPTION_INDEX = "android.telephony.extra.SUBSCRIPTION_INDEX";
-    field public static final int INVALID_SIM_SLOT_INDEX = -2; // 0xfffffffe
+    field public static final int INVALID_SIM_SLOT_INDEX = -1; // 0xffffffff
     field public static final int INVALID_SUBSCRIPTION_ID = -1; // 0xffffffff
-    field public static final int SIM_NOT_INSERTED = -3; // 0xfffffffd
   }
 
   public static class SubscriptionManager.OnOpportunisticSubscriptionsChangedListener {
@@ -43306,7 +43498,7 @@
     field public static final int PROTOCOL_IPV6 = 1; // 0x1
     field public static final int PROTOCOL_PPP = 3; // 0x3
     field public static final int TYPE_CBS = 128; // 0x80
-    field public static final int TYPE_DEFAULT = 1; // 0x1
+    field public static final int TYPE_DEFAULT = 17; // 0x11
     field public static final int TYPE_DUN = 8; // 0x8
     field public static final int TYPE_EMERGENCY = 512; // 0x200
     field public static final int TYPE_FOTA = 32; // 0x20
@@ -43343,6 +43535,37 @@
 
 }
 
+package android.telephony.emergency {
+
+  public final class EmergencyNumber implements java.lang.Comparable android.os.Parcelable {
+    method public int compareTo(android.telephony.emergency.EmergencyNumber);
+    method public int describeContents();
+    method public java.lang.String getCountryIso();
+    method public int getEmergencyNumberSourceBitmask();
+    method public java.util.List<java.lang.Integer> getEmergencyNumberSources();
+    method public java.util.List<java.lang.Integer> getEmergencyServiceCategories();
+    method public int getEmergencyServiceCategoryBitmask();
+    method public java.lang.String getNumber();
+    method public boolean isFromSources(int);
+    method public boolean isInEmergencyServiceCategories(int);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.telephony.emergency.EmergencyNumber> CREATOR;
+    field public static final int EMERGENCY_NUMBER_SOURCE_DEFAULT = 8; // 0x8
+    field public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG = 4; // 0x4
+    field public static final int EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING = 1; // 0x1
+    field public static final int EMERGENCY_NUMBER_SOURCE_SIM = 2; // 0x2
+    field public static final int EMERGENCY_SERVICE_CATEGORY_AIEC = 64; // 0x40
+    field public static final int EMERGENCY_SERVICE_CATEGORY_AMBULANCE = 2; // 0x2
+    field public static final int EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE = 4; // 0x4
+    field public static final int EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD = 8; // 0x8
+    field public static final int EMERGENCY_SERVICE_CATEGORY_MIEC = 32; // 0x20
+    field public static final int EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE = 16; // 0x10
+    field public static final int EMERGENCY_SERVICE_CATEGORY_POLICE = 1; // 0x1
+    field public static final int EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED = 0; // 0x0
+  }
+
+}
+
 package android.telephony.euicc {
 
   public final class DownloadableSubscription implements android.os.Parcelable {
@@ -44272,6 +44495,7 @@
     method public static int lastIndexOf(java.lang.CharSequence, char, int);
     method public static int lastIndexOf(java.lang.CharSequence, char, int, int);
     method public static java.lang.CharSequence listEllipsize(android.content.Context, java.util.List<java.lang.CharSequence>, java.lang.String, android.text.TextPaint, float, int);
+    method public static java.lang.CharSequence makeSafeForPresentation(java.lang.String, int, float, int);
     method public static boolean regionMatches(java.lang.CharSequence, int, java.lang.CharSequence, int, int);
     method public static java.lang.CharSequence replace(java.lang.CharSequence, java.lang.String[], java.lang.CharSequence[]);
     method public static java.lang.String[] split(java.lang.String, java.lang.String);
@@ -44283,6 +44507,9 @@
     field public static final int CAP_MODE_SENTENCES = 16384; // 0x4000
     field public static final int CAP_MODE_WORDS = 8192; // 0x2000
     field public static final android.os.Parcelable.Creator<java.lang.CharSequence> CHAR_SEQUENCE_CREATOR;
+    field public static final int SAFE_STRING_FLAG_FIRST_LINE = 4; // 0x4
+    field public static final int SAFE_STRING_FLAG_SINGLE_LINE = 2; // 0x2
+    field public static final int SAFE_STRING_FLAG_TRIM = 1; // 0x1
   }
 
   public static abstract interface TextUtils.EllipsizeCallback {
@@ -44881,6 +45108,16 @@
     method public abstract void drawBackground(android.graphics.Canvas, android.graphics.Paint, int, int, int, int, int, java.lang.CharSequence, int, int, int);
   }
 
+  public static class LineBackgroundSpan.Standard implements android.text.style.LineBackgroundSpan android.text.ParcelableSpan {
+    ctor public LineBackgroundSpan.Standard(int);
+    ctor public LineBackgroundSpan.Standard(android.os.Parcel);
+    method public int describeContents();
+    method public void drawBackground(android.graphics.Canvas, android.graphics.Paint, int, int, int, int, int, java.lang.CharSequence, int, int, int);
+    method public final int getColor();
+    method public int getSpanTypeId();
+    method public void writeToParcel(android.os.Parcel, int);
+  }
+
   public abstract interface LineHeightSpan implements android.text.style.ParagraphStyle android.text.style.WrapTogetherSpan {
     method public abstract void chooseHeight(java.lang.CharSequence, int, int, int, int, android.graphics.Paint.FontMetricsInt);
   }
@@ -45061,6 +45298,7 @@
     method public int getSpanTypeId();
     method public android.content.res.ColorStateList getTextColor();
     method public int getTextFontWeight();
+    method public android.os.LocaleList getTextLocales();
     method public int getTextSize();
     method public int getTextStyle();
     method public android.graphics.Typeface getTypeface();
@@ -46641,7 +46879,12 @@
   }
 
   public final class DisplayCutout {
-    ctor public DisplayCutout(android.graphics.Rect, java.util.List<android.graphics.Rect>);
+    ctor public DisplayCutout(android.graphics.Insets, android.graphics.Rect, android.graphics.Rect, android.graphics.Rect, android.graphics.Rect);
+    ctor public deprecated DisplayCutout(android.graphics.Rect, java.util.List<android.graphics.Rect>);
+    method public android.graphics.Rect getBoundingRectBottom();
+    method public android.graphics.Rect getBoundingRectLeft();
+    method public android.graphics.Rect getBoundingRectRight();
+    method public android.graphics.Rect getBoundingRectTop();
     method public java.util.List<android.graphics.Rect> getBoundingRects();
     method public int getSafeInsetBottom();
     method public int getSafeInsetLeft();
@@ -47973,6 +48216,7 @@
 
   public class TouchDelegate {
     ctor public TouchDelegate(android.graphics.Rect, android.view.View);
+    method public android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo getTouchDelegateInfo();
     method public boolean onTouchEvent(android.view.MotionEvent);
     field public static final int ABOVE = 1; // 0x1
     field public static final int BELOW = 2; // 0x2
@@ -48276,6 +48520,7 @@
     method public final boolean isFocusableInTouchMode();
     method public boolean isFocused();
     method public final boolean isFocusedByDefault();
+    method public boolean isForceDarkAllowed();
     method public boolean isHapticFeedbackEnabled();
     method public boolean isHardwareAccelerated();
     method public boolean isHorizontalFadingEdgeEnabled();
@@ -48462,6 +48707,7 @@
     method public void setFocusable(int);
     method public void setFocusableInTouchMode(boolean);
     method public void setFocusedByDefault(boolean);
+    method public void setForceDarkAllowed(boolean);
     method public void setForeground(android.graphics.drawable.Drawable);
     method public void setForegroundGravity(int);
     method public void setForegroundTintList(android.content.res.ColorStateList);
@@ -49955,6 +50201,7 @@
     method public int getTextSelectionEnd();
     method public int getTextSelectionStart();
     method public java.lang.CharSequence getTooltipText();
+    method public android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo getTouchDelegateInfo();
     method public android.view.accessibility.AccessibilityNodeInfo getTraversalAfter();
     method public android.view.accessibility.AccessibilityNodeInfo getTraversalBefore();
     method public java.lang.String getViewIdResourceName();
@@ -50045,6 +50292,7 @@
     method public void setTextEntryKey(boolean);
     method public void setTextSelection(int, int);
     method public void setTooltipText(java.lang.CharSequence);
+    method public void setTouchDelegateInfo(android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo);
     method public void setTraversalAfter(android.view.View);
     method public void setTraversalAfter(android.view.View, int);
     method public void setTraversalBefore(android.view.View);
@@ -50171,6 +50419,16 @@
     field public static final int RANGE_TYPE_PERCENT = 2; // 0x2
   }
 
+  public static final class AccessibilityNodeInfo.TouchDelegateInfo implements android.os.Parcelable {
+    ctor public AccessibilityNodeInfo.TouchDelegateInfo(java.util.Map<android.graphics.Region, android.view.View>);
+    method public int describeContents();
+    method public android.graphics.Region getRegionAt(int);
+    method public int getRegionCount();
+    method public android.view.accessibility.AccessibilityNodeInfo getTargetForRegion(android.graphics.Region);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo> CREATOR;
+  }
+
   public abstract class AccessibilityNodeProvider {
     ctor public AccessibilityNodeProvider();
     method public void addExtraDataToAccessibilityNodeInfo(int, android.view.accessibility.AccessibilityNodeInfo, java.lang.String, android.os.Bundle);
@@ -51194,6 +51452,7 @@
     method public default android.view.textclassifier.TextClassification classifyText(android.view.textclassifier.TextClassification.Request);
     method public default android.view.textclassifier.TextClassification classifyText(java.lang.CharSequence, int, int, android.os.LocaleList);
     method public default void destroy();
+    method public default android.view.textclassifier.TextLanguage detectLanguage(android.view.textclassifier.TextLanguage.Request);
     method public default android.view.textclassifier.TextLinks generateLinks(android.view.textclassifier.TextLinks.Request);
     method public default int getMaxGenerateLinksTextLength();
     method public default boolean isDestroyed();
@@ -51234,6 +51493,39 @@
     field public static final android.os.Parcelable.Creator<android.view.textclassifier.TextClassifier.EntityConfig> CREATOR;
   }
 
+  public final class TextLanguage implements android.os.Parcelable {
+    method public int describeContents();
+    method public float getConfidenceScore(android.icu.util.ULocale);
+    method public android.os.Bundle getExtras();
+    method public java.lang.String getId();
+    method public android.icu.util.ULocale getLocale(int);
+    method public int getLocaleHypothesisCount();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.textclassifier.TextLanguage> CREATOR;
+  }
+
+  public static final class TextLanguage.Builder {
+    ctor public TextLanguage.Builder();
+    method public android.view.textclassifier.TextLanguage build();
+    method public android.view.textclassifier.TextLanguage.Builder putLocale(android.icu.util.ULocale, float);
+    method public android.view.textclassifier.TextLanguage.Builder setExtras(android.os.Bundle);
+    method public android.view.textclassifier.TextLanguage.Builder setId(java.lang.String);
+  }
+
+  public static final class TextLanguage.Request implements android.os.Parcelable {
+    method public int describeContents();
+    method public android.os.Bundle getExtras();
+    method public java.lang.CharSequence getText();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.view.textclassifier.TextLanguage.Request> CREATOR;
+  }
+
+  public static final class TextLanguage.Request.Builder {
+    ctor public TextLanguage.Request.Builder(java.lang.CharSequence);
+    method public android.view.textclassifier.TextLanguage.Request build();
+    method public android.view.textclassifier.TextLanguage.Request.Builder setExtras(android.os.Bundle);
+  }
+
   public final class TextLinks implements android.os.Parcelable {
     method public int apply(android.text.Spannable, int, java.util.function.Function<android.view.textclassifier.TextLinks.TextLink, android.view.textclassifier.TextLinks.TextLinkSpan>);
     method public int describeContents();
@@ -52154,6 +52446,7 @@
     field public static final int ERROR_UNSAFE_RESOURCE = -16; // 0xfffffff0
     field public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3; // 0xfffffffd
     field public static final int ERROR_UNSUPPORTED_SCHEME = -10; // 0xfffffff6
+    field public static final int SAFE_BROWSING_THREAT_BILLING = 4; // 0x4
     field public static final int SAFE_BROWSING_THREAT_MALWARE = 1; // 0x1
     field public static final int SAFE_BROWSING_THREAT_PHISHING = 2; // 0x2
     field public static final int SAFE_BROWSING_THREAT_UNKNOWN = 0; // 0x0
diff --git a/api/system-current.txt b/api/system-current.txt
index 041b497..7e51082 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -119,6 +119,7 @@
     field public static final java.lang.String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
     field public static final java.lang.String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
     field public static final java.lang.String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE";
+    field public static final java.lang.String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD";
     field public static final java.lang.String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP";
     field public static final java.lang.String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS";
     field public static final java.lang.String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE";
@@ -221,7 +222,7 @@
   }
 
   public static final class R.dimen {
-    field public static final int config_restricted_icon_size = 17104903; // 0x1050007
+    field public static final int config_restrictedIconSize = 17104903; // 0x1050007
   }
 
   public static final class R.drawable {
@@ -234,12 +235,12 @@
   }
 
   public static final class R.string {
-    field public static final int config_feedback_intent_extra_key = 17039391; // 0x104001f
-    field public static final int config_feedback_intent_name_key = 17039392; // 0x1040020
-    field public static final int config_help_intent_extra_key = 17039389; // 0x104001d
-    field public static final int config_help_intent_name_key = 17039390; // 0x104001e
-    field public static final int config_help_package_name_key = 17039387; // 0x104001b
-    field public static final int config_help_package_name_value = 17039388; // 0x104001c
+    field public static final int config_feedbackIntentExtraKey = 17039391; // 0x104001f
+    field public static final int config_feedbackIntentNameKey = 17039392; // 0x1040020
+    field public static final int config_helpIntentExtraKey = 17039389; // 0x104001d
+    field public static final int config_helpIntentNameKey = 17039390; // 0x104001e
+    field public static final int config_helpPackageNameKey = 17039387; // 0x104001b
+    field public static final int config_helpPackageNameValue = 17039388; // 0x104001c
   }
 
   public static final class R.style {
@@ -523,11 +524,11 @@
     method public android.content.ComponentName getDeviceOwnerComponentOnAnyUser();
     method public java.lang.String getDeviceOwnerNameOnAnyUser();
     method public java.lang.CharSequence getDeviceOwnerOrganizationName();
-    method public int getDeviceOwnerUserId();
+    method public android.os.UserHandle getDeviceOwnerUser();
     method public java.util.List<java.lang.String> getPermittedAccessibilityServices(int);
     method public java.util.List<java.lang.String> getPermittedInputMethodsForCurrentUser();
     method public android.content.ComponentName getProfileOwner() throws java.lang.IllegalArgumentException;
-    method public android.content.ComponentName getProfileOwnerAsUser(int);
+    method public android.content.ComponentName getProfileOwnerAsUser(android.os.UserHandle);
     method public java.lang.String getProfileOwnerNameAsUser(int) throws java.lang.IllegalArgumentException;
     method public int getUserProvisioningState();
     method public boolean isDeviceManaged();
@@ -986,6 +987,7 @@
     field public static final java.lang.String ACTION_PRE_BOOT_COMPLETED = "android.intent.action.PRE_BOOT_COMPLETED";
     field public static final java.lang.String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART";
     field public static final java.lang.String ACTION_RESOLVE_INSTANT_APP_PACKAGE = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE";
+    field public static final java.lang.String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE";
     field public static final java.lang.String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS";
     field public static final java.lang.String ACTION_SHOW_SUSPENDED_APP_DETAILS = "android.intent.action.SHOW_SUSPENDED_APP_DETAILS";
     field public static final deprecated java.lang.String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
@@ -1011,7 +1013,6 @@
     field public static final java.lang.String EXTRA_REMOTE_CALLBACK = "android.intent.extra.REMOTE_CALLBACK";
     field public static final java.lang.String EXTRA_RESULT_NEEDED = "android.intent.extra.RESULT_NEEDED";
     field public static final java.lang.String EXTRA_UNKNOWN_INSTANT_APP = "android.intent.extra.UNKNOWN_INSTANT_APP";
-    field public static final java.lang.String EXTRA_USER_ID = "android.intent.extra.USER_ID";
     field public static final java.lang.String EXTRA_VERIFICATION_BUNDLE = "android.intent.extra.VERIFICATION_BUNDLE";
   }
 
@@ -1118,12 +1119,12 @@
   }
 
   public class PackageItemInfo {
+    method public static void forceSafeLabels();
     method public deprecated java.lang.CharSequence loadSafeLabel(android.content.pm.PackageManager);
     method public java.lang.CharSequence loadSafeLabel(android.content.pm.PackageManager, float, int);
-    method public static void setForceSafeLabels(boolean);
-    field public static final int SAFE_LABEL_FLAG_FIRST_LINE = 4; // 0x4
-    field public static final int SAFE_LABEL_FLAG_SINGLE_LINE = 2; // 0x2
-    field public static final int SAFE_LABEL_FLAG_TRIM = 1; // 0x1
+    field public static final deprecated int SAFE_LABEL_FLAG_FIRST_LINE = 4; // 0x4
+    field public static final deprecated int SAFE_LABEL_FLAG_SINGLE_LINE = 2; // 0x2
+    field public static final deprecated int SAFE_LABEL_FLAG_TRIM = 1; // 0x1
   }
 
   public abstract class PackageManager {
@@ -1150,7 +1151,8 @@
     method public abstract void revokeRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public abstract boolean setDefaultBrowserPackageNameAsUser(java.lang.String, int);
     method public void setHarmfulAppWarning(java.lang.String, java.lang.CharSequence);
-    method public java.lang.String[] setPackagesSuspended(java.lang.String[], boolean, android.os.PersistableBundle, android.os.PersistableBundle, java.lang.String);
+    method public deprecated java.lang.String[] setPackagesSuspended(java.lang.String[], boolean, android.os.PersistableBundle, android.os.PersistableBundle, java.lang.String);
+    method public java.lang.String[] setPackagesSuspended(java.lang.String[], boolean, android.os.PersistableBundle, android.os.PersistableBundle, android.content.pm.SuspendDialogInfo);
     method public abstract void setUpdateAvailable(java.lang.String, boolean);
     method public abstract boolean updateIntentVerificationStatusAsUser(java.lang.String, int, int);
     method public abstract void updatePermissionFlags(java.lang.String, java.lang.String, int, int, android.os.UserHandle);
@@ -1244,6 +1246,22 @@
     field public int requestRes;
   }
 
+  public final class SuspendDialogInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.content.pm.SuspendDialogInfo> CREATOR;
+  }
+
+  public static final class SuspendDialogInfo.Builder {
+    ctor public SuspendDialogInfo.Builder();
+    method public android.content.pm.SuspendDialogInfo build();
+    method public android.content.pm.SuspendDialogInfo.Builder setIcon(int);
+    method public android.content.pm.SuspendDialogInfo.Builder setMessage(java.lang.String);
+    method public android.content.pm.SuspendDialogInfo.Builder setMessage(int);
+    method public android.content.pm.SuspendDialogInfo.Builder setNeutralButtonText(int);
+    method public android.content.pm.SuspendDialogInfo.Builder setTitle(int);
+  }
+
 }
 
 package android.content.pm.dex {
@@ -1280,14 +1298,6 @@
 
 }
 
-package android.graphics.drawable {
-
-  public final class Icon implements android.os.Parcelable {
-    method public static android.graphics.drawable.Icon createWithResource(android.content.res.Resources, int);
-  }
-
-}
-
 package android.hardware {
 
   public final class Sensor {
@@ -3189,6 +3199,7 @@
   public class ConnectivityManager {
     method public java.lang.String getCaptivePortalServerUrl();
     method public boolean isTetheringSupported();
+    method public void setAirplaneMode(boolean);
     method public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback);
     method public void startTethering(int, boolean, android.net.ConnectivityManager.OnStartTetheringCallback, android.os.Handler);
     method public void stopTethering(int);
@@ -4132,12 +4143,10 @@
     field public static final android.os.UserHandle ALL;
     field public static final android.os.UserHandle CURRENT;
     field public static final android.os.UserHandle SYSTEM;
-    field public static final int USER_NULL = -10000; // 0xffffd8f0
   }
 
   public class UserManager {
     method public void clearSeedAccountData();
-    method public int[] getProfileIds(int, boolean);
     method public java.lang.String getSeedAccountName();
     method public android.os.PersistableBundle getSeedAccountOptions();
     method public java.lang.String getSeedAccountType();
@@ -4202,8 +4211,8 @@
   }
 
   public static final class PermissionManager.SplitPermissionInfo {
-    method public java.lang.String[] getNewPermissions();
-    method public java.lang.String getRootPermission();
+    method public java.util.List<java.lang.String> getNewPermissions();
+    method public java.lang.String getSplitPermission();
     method public int getTargetSdk();
   }
 
@@ -4441,6 +4450,7 @@
     field public static final java.lang.String INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT = "install_carrier_app_notification_persistent";
     field public static final java.lang.String INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS = "install_carrier_app_notification_sleep_millis";
     field public static final java.lang.String OTA_DISABLE_AUTOMATIC_UPDATE = "ota_disable_automatic_update";
+    field public static final java.lang.String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled";
     field public static final java.lang.String THEATER_MODE_ON = "theater_mode_on";
     field public static final java.lang.String WEBVIEW_MULTIPROCESS = "webview_multiprocess";
     field public static final java.lang.String WIFI_BADGING_THRESHOLDS = "wifi_badging_thresholds";
@@ -4462,6 +4472,23 @@
     field public static final java.lang.String VOLUME_HUSH_GESTURE = "volume_hush_gesture";
   }
 
+  public static final class Telephony.Carriers implements android.provider.BaseColumns {
+    field public static final java.lang.String APN_SET_ID = "apn_set_id";
+    field public static final int CARRIER_EDITED = 4; // 0x4
+    field public static final java.lang.String EDITED = "edited";
+    field public static final java.lang.String MAX_CONNS = "max_conns";
+    field public static final java.lang.String MAX_CONNS_TIME = "max_conns_time";
+    field public static final java.lang.String MODEM_COGNITIVE = "modem_cognitive";
+    field public static final java.lang.String MTU = "mtu";
+    field public static final int NO_SET_SET = 0; // 0x0
+    field public static final int UNEDITED = 0; // 0x0
+    field public static final int USER_DELETED = 2; // 0x2
+    field public static final java.lang.String USER_EDITABLE = "user_editable";
+    field public static final int USER_EDITED = 1; // 0x1
+    field public static final java.lang.String USER_VISIBLE = "user_visible";
+    field public static final java.lang.String WAIT_TIME = "wait_time";
+  }
+
   public final class TimeZoneRulesDataContract {
     field public static final java.lang.String AUTHORITY = "com.android.timezone";
   }
@@ -5287,6 +5314,7 @@
     method public int getRejectCause();
     method public int getTransportType();
     method public boolean isEmergencyEnabled();
+    method public boolean isRoaming();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationState> CREATOR;
     field public static final int DOMAIN_CS = 1; // 0x1
@@ -5329,10 +5357,18 @@
     field public static final int RESULT_SUCCESS = 0; // 0x0
   }
 
+  public class PhoneStateListener {
+    method public void onRadioPowerStateChanged(int);
+    field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
+  }
+
   public class ServiceState implements android.os.Parcelable {
+    method public android.telephony.NetworkRegistrationState getNetworkRegistrationState(int, int);
     method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates();
-    method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates(int);
-    method public android.telephony.NetworkRegistrationState getNetworkRegistrationStates(int, int);
+    method public deprecated java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates(int);
+    method public deprecated android.telephony.NetworkRegistrationState getNetworkRegistrationStates(int, int);
+    method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForDomain(int);
+    method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForTransportType(int);
   }
 
   public final class SmsManager {
@@ -5371,6 +5407,8 @@
     method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>);
     field public static final java.lang.String ACTION_MANAGE_SUBSCRIPTION_PLANS = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS";
     field public static final java.lang.String ACTION_REFRESH_SUBSCRIPTION_PLANS = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS";
+    field public static final android.net.Uri ENHANCED_4G_ENABLED_CONTENT_URI;
+    field public static final android.net.Uri WFC_ENABLED_CONTENT_URI;
   }
 
   public final class SubscriptionPlan implements android.os.Parcelable {
@@ -5451,6 +5489,7 @@
     method public boolean getEmergencyCallbackMode();
     method public java.lang.String getIsimDomain();
     method public int getPreferredNetworkType(int);
+    method public int getRadioPowerState();
     method public int getSimApplicationState();
     method public int getSimCardState();
     method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
@@ -5465,6 +5504,7 @@
     method public deprecated boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
     method public boolean needsOtaServiceProvisioning();
     method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
+    method public void setCarrierDataEnabled(boolean);
     method public void setDataActivationState(int);
     method public deprecated void setDataEnabled(int, boolean);
     method public void setDataRoamingEnabled(boolean);
@@ -5514,6 +5554,9 @@
     field public static final int NETWORK_MODE_TDSCDMA_WCDMA = 14; // 0xe
     field public static final int NETWORK_MODE_WCDMA_ONLY = 2; // 0x2
     field public static final int NETWORK_MODE_WCDMA_PREF = 0; // 0x0
+    field public static final int RADIO_POWER_OFF = 0; // 0x0
+    field public static final int RADIO_POWER_ON = 1; // 0x1
+    field public static final int RADIO_POWER_UNAVAILABLE = 2; // 0x2
     field public static final int SIM_ACTIVATION_STATE_ACTIVATED = 2; // 0x2
     field public static final int SIM_ACTIVATION_STATE_ACTIVATING = 1; // 0x1
     field public static final int SIM_ACTIVATION_STATE_DEACTIVATED = 3; // 0x3
@@ -5580,17 +5623,12 @@
   }
 
   public final class DataProfile implements android.os.Parcelable {
-    ctor public DataProfile(int, java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, int, int, int, int, boolean, int, java.lang.String, int, int, java.lang.String, java.lang.String, boolean);
-    ctor public DataProfile(android.os.Parcel);
-    method public int describeContents();
     method public java.lang.String getApn();
     method public int getAuthType();
     method public int getBearerBitmap();
     method public int getMaxConns();
     method public int getMaxConnsTime();
     method public int getMtu();
-    method public java.lang.String getMvnoMatchData();
-    method public java.lang.String getMvnoType();
     method public java.lang.String getPassword();
     method public int getProfileId();
     method public java.lang.String getProtocol();
@@ -5600,9 +5638,8 @@
     method public java.lang.String getUserName();
     method public int getWaitTime();
     method public boolean isEnabled();
-    method public boolean isModemCognitive();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator<android.telephony.data.DataProfile> CREATOR;
+    method public boolean isPersistent();
+    method public boolean isPreferred();
     field public static final int TYPE_3GPP = 1; // 0x1
     field public static final int TYPE_3GPP2 = 2; // 0x2
     field public static final int TYPE_COMMON = 0; // 0x0
@@ -5849,7 +5886,7 @@
     field public static final java.lang.String EXTRA_CODEC = "Codec";
     field public static final java.lang.String EXTRA_DIALSTRING = "dialstring";
     field public static final java.lang.String EXTRA_DISPLAY_TEXT = "DisplayText";
-    field public static final java.lang.String EXTRA_E_CALL = "e_call";
+    field public static final java.lang.String EXTRA_EMERGENCY_CALL = "e_call";
     field public static final java.lang.String EXTRA_IS_CALL_PULL = "CallPull";
     field public static final java.lang.String EXTRA_OI = "oi";
     field public static final java.lang.String EXTRA_OIR = "oir";
@@ -5928,11 +5965,13 @@
   }
 
   public final class ImsExternalCallState implements android.os.Parcelable {
+    ctor public ImsExternalCallState(java.lang.String, android.net.Uri, android.net.Uri, boolean, int, int, boolean);
     method public int describeContents();
     method public android.net.Uri getAddress();
     method public int getCallId();
     method public int getCallState();
     method public int getCallType();
+    method public android.net.Uri getLocalAddress();
     method public boolean isCallHeld();
     method public boolean isCallPullable();
     method public void writeToParcel(android.os.Parcel, int);
@@ -6352,7 +6391,8 @@
   }
 
   public static class MmTelFeature.MmTelCapabilities {
-    ctor public MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
+    ctor public MmTelFeature.MmTelCapabilities();
+    ctor public deprecated MmTelFeature.MmTelCapabilities(android.telephony.ims.feature.ImsFeature.Capabilities);
     ctor public MmTelFeature.MmTelCapabilities(int);
     method public final void addCapabilities(int);
     method public final boolean isCapable(int);
@@ -6650,7 +6690,7 @@
 package android.view {
 
   public abstract class Window {
-    method public void addPrivateFlags(int);
+    method public void addSystemFlags(int);
   }
 
   public abstract interface WindowManager implements android.view.ViewManager {
@@ -6660,7 +6700,10 @@
   public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
     method public final long getUserActivityTimeout();
     method public final void setUserActivityTimeout(long);
-    field public static final int PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 524288; // 0x80000
+    field public static final int SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 524288; // 0x80000
+  }
+
+  public static abstract class WindowManager.LayoutParams.SystemFlags implements java.lang.annotation.Annotation {
   }
 
 }
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 2246562..4e7a114 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -91,38 +91,6 @@
 
 }
 
-package android.security.keystore.recovery {
-
-  public final class KeyChainSnapshot implements android.os.Parcelable {
-    method public deprecated byte[] getTrustedHardwarePublicKey();
-  }
-
-  public class RecoveryController {
-    method public deprecated byte[] generateAndStoreKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
-    method public deprecated java.security.Key generateKey(java.lang.String, byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
-    method public deprecated java.util.List<java.lang.String> getAliases(java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
-    method public deprecated android.security.keystore.recovery.KeyChainSnapshot getRecoveryData() throws android.security.keystore.recovery.InternalRecoveryServiceException;
-    method public deprecated int getRecoveryStatus(java.lang.String, java.lang.String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
-    method public deprecated void initRecoveryService(java.lang.String, byte[]) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
-    method public deprecated void setRecoveryStatus(java.lang.String, java.lang.String, int) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.content.pm.PackageManager.NameNotFoundException;
-  }
-
-  public class RecoverySession implements java.lang.AutoCloseable {
-    method public deprecated java.util.Map<java.lang.String, byte[]> recoverKeys(byte[], java.util.List<android.security.keystore.recovery.WrappedApplicationKey>) throws android.security.keystore.recovery.DecryptionFailedException, android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.SessionExpiredException;
-    method public deprecated byte[] start(byte[], byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
-    method public deprecated byte[] start(java.security.cert.CertPath, byte[], byte[], java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
-  }
-
-  public final class WrappedApplicationKey implements android.os.Parcelable {
-    method public deprecated byte[] getAccount();
-  }
-
-  public static class WrappedApplicationKey.Builder {
-    method public deprecated android.security.keystore.recovery.WrappedApplicationKey.Builder setAccount(byte[]);
-  }
-
-}
-
 package android.service.notification {
 
   public abstract class NotificationListenerService extends android.app.Service {
diff --git a/api/test-current.txt b/api/test-current.txt
index dd02504..463c9d3 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -84,6 +84,7 @@
     method public static java.lang.String opToPermission(int);
     method public static int permissionToOpCode(java.lang.String);
     method public void setMode(int, int, java.lang.String, int);
+    method public void setUidMode(java.lang.String, int, int);
     method public void startWatchingActive(int[], android.app.AppOpsManager.OnOpActiveChangedListener);
     method public void stopWatchingActive(android.app.AppOpsManager.OnOpActiveChangedListener);
     method public static int strOpToOp(java.lang.String);
@@ -950,6 +951,7 @@
     field public static final java.lang.String LOCATION_GLOBAL_KILL_SWITCH = "location_global_kill_switch";
     field public static final java.lang.String LOW_POWER_MODE = "low_power";
     field public static final java.lang.String LOW_POWER_MODE_STICKY = "low_power_sticky";
+    field public static final java.lang.String SMS_ACCESS_RESTRICTION_ENABLED = "sms_access_restriction_enabled";
     field public static final java.lang.String USE_OPEN_WIFI_PACKAGE = "use_open_wifi_package";
   }
 
@@ -1607,6 +1609,10 @@
     method public void writeToParcelNoRecycle(android.os.Parcel, int);
   }
 
+  public static final class AccessibilityNodeInfo.TouchDelegateInfo implements android.os.Parcelable {
+    method public long getAccessibilityIdForRegion(android.graphics.Region);
+  }
+
   public final class AccessibilityWindowInfo implements android.os.Parcelable {
     method public static void setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger);
   }
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index c04e61b..41d546f 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -174,6 +174,8 @@
                 instrument.noWindowAnimation = true;
             } else if (opt.equals("--no-hidden-api-checks")) {
                 instrument.disableHiddenApiChecks = true;
+            } else if (opt.equals("--no-isolated-storage")) {
+                instrument.disableIsolatedStorage = true;
             } else if (opt.equals("--user")) {
                 instrument.userId = parseUserArg(nextArgRequired());
             } else if (opt.equals("--abi")) {
diff --git a/cmds/am/src/com/android/commands/am/Instrument.java b/cmds/am/src/com/android/commands/am/Instrument.java
index 0dade0b..70baa87 100644
--- a/cmds/am/src/com/android/commands/am/Instrument.java
+++ b/cmds/am/src/com/android/commands/am/Instrument.java
@@ -16,6 +16,9 @@
 
 package com.android.commands.am;
 
+import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
+
 import android.app.IActivityManager;
 import android.app.IInstrumentationWatcher;
 import android.app.Instrumentation;
@@ -74,16 +77,13 @@
     String logPath = null;
     public boolean noWindowAnimation = false;
     public boolean disableHiddenApiChecks = false;
+    public boolean disableIsolatedStorage = false;
     public String abi = null;
     public int userId = UserHandle.USER_CURRENT;
     public Bundle args = new Bundle();
     // Required
     public String componentNameArg;
 
-    // Disable hidden API checks for the newly started instrumentation.
-    // Must be kept in sync with ActivityManagerService.
-    private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
-
     /**
      * Construct the instrument command runner.
      */
@@ -480,7 +480,13 @@
             }
 
             // Start the instrumentation
-            int flags = disableHiddenApiChecks ? INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS : 0;
+            int flags = 0;
+            if (disableHiddenApiChecks) {
+                flags |= INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+            }
+            if (disableIsolatedStorage) {
+                flags |= INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
+            }
             if (!mAm.startInstrumentation(cn, profileFile, flags, args, watcher, connection, userId,
                         abi)) {
                 throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index e915cc8..5dcb392b 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -114,7 +114,7 @@
 
 void BootAnimation::onFirstRef() {
     status_t err = mSession->linkToComposerDeath(this);
-    ALOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
+    SLOGE_IF(err, "linkToComposerDeath failed (%s) ", strerror(-err));
     if (err == NO_ERROR) {
         run("BootAnimation", PRIORITY_DISPLAY);
     }
@@ -128,7 +128,7 @@
 void BootAnimation::binderDied(const wp<IBinder>&)
 {
     // woah, surfaceflinger died!
-    ALOGD("SurfaceFlinger died, exiting...");
+    SLOGD("SurfaceFlinger died, exiting...");
 
     // calling requestExit() is not enough here because the Surface code
     // might be blocked on a condition variable that will never be updated.
@@ -360,7 +360,7 @@
 
 bool BootAnimation::android()
 {
-    ALOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
+    SLOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
             elapsedRealtime());
     initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
     initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
@@ -508,14 +508,14 @@
 static bool readFile(ZipFileRO* zip, const char* name, String8& outString)
 {
     ZipEntryRO entry = zip->findEntryByName(name);
-    ALOGE_IF(!entry, "couldn't find %s", name);
+    SLOGE_IF(!entry, "couldn't find %s", name);
     if (!entry) {
         return false;
     }
 
     FileMap* entryMap = zip->createEntryFileMap(entry);
     zip->releaseEntry(entry);
-    ALOGE_IF(!entryMap, "entryMap is null");
+    SLOGE_IF(!entryMap, "entryMap is null");
     if (!entryMap) {
         return false;
     }
@@ -616,7 +616,7 @@
     size_t length = strftime(timeBuff, TIME_LENGTH, timeFormat, timeInfo);
 
     if (length != TIME_LENGTH - 1) {
-        ALOGE("Couldn't format time; abandoning boot animation clock");
+        SLOGE("Couldn't format time; abandoning boot animation clock");
         mClockEnabled = false;
         return;
     }
@@ -654,13 +654,13 @@
 
         char pathType;
         if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) {
-            // ALOGD("> w=%d, h=%d, fps=%d", width, height, fps);
+            // SLOGD("> w=%d, h=%d, fps=%d", width, height, fps);
             animation.width = width;
             animation.height = height;
             animation.fps = fps;
         } else if (sscanf(l, " %c %d %d %s #%6s %16s %16s",
                           &pathType, &count, &pause, path, color, clockPos1, clockPos2) >= 4) {
-            //ALOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s, clockPos1=%s, clockPos2=%s",
+            //SLOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s, clockPos1=%s, clockPos2=%s",
             //    pathType, count, pause, path, color, clockPos1, clockPos2);
             Animation::Part part;
             part.playUntilComplete = pathType == 'c';
@@ -670,7 +670,7 @@
             part.audioData = NULL;
             part.animation = NULL;
             if (!parseColor(color, part.backgroundColor)) {
-                ALOGE("> invalid color '#%s'", color);
+                SLOGE("> invalid color '#%s'", color);
                 part.backgroundColor[0] = 0.0f;
                 part.backgroundColor[1] = 0.0f;
                 part.backgroundColor[2] = 0.0f;
@@ -679,7 +679,7 @@
             animation.parts.add(part);
         }
         else if (strcmp(l, "$SYSTEM") == 0) {
-            // ALOGD("> SYSTEM");
+            // SLOGD("> SYSTEM");
             Animation::Part part;
             part.playUntilComplete = false;
             part.count = 1;
@@ -710,7 +710,7 @@
     while ((entry = zip->nextEntry(cookie)) != NULL) {
         const int foundEntryName = zip->getEntryFileName(entry, name, ANIM_ENTRY_NAME_MAX);
         if (foundEntryName > ANIM_ENTRY_NAME_MAX || foundEntryName == -1) {
-            ALOGE("Error fetching entry file name");
+            SLOGE("Error fetching entry file name");
             continue;
         }
 
@@ -754,7 +754,7 @@
                                 }
                             }
                         } else {
-                            ALOGE("bootanimation.zip is compressed; must be only stored");
+                            SLOGE("bootanimation.zip is compressed; must be only stored");
                         }
                     }
                 }
@@ -782,7 +782,7 @@
                 frame.trimX = x;
                 frame.trimY = y;
             } else {
-                ALOGE("Error parsing trim.txt, line: %s", lineStr);
+                SLOGE("Error parsing trim.txt, line: %s", lineStr);
                 break;
             }
         }
@@ -876,7 +876,7 @@
     const int animationX = (mWidth - animation.width) / 2;
     const int animationY = (mHeight - animation.height) / 2;
 
-    ALOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
+    SLOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
             elapsedRealtime());
     for (size_t i=0 ; i<pcount ; i++) {
         const Animation::Part& part(animation.parts[i]);
@@ -949,7 +949,7 @@
 
                 nsecs_t now = systemTime();
                 nsecs_t delay = frameDuration - (now - lastFrame);
-                //ALOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay));
+                //SLOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay));
                 lastFrame = now;
 
                 if (delay > 0) {
@@ -1048,13 +1048,13 @@
 BootAnimation::Animation* BootAnimation::loadAnimation(const String8& fn)
 {
     if (mLoadedFiles.indexOf(fn) >= 0) {
-        ALOGE("File \"%s\" is already loaded. Cyclic ref is not allowed",
+        SLOGE("File \"%s\" is already loaded. Cyclic ref is not allowed",
             fn.string());
         return NULL;
     }
     ZipFileRO *zip = ZipFileRO::open(fn);
     if (zip == NULL) {
-        ALOGE("Failed to open animation zip \"%s\": %s",
+        SLOGE("Failed to open animation zip \"%s\": %s",
             fn.string(), strerror(errno));
         return NULL;
     }
@@ -1143,7 +1143,7 @@
     if (pollResult == 0) {
         return true;
     } else if (pollResult < 0) {
-        ALOGE("Could not poll inotify events");
+        SLOGE("Could not poll inotify events");
         return false;
     }
 
@@ -1152,7 +1152,7 @@
     if (length == 0) {
         return true;
     } else if (length < 0) {
-        ALOGE("Could not read inotify events");
+        SLOGE("Could not read inotify events");
         return false;
     }
 
@@ -1183,7 +1183,7 @@
 status_t BootAnimation::TimeCheckThread::readyToRun() {
     mInotifyFd = inotify_init();
     if (mInotifyFd < 0) {
-        ALOGE("Could not initialize inotify fd");
+        SLOGE("Could not initialize inotify fd");
         return NO_INIT;
     }
 
@@ -1191,7 +1191,7 @@
     if (mSystemWd < 0) {
         close(mInotifyFd);
         mInotifyFd = -1;
-        ALOGE("Could not add watch for %s", SYSTEM_DATA_DIR_PATH);
+        SLOGE("Could not add watch for %s", SYSTEM_DATA_DIR_PATH);
         return NO_INIT;
     }
 
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index 12fb4a3..1597c8c 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -33,11 +33,7 @@
 import android.os.UserHandle;
 import android.text.TextUtils;
 
-import libcore.io.Streams;
-
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 
 /**
  * This class is a command line utility for manipulating content. A client
diff --git a/cmds/incidentd/Android.mk b/cmds/incidentd/Android.mk
index db864ae..eba5586 100644
--- a/cmds/incidentd/Android.mk
+++ b/cmds/incidentd/Android.mk
@@ -33,6 +33,9 @@
 LOCAL_CFLAGS += \
         -Wall -Werror -Wno-missing-field-initializers -Wno-unused-variable -Wunused-parameter
 
+# Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed.
+LOCAL_CFLAGS += -Wno-error=implicit-fallthrough
+
 ifeq (debug,)
     LOCAL_CFLAGS += \
             -g -O0
@@ -100,6 +103,9 @@
 
 LOCAL_CFLAGS := -Werror -Wall -Wno-unused-variable -Wunused-parameter
 
+# Allow implicit fallthrough in IncidentService.cpp:85 until it is fixed.
+LOCAL_CFLAGS += -Wno-error=implicit-fallthrough
+
 LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
 
 LOCAL_SRC_FILES := $(call all-cpp-files-under, tests) \
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index d334f96..8fa2980 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -31,6 +31,7 @@
 #include <gui/ISurfaceComposer.h>
 
 #include <ui/DisplayInfo.h>
+#include <ui/GraphicTypes.h>
 #include <ui/PixelFormat.h>
 
 #include <system/graphics.h>
@@ -74,12 +75,12 @@
     }
 }
 
-static sk_sp<SkColorSpace> dataSpaceToColorSpace(android_dataspace d)
+static sk_sp<SkColorSpace> dataSpaceToColorSpace(ui::Dataspace d)
 {
     switch (d) {
-        case HAL_DATASPACE_V0_SRGB:
+        case ui::Dataspace::V0_SRGB:
             return SkColorSpace::MakeSRGB();
-        case HAL_DATASPACE_DISPLAY_P3:
+        case ui::Dataspace::DISPLAY_P3:
             return SkColorSpace::MakeRGB(
                     SkColorSpace::kSRGB_RenderTargetGamma, SkColorSpace::kDCIP3_D65_Gamut);
         default:
@@ -87,12 +88,26 @@
     }
 }
 
-static uint32_t dataSpaceToInt(android_dataspace d)
+static ui::Dataspace pickBestDataspace(ui::ColorMode colorMode)
+{
+    switch (colorMode) {
+        case ui::ColorMode::SRGB:
+            return ui::Dataspace::V0_SRGB;
+        case ui::ColorMode::DISPLAY_P3:
+        case ui::ColorMode::BT2100_PQ:
+        case ui::ColorMode::BT2100_HLG:
+            return ui::Dataspace::DISPLAY_P3;
+        default:
+            return ui::Dataspace::V0_SRGB;
+    }
+}
+
+static uint32_t dataSpaceToInt(ui::Dataspace d)
 {
     switch (d) {
-        case HAL_DATASPACE_V0_SRGB:
+        case ui::Dataspace::V0_SRGB:
             return COLORSPACE_SRGB;
-        case HAL_DATASPACE_DISPLAY_P3:
+        case ui::Dataspace::DISPLAY_P3:
             return COLORSPACE_DISPLAY_P3;
         default:
             return COLORSPACE_UNKNOWN;
@@ -161,7 +176,6 @@
 
     void* base = NULL;
     uint32_t w, s, h, f;
-    android_dataspace d;
     size_t size = 0;
 
     // Maps orientations from DisplayInfo to ISurfaceComposer
@@ -197,8 +211,15 @@
     uint32_t captureOrientation = ORIENTATION_MAP[displayOrientation];
 
     sp<GraphicBuffer> outBuffer;
-    status_t result = ScreenshotClient::capture(display, Rect(), 0 /* reqWidth */,
-            0 /* reqHeight */, false, captureOrientation, &outBuffer);
+    ui::Dataspace reqDataspace =
+        pickBestDataspace(SurfaceComposerClient::getActiveColorMode(display));
+
+    // Due to the fact that we hard code the way we write pixels into screenshot,
+    // we hard code RGBA_8888 here.
+    ui::PixelFormat reqPixelFormat = ui::PixelFormat::RGBA_8888;
+    status_t result = ScreenshotClient::capture(display, reqDataspace, reqPixelFormat, Rect(),
+                                                0 /* reqWidth */, 0 /* reqHeight */, false,
+                                                captureOrientation, &outBuffer);
     if (result != NO_ERROR) {
         close(fd);
         return 1;
@@ -222,12 +243,12 @@
     h = outBuffer->getHeight();
     s = outBuffer->getStride();
     f = outBuffer->getPixelFormat();
-    d = HAL_DATASPACE_UNKNOWN;
     size = s * h * bytesPerPixel(f);
 
     if (png) {
         const SkImageInfo info =
-            SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType, dataSpaceToColorSpace(d));
+            SkImageInfo::Make(w, h, flinger2skia(f), kPremul_SkAlphaType,
+                              dataSpaceToColorSpace(reqDataspace));
         SkPixmap pixmap(info, base, s * bytesPerPixel(f));
         struct FDWStream final : public SkWStream {
           size_t fBytesWritten = 0;
@@ -244,7 +265,7 @@
             notifyMediaScanner(fn);
         }
     } else {
-        uint32_t c = dataSpaceToInt(d);
+        uint32_t c = dataSpaceToInt(reqDataspace);
         write(fd, &w, 4);
         write(fd, &h, 4);
         write(fd, &f, 4);
@@ -261,4 +282,4 @@
     }
 
     return 0;
-}
\ No newline at end of file
+}
diff --git a/cmds/statsd/Android.mk b/cmds/statsd/Android.mk
index f6b0db8..5818f5d 100644
--- a/cmds/statsd/Android.mk
+++ b/cmds/statsd/Android.mk
@@ -46,6 +46,7 @@
     src/logd/LogEvent.cpp \
     src/logd/LogListener.cpp \
     src/matchers/CombinationLogMatchingTracker.cpp \
+    src/matchers/EventMatcherWizard.cpp \
     src/matchers/matcher_util.cpp \
     src/matchers/SimpleLogMatchingTracker.cpp \
     src/metrics/MetricProducer.cpp \
@@ -189,6 +190,7 @@
     src/atom_field_options.proto \
     src/atoms.proto \
     src/stats_log.proto \
+    src/shell/shell_data.proto \
     tests/AlarmMonitor_test.cpp \
     tests/anomaly/AlarmTracker_test.cpp \
     tests/anomaly/AnomalyTracker_test.cpp \
@@ -216,6 +218,7 @@
     tests/metrics/metrics_test_helper.cpp \
     tests/statsd_test_util.cpp \
     tests/e2e/WakelockDuration_e2e_test.cpp \
+    tests/e2e/MetricActivation_e2e_test.cpp \
     tests/e2e/MetricConditionLink_e2e_test.cpp \
     tests/e2e/Alarm_e2e_test.cpp \
     tests/e2e/Attribution_e2e_test.cpp \
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 4091d95..3e8b9b8 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -39,7 +39,8 @@
     GET_DATA_CALLED = 4,
     ADB_DUMP = 5,
     CONFIG_RESET = 6,
-    STATSCOMPANION_DIED = 7
+    STATSCOMPANION_DIED = 7,
+    TERMINATION_SIGNAL_RECEIVED = 8
 };
 
 class StatsLogProcessor : public ConfigListener {
@@ -193,7 +194,7 @@
     FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
-    FRIEND_TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents);
+    FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
 
@@ -218,6 +219,7 @@
 
     FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
     FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 8da2d44..ce28777 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -319,7 +319,7 @@
         }
         if (!args[0].compare(String8("data-subscribe"))) {
             if (mShellSubscriber == nullptr) {
-                mShellSubscriber = new ShellSubscriber(mUidMap);
+                mShellSubscriber = new ShellSubscriber(mUidMap, mPullerManager);
             }
             mShellSubscriber->startNewSubscription(in, out, resultReceiver);
             return NO_ERROR;
@@ -867,6 +867,13 @@
     mConfigManager->Startup();
 }
 
+void StatsService::Terminate() {
+    ALOGI("StatsService::Terminating");
+    if (mProcessor != nullptr) {
+        mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED);
+    }
+}
+
 void StatsService::OnLogEvent(LogEvent* event) {
     mProcessor->OnLogEvent(event);
     if (mShellSubscriber != nullptr) {
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 1f1d782..cbf3429 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -84,6 +84,11 @@
     void Startup();
 
     /**
+     * Called when terminiation signal received.
+     */
+    void Terminate();
+
+    /**
      * Called by LogReader when there's a log event to process.
      */
     virtual void OnLogEvent(LogEvent* event);
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index a2a03b1..e33bd8c 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -36,8 +36,8 @@
 // exclusive state field, and any number of primary key fields.
 // For example,
 // message UidProcessStateChanged {
-//    optional int32 uid = 1 [(stateFieldOption).option = PRIMARY];
-//    optional android.app.ProcessStateEnum state = 2 [(stateFieldOption).option = EXCLUSIVE];
+//    optional int32 uid = 1 [(state_field_option).option = PRIMARY];
+//    optional android.app.ProcessStateEnum state = 2 [(state_field_option).option = EXCLUSIVE];
 //  }
 // Each of this UidProcessStateChanged atom represents a state change for a specific uid.
 // A new state automatically overrides the previous state.
@@ -46,16 +46,16 @@
 // the primary key.
 // For example:
 // message ThreadStateChanged {
-//    optional int32 pid = 1  [(stateFieldOption).option = PRIMARY];
-//    optional int32 tid = 2  [(stateFieldOption).option = PRIMARY];
-//    optional int32 state = 3 [(stateFieldOption).option = EXCLUSIVE];
+//    optional int32 pid = 1  [(state_field_option).option = PRIMARY];
+//    optional int32 tid = 2  [(state_field_option).option = PRIMARY];
+//    optional int32 state = 3 [(state_field_option).option = EXCLUSIVE];
 // }
 //
 // Sometimes, there is no primary key field, when the state is GLOBAL.
 // For example,
 //
 // message ScreenStateChanged {
-//    optional android.view.DisplayStateEnum state = 1 [(stateFieldOption).option = EXCLUSIVE];
+//    optional android.view.DisplayStateEnum state = 1 [(state_field_option).option = EXCLUSIVE];
 // }
 //
 // Only fields of primary types can be annotated. AttributionNode cannot be primary keys (and they
@@ -64,10 +64,22 @@
     optional StateField option = 1 [default = STATE_FIELD_UNSET];
 }
 
+// Used to generate StatsLog.write APIs.
+enum LogMode {
+    MODE_UNSET = 0;
+    // Log fields as their actual types e.g., all primary data types.
+    // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode
+    MODE_AUTOMATIC = 1;
+    // Log fields in their proto binary format. These fields will not be parsed in statsd
+    MODE_BYTES = 2;
+}
+
 extend google.protobuf.FieldOptions {
     // Flags to decorate an atom that presents a state change.
-    optional StateAtomFieldOption stateFieldOption = 50000;
+    optional StateAtomFieldOption state_field_option = 50000;
 
     // Flags to decorate the uid fields in an atom.
     optional bool is_uid = 50001 [default = false];
+
+    optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
 }
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 988ffc4..d52dec1 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -22,15 +22,16 @@
 
 import "frameworks/base/cmds/statsd/src/atom_field_options.proto";
 import "frameworks/base/core/proto/android/app/enums.proto";
+import "frameworks/base/core/proto/android/app/settings_enums.proto";
 import "frameworks/base/core/proto/android/app/job/enums.proto";
 import "frameworks/base/core/proto/android/bluetooth/enums.proto";
 import "frameworks/base/core/proto/android/os/enums.proto";
 import "frameworks/base/core/proto/android/server/enums.proto";
+import "frameworks/base/core/proto/android/service/procstats_enum.proto";
+import "frameworks/base/core/proto/android/stats/enums.proto";
 import "frameworks/base/core/proto/android/telecomm/enums.proto";
 import "frameworks/base/core/proto/android/telephony/enums.proto";
 import "frameworks/base/core/proto/android/view/enums.proto";
-import "frameworks/base/proto/src/stats_enums.proto";
-import "frameworks/base/core/proto/android/service/procstats.proto";
 
 /**
  * The master atom class. This message defines all of the available
@@ -141,10 +142,14 @@
         BatteryHealthSnapshot battery_health_snapshot = 91;
         SlowIo slow_io = 92;
         BatteryCausedShutdown battery_caused_shutdown = 93;
+        PhoneServiceStateChanged phone_service_state_changed = 94;
+        PhoneStateChanged phone_state_changed = 95;
+        UserRestrictionChanged user_restriction_changed = 96;
+        SettingsUIChanged settings_ui_changed = 97;
     }
 
     // Pulled events will start at field 10000.
-    // Next: 10025
+    // Next: 10037
     oneof pulled {
         WifiBytesTransfer wifi_bytes_transfer = 10000;
         WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001;
@@ -175,10 +180,14 @@
         DirectoryUsage directory_usage = 10026;
         AppSize app_size = 10027;
         CategorySize category_size = 10028;
+        ProcStats proc_stats = 10029;
         BatteryVoltage battery_voltage = 10030;
         NumFingerprints num_fingerprints = 10031;
-        ProcStats proc_stats = 10029;
         DiskIo disk_io = 10032;
+        PowerProfile power_profile = 10033;
+        ProcStats proc_stats_pkg_proc = 10034;
+        ProcessCpuTime process_cpu_time = 10035;
+        NativeProcessMemoryState native_process_memory_state = 10036;
     }
 
     // DO NOT USE field numbers above 100,000 in AOSP.
@@ -270,7 +279,7 @@
  */
 message ScreenStateChanged {
     // New screen state, from frameworks/base/core/proto/android/view/enums.proto.
-    optional android.view.DisplayStateEnum state = 1 [(stateFieldOption).option = EXCLUSIVE];
+    optional android.view.DisplayStateEnum state = 1 [(state_field_option).option = EXCLUSIVE];
 }
 
 /**
@@ -281,10 +290,10 @@
  *   frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
  */
 message UidProcessStateChanged {
-    optional int32 uid = 1 [(stateFieldOption).option = PRIMARY, (is_uid) = true];
+    optional int32 uid = 1 [(state_field_option).option = PRIMARY, (is_uid) = true];
 
     // The state, from frameworks/base/core/proto/android/app/enums.proto.
-    optional android.app.ProcessStateEnum state = 2 [(stateFieldOption).option = EXCLUSIVE];
+    optional android.app.ProcessStateEnum state = 2 [(state_field_option).option = EXCLUSIVE];
 }
 
 /**
@@ -316,7 +325,7 @@
         ASLEEP = 1;
         AWAKE = 2;
     }
-    optional State state = 1 [(stateFieldOption).option = EXCLUSIVE];
+    optional State state = 1 [(state_field_option).option = EXCLUSIVE];
 }
 
 /**
@@ -335,7 +344,7 @@
         CRITICAL = 4;   // critical memory.
 
     }
-    optional State factor = 1 [(stateFieldOption).option = EXCLUSIVE];
+    optional State factor = 1 [(state_field_option).option = EXCLUSIVE];
 }
 
 /**
@@ -634,7 +643,7 @@
 
     // The type (level) of the wakelock; e.g. a partial wakelock or a full wakelock.
     // From frameworks/base/core/proto/android/os/enums.proto.
-    optional android.os.WakeLockLevelEnum level = 2;
+    optional android.os.WakeLockLevelEnum type = 2;
 
     // The wakelock tag (Called tag in the Java API, sometimes name elsewhere).
     optional string tag = 3;
@@ -1027,20 +1036,20 @@
     // Bit mask of color capabilities of the screen.
     // Contains information about the color gamut and hdr mode of the screen.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#colorMode
-    optional int32 colorMode = 1;
+    optional int32 color_mode = 1;
 
     // The target screen density being rendered to.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#densityDpi
-    optional int32 densityDpi = 2;
+    optional int32 density_dpi = 2;
 
     // Current user preference for the scaling factor for fonts,
     // relative to the base density scaling.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#fontScale
-    optional float fontScale = 3;
+    optional float font_scale = 3;
 
     // Flag indicating whether the hard keyboard is hidden.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#hardKeyboardHidden
-    optional int32 hardKeyboardHidden = 4;
+    optional int32 hard_keyboard_hidden = 4;
 
     // The type of keyboard attached to the device.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#keyboard
@@ -1048,7 +1057,7 @@
 
     // Flag indicating whether any keyboard is available. Takes soft keyboards into account.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#keyboardHidden
-    optional int32 keyboardHideen = 6;
+    optional int32 keyboard_hidden = 6;
 
     // IMSI MCC (Mobile Country Code), corresponding to mcc resource qualifier.
     // 0 if undefined.
@@ -1067,7 +1076,7 @@
 
     // Flag indicating whether the navigation is available.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#navigationHidden
-    optional int32 navigationHidden = 10;
+    optional int32 navigation_hidden = 10;
 
     // Overall orientation of the screen.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#orientation
@@ -1075,24 +1084,24 @@
 
     // The current height of the available screen space, in dp units.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#screenHeightDp
-    optional int32 screenHeightDp = 12;
+    optional int32 screen_height_dp = 12;
 
     // Bit mask of overall layout of the screen.
     // Contains information about screen size, whether the screen is wider/taller
     // than normal, whether the screen layout is right-tl-left or left-to-right,
     // and whether the screen has a rounded shape.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#screenLayout
-    optional int32 screenLayout = 13;
+    optional int32 screen_layout = 13;
 
     // Current width of the available screen space, in dp units.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#screenWidthDp
-    optional int32 screenWidthDp = 14;
+    optional int32 screen_width_dp = 14;
 
     // The smallest screen size an application will see in normal operation.
     // This is the smallest value of both screenWidthDp and screenHeightDp
     // in portrait and landscape.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#smallestScreenWidthDp
-    optional int32 smallestScreenWidthDp = 15;
+    optional int32 smallest_screen_width_dp = 15;
 
     // The type of touch screen attached to the device.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#touchscreen
@@ -1103,7 +1112,7 @@
     // Eg: NORMAL, DESK, CAR, TELEVISION, WATCH, VR_HEADSET
     // Also contains information about whether the device is in night mode.
     // See: https://d.android.com/reference/android/content/res/Configuration.html#uiMode
-    optional int32 uiMode = 17;
+    optional int32 ui_mode = 17;
 }
 
 
@@ -1190,7 +1199,7 @@
     // Eg. Airplane mode, crash, application request.
     optional android.bluetooth.EnableDisableReasonEnum reason = 3;
     // If the reason is an application request, this will be the package name.
-    optional string pkgName = 4;
+    optional string pkg_name = 4;
 }
 
 /**
@@ -1339,7 +1348,7 @@
     }
     optional BatterySnapshotType type = 1;
     // Temperature, in 1/10ths of degree C.
-    optional int32 temperature_deci_celcius = 2;
+    optional int32 temperature_deci_celsius = 2;
     // Voltage Battery Voltage, in microVolts.
     optional int32 voltage_micro_volt = 3;
     // Current Battery current, in microAmps.
@@ -1403,6 +1412,67 @@
     optional android.telephony.SignalStrengthEnum signal_strength = 1;
 }
 
+
+/**
+ * Logs when the phone state, sim state or signal strength changes
+ *
+ * Logged from:
+ *   frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ */
+message PhoneServiceStateChanged {
+    optional android.telephony.ServiceStateEnum state = 1;
+    optional android.telephony.SimStateEnum sim_state = 2;
+    optional android.telephony.SignalStrengthEnum signal_strength = 3;
+}
+
+/**
+ * Logs when the phone becomes on or off.
+ *
+ * Logged from:
+ *   frameworks/base/core/java/com/android/internal/os/TelephonyRegistry.java
+ */
+message PhoneStateChanged {
+    enum State {
+        OFF = 0;
+        ON = 1;
+    }
+    optional State state = 1;
+}
+
+/**
+ * Logs when Settings UI has changed.
+ *
+ * Logged from:
+ *   packages/apps/Settings
+ */
+message SettingsUIChanged {
+    /**
+     * Where this SettingsUIChange event comes from. For example, if
+     * it's a PAGE_VISIBLE event, where the page is opened from.
+     */
+    optional android.app.settings.PageId attribution = 1;
+
+    /**
+     * What the UI action is.
+     */
+    optional android.app.settings.Action action = 2;
+
+    /**
+     * Where the action is happening
+     */
+    optional android.app.settings.PageId pageId = 3;
+
+    /**
+     * What preference changed in this event.
+     */
+    optional string changedPreferenceKey = 4;
+
+    /**
+     * The new value of the changed preference.
+     */
+    optional int64 changedPreferenceIntValue = 5;
+}
+
 /**
  * Logs that a setting was updated.
  * Logged from:
@@ -1840,10 +1910,10 @@
     optional string activity_name = 3;
 
     // # of page-faults
-    optional int64 pgfault = 4;
+    optional int64 page_fault = 4;
 
     // # of major page-faults
-    optional int64 pgmajfault = 5;
+    optional int64 page_major_fault = 5;
 
     // RSS
     optional int64 rss_in_bytes = 6;
@@ -1883,13 +1953,13 @@
     optional string process_name = 2;
 
     // oom adj score.
-    optional int32 oom_score = 3;
+    optional int32 oom_adj_score = 3;
 
     // # of page-faults
-    optional int64 pgfault = 4;
+    optional int64 page_fault = 4;
 
     // # of major page-faults
-    optional int64 pgmajfault = 5;
+    optional int64 page_major_fault = 5;
 
     // RSS
     optional int64 rss_in_bytes = 6;
@@ -1909,7 +1979,7 @@
  */
 message AppDied {
     // timestamp(elapsedRealtime) of record creation
-    optional uint64 timestamp_millis = 1 [(stateFieldOption).option = EXCLUSIVE];
+    optional uint64 timestamp_millis = 1 [(state_field_option).option = EXCLUSIVE];
 }
 
 /**
@@ -1920,7 +1990,7 @@
     optional int32 uid = 1 [(is_uid) = true];
 
     // An event_id indicates the type of event.
-    optional android.os.statsd.EventType event_id = 2;
+    optional android.stats.EventType event_id = 2;
 }
 
 /**
@@ -2018,25 +2088,34 @@
     optional int32 importance = 7;
 
     // ID for the notification channel.
-    optional int32 channel_id = 8;
+    optional string channel_id = 8;
 
     // Importance for the notification channel.
     optional int32 channel_importance = 9;
 
+    // Application-supplied ID associated with the notifications group.
+    optional string group_id = 10;
+
     // Whether notification was a group summary.
-    optional bool group_summary = 10;
+    optional bool group_summary = 11;
 
-    // Time since notification was created in milliseconds.
-    optional int64 since_create_millis = 11;
+    // Reason for dismissal of a notification. This field is only meaningful for
+    // TYPE_DISMISS events.
+    optional int32 dismiss_reason = 12;
 
-    // Time since notification was interrupted in milliseconds.
-    optional int64 since_interruption_millis = 12;
+    // The first post time of notification, stable across updates.
+    optional int64 creation_millis = 13;
 
-    // Time since notification was updated in milliseconds.
-    optional int64 since_update_millis = 13;
+    // The most recent interruption time, or the creation time if no updates.
+    // Differs from update_millis because updates are filtered based on whether
+    // they actually interrupted the user.
+    optional int64 interruption_millis = 14;
 
-    // Time since notification was visible in milliseconds.
-    optional int64 since_visible_millis = 14;
+    // The most recent update time, or the creation time if no updates.
+    optional int64 update_millis = 15;
+
+    // The most recent visibility event.
+    optional int64 visible_millis = 16;
 }
 
 
@@ -2151,7 +2230,7 @@
 
     optional int32 version = 3;
 
-    optional int64 time = 4;
+    optional int64 time_micros = 4;
 }
 
 /**
@@ -2215,11 +2294,11 @@
     // stack reported state
     // TODO: replace this with proto enum
     optional int32 stack_state = 2;
-    // tx time in ms
+    // tx time in millis
     optional uint64 controller_tx_time_millis = 3;
-    // rx time in ms
+    // rx time in millis
     optional uint64 controller_rx_time_millis = 4;
-    // idle time in ms
+    // idle time in millis
     optional uint64 controller_idle_time_millis = 5;
     // product of current(mA), voltage(V) and time(ms)
     optional uint64 controller_energy_used = 6;
@@ -2231,9 +2310,9 @@
 message ModemActivityInfo {
     // timestamp(wall clock) of record creation
     optional uint64 timestamp_millis = 1;
-    // sleep time in ms.
+    // sleep time in millis.
     optional uint64 sleep_time_millis = 2;
-    // idle time in ms
+    // idle time in millis
     optional uint64 controller_idle_time_millis = 3;
     /**
      * Tx power index
@@ -2268,11 +2347,11 @@
     optional uint64 timestamp_millis = 1;
     // bluetooth stack state
     optional int32 bluetooth_stack_state = 2;
-    // tx time in ms
+    // tx time in millis
     optional uint64 controller_tx_time_millis = 3;
-    // rx time in ms
+    // rx time in millis
     optional uint64 controller_rx_time_millis = 4;
-    // idle time in ms
+    // idle time in millis
     optional uint64 controller_idle_time_millis = 5;
     // product of current(mA), voltage(V) and time(ms)
     optional uint64 energy_used = 6;
@@ -2289,13 +2368,13 @@
     optional string process_name = 2;
 
     // oom adj score.
-    optional int32 oom_score = 3;
+    optional int32 oom_adj_score = 3;
 
     // # of page-faults
-    optional int64 pgfault = 4;
+    optional int64 page_fault = 4;
 
     // # of major page-faults
-    optional int64 pgmajfault = 5;
+    optional int64 page_major_fault = 5;
 
     // RSS
     optional int64 rss_in_bytes = 6;
@@ -2313,6 +2392,31 @@
 }
 
 /*
+ * Logs the memory stats for a native process (from procfs).
+ */
+message NativeProcessMemoryState {
+  // The uid if available. -1 means not available.
+  optional int32 uid = 1 [(is_uid) = true];
+
+  // The process name.
+  optional string process_name = 2;
+
+  // # of page-faults
+  optional int64 page_fault = 3;
+
+  // # of major page-faults
+  optional int64 page_major_fault = 4;
+
+  // RSS
+  optional int64 rss_in_bytes = 5;
+
+  // RSS high watermark.
+  // Peak RSS usage of the process. Value is read from the VmHWM field in /proc/PID/status or
+  // from memory.max_usage_in_bytes under /dev/memcg if the device uses per-app memory cgroups.
+  optional int64 rss_high_watermark_in_bytes = 6;
+}
+
+/*
  * Elapsed real time from SystemClock.
  */
 message SystemElapsedRealtime {
@@ -2377,7 +2481,7 @@
  *   frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
  */
 message RemainingBatteryCapacity {
-    optional int32 charge_uAh = 1;
+    optional int32 charge_micro_ampere_hour = 1;
 }
 
 /**
@@ -2386,7 +2490,7 @@
  *   frameworks/base/cmds/statsd/src/external/ResourceHealthManagerPuller.cpp
  */
 message FullBatteryCapacity {
-    optional int32 capacity_uAh = 1;
+    optional int32 capacity_micro_ampere_hour = 1;
 }
 
 /**
@@ -2396,7 +2500,7 @@
  */
 message BatteryVoltage {
     // The voltage of the battery, in millivolts.
-    optional int32 voltage_mV = 1;
+    optional int32 voltage_millivolt = 1;
 }
 
 /**
@@ -2414,7 +2518,7 @@
     optional string sensor_name = 2;
 
     // Temperature in tenths of a degree C.
-    optional int32 temperature_dC = 3;
+    optional int32 temperature_deci_celsius = 3;
 }
 
 /**
@@ -2524,8 +2628,7 @@
     // recorded_message_count.
     //
     // If recorded_message_count is different than message_count, it means data
-    // collection has been sampled. All the fields below will be sampled in this
-    // case.
+    // collection has been sampled. The fields below will be sampled in this case.
     optional int64 recorded_message_count = 7;
 
     // Total latency of all processed messages.
@@ -2541,6 +2644,32 @@
 
     // True if the screen was interactive PowerManager#isInteractive at the end of the call.
     optional bool screen_interactive = 10;
+
+    // Max recorded CPU usage of all processed messages.
+    optional int64 recorded_max_cpu_micros = 11;
+
+    // Max recorded latency of all processed messages.
+    optional int64 recorded_max_latency_micros = 12;
+
+    // Total number of messages we tracked the dispatching delay for. If we
+    // collected data for all the messages, message_count will be equal to
+    // recorded_delay_message_count.
+    //
+    // If recorded_delay_message_count is different than message_count, it means data
+    // collection has been sampled or/and not all messages specified the target dispatch time.
+    // The fields below will be sampled in this case.
+    optional int64 recorded_delay_message_count = 13;
+
+    // Total dispatching delay of all processed messages.
+    // Calculated as a difference between the target dispatching time (Message.when)
+    // and the actual dispatching time.
+    // Average can be computed using recorded_total_delay_millis / recorded_delay_message_count.
+    optional int64 recorded_total_delay_millis = 14;
+
+    // Max dispatching delay of all processed messages.
+    // Calculated as a difference between the target dispatching time (Message.when)
+    // and the actual dispatching time.
+    optional int64 recorded_max_delay_millis = 15;
 }
 
 /**
@@ -2659,9 +2788,324 @@
     optional int32 num_fingerprints = 2;
 }
 
+message AggStats {
+    optional int64 min = 1;
+
+    optional int64 average = 2;
+
+    optional int64 max = 3;
+}
+
+message ProcessStatsStateProto {
+    optional android.service.procstats.ScreenState screen_state = 1;
+
+    optional android.service.procstats.MemoryState memory_state = 2;
+
+    // this enum list is from frameworks/base/core/java/com/android/internal/app/procstats/ProcessStats.java
+    // and not frameworks/base/core/java/android/app/ActivityManager.java
+    optional android.service.procstats.ProcessState process_state = 3;
+
+    // Millisecond uptime duration spent in this state
+    optional int64 duration_millis = 4;
+
+    // Millisecond elapsed realtime duration spent in this state
+    optional int64 realtime_duration_millis = 9;
+
+    // # of samples taken
+    optional int32 sample_size = 5;
+
+    // PSS is memory reserved for this process
+    optional AggStats pss = 6;
+
+    // USS is memory shared between processes, divided evenly for accounting
+    optional AggStats uss = 7;
+
+    // RSS is memory resident for this process
+    optional AggStats rss = 8;
+}
+
+// Next Tag: 7
+message ProcessStatsProto {
+    // Name of process.
+    optional string process = 1;
+
+    // Uid of the process.
+    optional int32 uid = 2;
+
+    // Information about how often kills occurred
+    message Kill {
+        // Count of excessive CPU kills
+        optional int32 cpu = 1;
+
+        // Count of kills when cached
+        optional int32 cached = 2;
+
+        // PSS stats during cached kill
+        optional AggStats cached_pss = 3;
+    }
+    optional Kill kill = 3;
+
+    // Time and memory spent in various states.
+    repeated ProcessStatsStateProto states = 5;
+
+    // Total time process has been running...  screen_state, memory_state, and process_state
+    // will not be set.
+    optional ProcessStatsStateProto total_running_state = 6;
+}
+
+message PackageServiceOperationStatsProto {
+    // Operate enum: Started, Foreground, Bound, Executing
+    optional android.service.procstats.ServiceOperationState operation = 1;
+
+    // Number of times the service was in this operation.
+    optional int32 count = 2;
+
+    // Information about a state the service can be in.
+    message StateStats {
+        // Screen state enum.
+        optional android.service.procstats.ScreenState screen_state = 1;
+        // Memory state enum.
+        optional android.service.procstats.MemoryState memory_state = 2;
+
+        // duration in milliseconds.
+        optional int64 duration_millis = 3;
+        // Millisecond elapsed realtime duration spent in this state
+        optional int64 realtime_duration_millis = 4;
+    }
+    repeated StateStats state_stats = 3;
+}
+
+message PackageServiceStatsProto {
+    // Name of service component.
+    optional string service_name = 1;
+
+    // The operation stats.
+    // The package_name, package_uid, package_version, service_name will not be set to save space.
+    repeated PackageServiceOperationStatsProto operation_stats = 2;
+}
+
+message PackageAssociationSourceProcessStatsProto {
+    // Uid of the process.
+    optional int32 process_uid = 1;
+    // Process name.
+    optional string process_name = 2;
+
+    // Total count of the times this association appeared.
+    optional int32 total_count = 3;
+
+    // Millisecond uptime total duration this association was around.
+    optional int64 total_duration_millis = 4;
+
+    // Total count of the times this association became actively impacting its target process.
+    optional int32 active_count = 5;
+
+    // Information on one source in this association.
+    message StateStats {
+        // Process state enum.
+        optional android.service.procstats.ProcessState process_state = 1;
+        // Millisecond uptime duration spent in this state
+        optional int64 duration_millis = 2;
+        // Millisecond elapsed realtime duration spent in this state
+        optional int64 realtime_duration_mmillis = 3;
+    }
+    repeated StateStats active_state_stats = 6;
+}
+
+message PackageAssociationProcessStatsProto {
+    // Name of the target component.
+    optional string component_name = 1;
+    // Information on one source in this association.
+    repeated PackageAssociationSourceProcessStatsProto sources = 2;
+}
+
+
+message ProcessStatsPackageProto {
+    // Name of package.
+    optional string package = 1;
+
+    // Uid of the package.
+    optional int32 uid = 2;
+
+    // Version of the package.
+    optional int64 version = 3;
+
+    // Stats for each process running with the package loaded in to it.
+    repeated ProcessStatsProto process_stats = 4;
+
+    // Stats for each of the package's services.
+    repeated PackageServiceStatsProto service_stats = 5;
+
+    // Stats for each association with the package.
+    repeated PackageAssociationProcessStatsProto association_stats = 6;
+}
+
+message ProcessStatsSectionProto {
+    // Elapsed realtime at start of report.
+    optional int64 start_realtime_millis = 1;
+
+    // Elapsed realtime at end of report.
+    optional int64 end_realtime_millis = 2;
+
+    // CPU uptime at start of report.
+    optional int64 start_uptime_millis = 3;
+
+    // CPU uptime at end of report.
+    optional int64 end_uptime_millis = 4;
+
+    // System runtime library. e.g. "libdvm.so", "libart.so".
+    optional string runtime = 5;
+
+    // whether kernel reports swapped pss.
+    optional bool has_swapped_pss = 6;
+
+    // Data completeness. e.g. "complete", "partial", shutdown", or "sysprops".
+    enum Status {
+        STATUS_UNKNOWN = 0;
+        STATUS_COMPLETE = 1;
+        STATUS_PARTIAL = 2;
+        STATUS_SHUTDOWN = 3;
+        STATUS_SYSPROPS = 4;
+    }
+    repeated Status status = 7;
+
+    // Stats for each process.
+    repeated ProcessStatsProto process_stats = 8;
+
+    // Stats for each package.
+    repeated ProcessStatsPackageProto package_stats = 9;
+}
+
 /**
  * Pulled from ProcessStatsService.java
  */
 message ProcStats {
-    optional android.service.procstats.ProcessStatsSectionProto proc_stats_section = 1;
+    optional ProcessStatsSectionProto proc_stats_section = 1;
 }
+
+message PowerProfileProto {
+    optional double cpu_suspend = 1;
+
+    optional double cpu_idle = 2;
+
+    optional double cpu_active = 3;
+
+    message CpuCluster {
+        optional int32 id = 1;
+        optional double cluster_power = 2;
+        optional int32 cores = 3;
+        repeated int64 speed = 4;
+        repeated double core_power = 5;
+    }
+
+    repeated CpuCluster cpu_cluster = 40;
+
+    optional double wifi_scan = 4;
+
+    optional double wifi_on = 5;
+
+    optional double wifi_active = 6;
+
+    optional double wifi_controller_idle = 7;
+
+    optional double wifi_controller_rx = 8;
+
+    optional double wifi_controller_tx = 9;
+
+    repeated double wifi_controller_tx_levels = 10;
+
+    optional double wifi_controller_operating_voltage = 11;
+
+    optional double bluetooth_controller_idle = 12;
+
+    optional double bluetooth_controller_rx = 13;
+
+    optional double bluetooth_controller_tx = 14;
+
+    optional double bluetooth_controller_operating_voltage = 15;
+
+    optional double modem_controller_sleep = 16;
+
+    optional double modem_controller_idle = 17;
+
+    optional double modem_controller_rx = 18;
+
+    repeated double modem_controller_tx = 19;
+
+    optional double modem_controller_operating_voltage = 20;
+
+    optional double gps_on = 21;
+
+    repeated double gps_signal_quality_based = 22;
+
+    optional double gps_operating_voltage = 23;
+
+    optional double bluetooth_on = 24;
+
+    optional double bluetooth_active = 25;
+
+    optional double bluetooth_at_cmd = 26;
+
+    optional double ambient_display = 27;
+
+    optional double screen_on = 28;
+
+    optional double radio_on = 29;
+
+    optional double radio_scanning = 30;
+
+    optional double radio_active = 31;
+
+    optional double screen_full = 32;
+
+    optional double audio = 33;
+
+    optional double video = 34;
+
+    optional double flashlight = 35;
+
+    optional double memory = 36;
+
+    optional double camera = 37;
+
+    optional double wifi_batched_scan = 38;
+
+    optional double battery_capacity = 39;
+}
+
+/**
+ * power_profile.xml and other constants for power model calculations.
+ * Pulled from PowerProfile.java
+ */
+message PowerProfile {
+    optional PowerProfileProto power_profile = 1;
+}
+
+/**
+ * Logs when a user restriction was added or removed.
+ *
+ * Logged from:
+ *   frameworks/base/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+ */
+message UserRestrictionChanged {
+    // The raw string of the user restriction as defined in UserManager.
+    // Allowed values are defined in UserRestrictionsUtils#USER_RESTRICTIONS.
+    optional string restriction = 1;
+    // Whether the restriction is enabled or disabled.
+    optional bool enabled = 2;
+}
+
+/**
+ * Pulls process user time and system time. Puller takes a snapshot of all pids
+ * in the system and returns cpu stats for those that are working at the time.
+ * Dead pids will be dropped. Kernel processes are excluded.
+ * Min cool-down is 5 sec.
+ */
+message ProcessCpuTime {
+    optional int32 uid = 1 [(is_uid) = true];
+
+    optional string process_name = 2;
+    // Process cpu time in user space, cumulative from boot/process start
+    optional int64 user_time_millis = 3;
+    // Process cpu time in system space, cumulative from boot/process start
+    optional int64 system_time_millis = 4;
+}
\ No newline at end of file
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
index 6d7bba0..3eb05a9 100644
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
+++ b/cmds/statsd/src/external/StatsCompanionServicePuller.cpp
@@ -54,7 +54,7 @@
         vector<StatsLogEventWrapper> returned_value;
         Status status = statsCompanionServiceCopy->pullData(mTagId, &returned_value);
         if (!status.isOk()) {
-            ALOGW("StatsCompanionServicePuller::pull failed to pull for %d", mTagId);
+            ALOGW("StatsCompanionServicePuller::pull failed for %d", mTagId);
             return false;
         }
         data->clear();
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index fd86714..ba626f8 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -170,6 +170,12 @@
           {2, 3},
           1 * NS_PER_SEC,
           new StatsCompanionServicePuller(android::util::PROCESS_MEMORY_STATE)}},
+        // native_process_memory_state
+        {android::util::NATIVE_PROCESS_MEMORY_STATE,
+         {{3, 4, 5, 6},
+          {2},
+          1 * NS_PER_SEC,
+          new StatsCompanionServicePuller(android::util::NATIVE_PROCESS_MEMORY_STATE)}},
         // temperature
         {android::util::TEMPERATURE, {{}, {}, 1 * NS_PER_SEC, new ResourceThermalManagerPuller()}},
         // binder_calls
@@ -211,12 +217,23 @@
         // ProcStats.
         {android::util::PROC_STATS,
          {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::PROC_STATS)}},
+        // ProcStatsPkgProc.
+        {android::util::PROC_STATS_PKG_PROC,
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::PROC_STATS_PKG_PROC)}},
         // Disk I/O stats per uid.
         {android::util::DISK_IO,
          {{2,3,4,5,6,7,8,9,10,11},
           {},
           3 * NS_PER_SEC,
           new StatsCompanionServicePuller(android::util::DISK_IO)}},
+        // PowerProfile constants for power model calculations.
+        {android::util::POWER_PROFILE,
+         {{}, {}, 1 * NS_PER_SEC, new StatsCompanionServicePuller(android::util::POWER_PROFILE)}},
+        // Process cpu stats. Min cool-down is 5 sec, inline with what AcitivityManagerService uses.
+        {android::util::PROCESS_CPU_TIME,
+            {{} /* additive fields */, {} /* non additive fields */,
+             5 * NS_PER_SEC /* min cool-down in seconds*/,
+             new StatsCompanionServicePuller(android::util::PROCESS_CPU_TIME)}},
 };
 
 StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/cmds/statsd/src/hash.cpp b/cmds/statsd/src/hash.cpp
index c501c9f..543a748 100644
--- a/cmds/statsd/src/hash.cpp
+++ b/cmds/statsd/src/hash.cpp
@@ -16,6 +16,10 @@
 
 #include "hash.h"
 
+#ifndef FALLTHROUGH_INTENDED
+#define FALLTHROUGH_INTENDED [[fallthrough]]
+#endif
+
 namespace android {
 namespace os {
 namespace statsd {
@@ -67,8 +71,10 @@
   switch (n) {
     case 3:
       h ^= ByteAs32(data[2]) << 16;
+      FALLTHROUGH_INTENDED;
     case 2:
       h ^= ByteAs32(data[1]) << 8;
+      FALLTHROUGH_INTENDED;
     case 1:
       h ^= ByteAs32(data[0]);
       h *= m;
@@ -104,16 +110,22 @@
   switch (n) {
     case 7:
       h ^= ByteAs64(data[6]) << 48;
+      FALLTHROUGH_INTENDED;
     case 6:
       h ^= ByteAs64(data[5]) << 40;
+      FALLTHROUGH_INTENDED;
     case 5:
       h ^= ByteAs64(data[4]) << 32;
+      FALLTHROUGH_INTENDED;
     case 4:
       h ^= ByteAs64(data[3]) << 24;
+      FALLTHROUGH_INTENDED;
     case 3:
       h ^= ByteAs64(data[2]) << 16;
+      FALLTHROUGH_INTENDED;
     case 2:
       h ^= ByteAs64(data[1]) << 8;
+      FALLTHROUGH_INTENDED;
     case 1:
       h ^= ByteAs64(data[0]);
       h *= m;
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index a5dac08..6b8c12a 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -46,6 +46,27 @@
     sp<StatsService> service;
 };
 
+
+sp<StatsService> gStatsService = nullptr;
+
+void sigHandler(int sig) {
+    if (gStatsService != nullptr) {
+        gStatsService->Terminate();
+    }
+}
+
+void registerSigHandler()
+{
+    struct sigaction sa;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+    sa.sa_handler = sigHandler;
+    sigaction(SIGHUP, &sa, nullptr);
+    sigaction(SIGINT, &sa, nullptr);
+    sigaction(SIGQUIT, &sa, nullptr);
+    sigaction(SIGTERM, &sa, nullptr);
+}
+
 int main(int /*argc*/, char** /*argv*/) {
     // Set up the looper
     sp<Looper> looper(Looper::prepare(0 /* opts */));
@@ -60,23 +81,25 @@
     ::android::hardware::configureRpcThreadpool(1 /*threads*/, false /*willJoin*/);
 
     // Create the service
-    sp<StatsService> service = new StatsService(looper);
-    if (defaultServiceManager()->addService(String16("stats"), service) != 0) {
+    gStatsService = new StatsService(looper);
+    if (defaultServiceManager()->addService(String16("stats"), gStatsService) != 0) {
         ALOGE("Failed to add service as AIDL service");
         return -1;
     }
 
-    auto ret = service->registerAsService();
+    auto ret = gStatsService->registerAsService();
     if (ret != ::android::OK) {
         ALOGE("Failed to add service as HIDL service");
         return 1; // or handle error
     }
 
-    service->sayHiToStatsCompanion();
+    registerSigHandler();
 
-    service->Startup();
+    gStatsService->sayHiToStatsCompanion();
 
-    sp<StatsSocketListener> socketListener = new StatsSocketListener(service);
+    gStatsService->Startup();
+
+    sp<StatsSocketListener> socketListener = new StatsSocketListener(gStatsService);
 
         ALOGI("using statsd socket");
         // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.cpp b/cmds/statsd/src/matchers/EventMatcherWizard.cpp
new file mode 100644
index 0000000..8418e98
--- /dev/null
+++ b/cmds/statsd/src/matchers/EventMatcherWizard.cpp
@@ -0,0 +1,38 @@
+/*
+ * 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 "EventMatcherWizard.h"
+#include <unordered_set>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+using std::map;
+using std::string;
+using std::vector;
+
+MatchingState EventMatcherWizard::matchLogEvent(const LogEvent& event, int matcher_index) {
+    if (matcher_index < 0 || matcher_index >= (int)mAllEventMatchers.size()) {
+        return MatchingState::kNotComputed;
+    }
+    vector<MatchingState> matcherCache(mAllEventMatchers.size(), MatchingState::kNotComputed);
+    mAllEventMatchers[matcher_index]->onLogEvent(event, mAllEventMatchers, matcherCache);
+    return matcherCache[matcher_index];
+}
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
\ No newline at end of file
diff --git a/cmds/statsd/src/matchers/EventMatcherWizard.h b/cmds/statsd/src/matchers/EventMatcherWizard.h
new file mode 100644
index 0000000..57ec2b3
--- /dev/null
+++ b/cmds/statsd/src/matchers/EventMatcherWizard.h
@@ -0,0 +1,41 @@
+/*
+ * 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 "LogMatchingTracker.h"
+
+namespace android {
+namespace os {
+namespace statsd {
+
+class EventMatcherWizard : public virtual android::RefBase {
+public:
+    EventMatcherWizard(){};  // for testing
+    EventMatcherWizard(const std::vector<sp<LogMatchingTracker>>& eventTrackers)
+        : mAllEventMatchers(eventTrackers){};
+
+    virtual ~EventMatcherWizard(){};
+
+    MatchingState matchLogEvent(const LogEvent& event, int matcher_index);
+
+private:
+    std::vector<sp<LogMatchingTracker>> mAllEventMatchers;
+};
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 02b9773..f5a16e9 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -69,11 +69,16 @@
 
 GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& metric,
                                          const int conditionIndex,
-                                         const sp<ConditionWizard>& wizard, const int pullTagId,
+                                         const sp<ConditionWizard>& wizard,
+                                         const int whatMatcherIndex,
+                                         const sp<EventMatcherWizard>& matcherWizard,
+                                         const int pullTagId,
                                          const int triggerAtomId, const int atomId,
                                          const int64_t timeBaseNs, const int64_t startTimeNs,
                                          const sp<StatsPullerManager>& pullerManager)
     : MetricProducer(metric.id(), key, timeBaseNs, conditionIndex, wizard),
+      mWhatMatcherIndex(whatMatcherIndex),
+      mEventMatcherWizard(matcherWizard),
       mPullerManager(pullerManager),
       mPullTagId(pullTagId),
       mTriggerAtomId(triggerAtomId),
@@ -136,7 +141,7 @@
     // Adjust start for partial bucket
     mCurrentBucketStartTimeNs = startTimeNs;
     if (mIsPulled) {
-        pullLocked(startTimeNs);
+        pullAndMatchEventsLocked(startTimeNs);
     }
 
     VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d",
@@ -302,7 +307,7 @@
     mPastBuckets.clear();
 }
 
-void GaugeMetricProducer::pullLocked(const int64_t timestampNs) {
+void GaugeMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
     bool triggerPuller = false;
     switch(mSamplingType) {
         // When the metric wants to do random sampling and there is already one gauge atom for the
@@ -331,7 +336,10 @@
         return;
     }
     for (const auto& data : allData) {
-        onMatchedLogEventLocked(0, *data);
+        if (mEventMatcherWizard->matchLogEvent(
+                *data, mWhatMatcherIndex) == MatchingState::kMatched) {
+            onMatchedLogEventLocked(mWhatMatcherIndex, *data);
+        }
     }
 }
 
@@ -341,7 +349,7 @@
     flushIfNeededLocked(eventTimeNs);
     mCondition = conditionMet;
     if (mIsPulled) {
-        pullLocked(eventTimeNs);
+        pullAndMatchEventsLocked(eventTimeNs);
     }  // else: Push mode. No need to proactively pull the gauge data.
 }
 
@@ -354,7 +362,7 @@
     // pull for every dimension.
     mCondition = overallCondition;
     if (mIsPulled) {
-        pullLocked(eventTimeNs);
+        pullAndMatchEventsLocked(eventTimeNs);
     }  // else: Push mode. No need to proactively pull the gauge data.
 }
 
@@ -387,7 +395,10 @@
         return;
     }
     for (const auto& data : allData) {
-        onMatchedLogEventLocked(0, *data);
+        if (mEventMatcherWizard->matchLogEvent(
+                *data, mWhatMatcherIndex) == MatchingState::kMatched) {
+            onMatchedLogEventLocked(mWhatMatcherIndex, *data);
+        }
     }
 }
 
@@ -426,7 +437,7 @@
     flushIfNeededLocked(eventTimeNs);
 
     if (mTriggerAtomId == event.GetTagId()) {
-        pullLocked(eventTimeNs);
+        pullAndMatchEventsLocked(eventTimeNs);
         return;
     }
 
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 6379389..99827bb 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -24,6 +24,7 @@
 #include "../external/PullDataReceiver.h"
 #include "../external/StatsPullerManager.h"
 #include "../matchers/matcher_util.h"
+#include "../matchers/EventMatcherWizard.h"
 #include "MetricProducer.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 #include "../stats_util.h"
@@ -56,7 +57,9 @@
 class GaugeMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
 public:
     GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric,
-                        const int conditionIndex, const sp<ConditionWizard>& wizard,
+                        const int conditionIndex, const sp<ConditionWizard>& conditionWizard,
+                        const int whatMatcherIndex,
+                        const sp<EventMatcherWizard>& matcherWizard,
                         const int pullTagId, const int triggerAtomId, const int atomId,
                         const int64_t timeBaseNs, const int64_t startTimeNs,
                         const sp<StatsPullerManager>& pullerManager);
@@ -78,7 +81,7 @@
         flushCurrentBucketLocked(eventTimeNs);
         mCurrentBucketStartTimeNs = eventTimeNs;
         if (mIsPulled) {
-            pullLocked(eventTimeNs);
+            pullAndMatchEventsLocked(eventTimeNs);
         }
     };
 
@@ -113,7 +116,11 @@
 
     void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
 
-    void pullLocked(const int64_t timestampNs);
+    void pullAndMatchEventsLocked(const int64_t timestampNs);
+
+    const int mWhatMatcherIndex;
+
+    sp<EventMatcherWizard> mEventMatcherWizard;
 
     sp<StatsPullerManager> mPullerManager;
     // tagId for pulled data. -1 if this is not pulled
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index df08181..f87849e 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -64,8 +64,54 @@
         onMatchedLogEventInternalLocked(
                 matcherIndex, metricKey, conditionKey, condition, event);
     }
+}
 
- }
+bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) {
+    bool isActive = mEventActivationMap.empty();
+    for (auto& it : mEventActivationMap) {
+        if (it.second.state == ActivationState::kActive &&
+            elapsedTimestampNs > it.second.ttl_ns + it.second.activation_ns) {
+            it.second.state = ActivationState::kNotActive;
+        }
+        if (it.second.state == ActivationState::kActive) {
+            isActive = true;
+        }
+    }
+    return isActive;
+}
+
+void MetricProducer::flushIfExpire(int64_t elapsedTimestampNs) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    if (!mIsActive) {
+        return;
+    }
+    mIsActive = evaluateActiveStateLocked(elapsedTimestampNs);
+    if (!mIsActive) {
+        flushLocked(elapsedTimestampNs);
+    }
+}
+
+void MetricProducer::addActivation(int activationTrackerIndex, int64_t ttl_seconds) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    // When a metric producer does not depend on any activation, its mIsActive is true.
+    // Therefor, if this is the 1st activation, mIsActive will turn to false. Otherwise it does not
+    // change.
+    if  (mEventActivationMap.empty()) {
+        mIsActive = false;
+    }
+    mEventActivationMap[activationTrackerIndex].ttl_ns = ttl_seconds * NS_PER_SEC;
+}
+
+void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs) {
+    auto it = mEventActivationMap.find(activationTrackerIndex);
+    if (it == mEventActivationMap.end()) {
+        return;
+    }
+    it->second.activation_ns = elapsedTimestampNs;
+    it->second.state = ActivationState::kActive;
+    mIsActive = true;
+}
+
 
 }  // namespace statsd
 }  // namespace os
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 6fe4bfb..b21fd50 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -34,6 +34,17 @@
 namespace os {
 namespace statsd {
 
+// If the metric has no activation requirement, it will be active once the metric producer is
+// created.
+// If the metric needs to be activated by atoms, the metric producer will start
+// with kNotActive state, turn to kActive when the activation event arrives, become kNotActive
+// when it reaches the duration limit (timebomb). If the activation event arrives again before
+// or after it expires, the event producer will be re-activated and ttl will be reset.
+enum ActivationState {
+    kNotActive = 0,
+    kActive = 1,
+};
+
 // A MetricProducer is responsible for compute one single metrics, creating stats log report, and
 // writing the report to dropbox. MetricProducers should respond to package changes as required in
 // PackageInfoListener, but if none of the metrics are slicing by package name, then the update can
@@ -54,7 +65,8 @@
           mContainANYPositionInDimensionsInWhat(false),
           mSliceByPositionALL(false),
           mSameConditionDimensionsInTracker(false),
-          mHasLinksToAllConditionDimensionsInTracker(false) {
+          mHasLinksToAllConditionDimensionsInTracker(false),
+          mIsActive(true) {
     }
 
     virtual ~MetricProducer(){};
@@ -93,17 +105,23 @@
     // 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);
-        onMatchedLogEventLocked(matcherIndex, event);
+        if (mIsActive) {
+            onMatchedLogEventLocked(matcherIndex, event);
+        }
     }
 
     void onConditionChanged(const bool condition, const int64_t eventTime) {
         std::lock_guard<std::mutex> lock(mMutex);
-        onConditionChangedLocked(condition, eventTime);
+        if (mIsActive) {
+            onConditionChangedLocked(condition, eventTime);
+        }
     }
 
     void onSlicedConditionMayChange(bool overallCondition, const int64_t eventTime) {
         std::lock_guard<std::mutex> lock(mMutex);
-        onSlicedConditionMayChangeLocked(overallCondition, eventTime);
+        if (mIsActive) {
+            onSlicedConditionMayChangeLocked(overallCondition, eventTime);
+        }
     }
 
     bool isConditionSliced() const {
@@ -177,6 +195,15 @@
         return mCurrentBucketNum;
     }
 
+    void activate(int activationTrackerIndex, int64_t elapsedTimestampNs) {
+        std::lock_guard<std::mutex> lock(mMutex);
+        activateLocked(activationTrackerIndex, elapsedTimestampNs);
+    }
+
+    void addActivation(int activationTrackerIndex, int64_t ttl_seconds);
+
+    void flushIfExpire(int64_t elapsedTimestampNs);
+
 protected:
     virtual void onConditionChangedLocked(const bool condition, const int64_t eventTime) = 0;
     virtual void onSlicedConditionMayChangeLocked(bool overallCondition,
@@ -189,6 +216,10 @@
     virtual size_t byteSizeLocked() const = 0;
     virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
 
+    bool evaluateActiveStateLocked(int64_t elapsedTimestampNs);
+
+    void activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs);
+
     /**
      * Flushes the current bucket if the eventTime is after the current bucket's end time. This will
        also flush the current partial bucket in memory.
@@ -198,9 +229,9 @@
     /**
      * Flushes all the data including the current partial bucket.
      */
-    virtual void flushLocked(const int64_t& eventTime) {
-        flushIfNeededLocked(eventTime);
-        flushCurrentBucketLocked(eventTime);
+    virtual void flushLocked(const int64_t& eventTimeNs) {
+        flushIfNeededLocked(eventTimeNs);
+        flushCurrentBucketLocked(eventTimeNs);
     };
 
     /**
@@ -295,6 +326,21 @@
     virtual void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event);
 
     mutable std::mutex mMutex;
+
+    struct Activation {
+        Activation() : ttl_ns(0), activation_ns(0), state(ActivationState::kNotActive)  {}
+
+        int64_t ttl_ns;
+        int64_t activation_ns;
+        ActivationState state;
+    };
+    // When the metric producer has multiple activations, these activations are ORed to determine
+    // whether the metric producer is ready to generate metrics.
+    std::unordered_map<int, Activation> mEventActivationMap;
+
+    bool mIsActive;
+
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 0e5ef4d..f85ba1f 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -73,7 +73,8 @@
             key, config, *uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
             timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, mAllConditionTrackers,
             mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
-            mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap, mNoReportMetricIds);
+            mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
+            mActivationAtomTrackerToMetricMap, mMetricIndexesWithActivation, mNoReportMetricIds);
 
     mHashStringsInReport = config.hash_strings_in_metric_report();
 
@@ -298,7 +299,12 @@
     }
 
     int tagId = event.GetTagId();
-    int64_t eventTime = event.GetElapsedTimestampNs();
+    int64_t eventTimeNs = event.GetElapsedTimestampNs();
+
+    for (int metric : mMetricIndexesWithActivation) {
+        mAllMetricProducers[metric]->flushIfExpire(eventTimeNs);
+    }
+
     if (mTagIds.find(tagId) == mTagIds.end()) {
         // not interesting...
         return;
@@ -310,6 +316,14 @@
         matcher->onLogEvent(event, mAllAtomMatchers, matcherCache);
     }
 
+    for (const auto& it : mActivationAtomTrackerToMetricMap) {
+        if (matcherCache[it.first] == MatchingState::kMatched) {
+            for (int metricIndex : it.second) {
+                mAllMetricProducers[metricIndex]->activate(it.first, eventTimeNs);
+            }
+        }
+    }
+
     // A bitmap to see which ConditionTracker needs to be re-evaluated.
     vector<bool> conditionToBeEvaluated(mAllConditionTrackers.size(), false);
 
@@ -347,13 +361,13 @@
                 // Push the new condition to it directly.
                 if (!mAllMetricProducers[metricIndex]->isConditionSliced()) {
                     mAllMetricProducers[metricIndex]->onConditionChanged(conditionCache[i],
-                                                                         eventTime);
+                                                                         eventTimeNs);
                     // metric cares about sliced conditions, and it may have changed. Send
                     // notification, and the metric can query the sliced conditions that are
                     // interesting to it.
                 } else {
                     mAllMetricProducers[metricIndex]->onSlicedConditionMayChange(conditionCache[i],
-                                                                                 eventTime);
+                                                                                 eventTimeNs);
                 }
             }
         }
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index dfbb69f..649222ff 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -195,6 +195,11 @@
     // maps from ConditionTracker to MetricProducer
     std::unordered_map<int, std::vector<int>> mConditionToMetricMap;
 
+    // maps from life span triggering event to MetricProducers.
+    std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap;
+
+    std::vector<int> mMetricIndexesWithActivation;
+
     void initLogSourceWhiteList();
 
     // The metrics that don't need to be uploaded or even reported.
@@ -207,7 +212,7 @@
     FRIEND_TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent);
     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents);
     FRIEND_TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm);
-    FRIEND_TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents);
+    FRIEND_TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents);
     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm);
     FRIEND_TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCondition);
@@ -230,6 +235,7 @@
 
     FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
     FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
+    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 75d6df9..136ba07 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -25,6 +25,7 @@
 #include "../external/StatsPullerManager.h"
 #include "../matchers/CombinationLogMatchingTracker.h"
 #include "../matchers/SimpleLogMatchingTracker.h"
+#include "../matchers/EventMatcherWizard.h"
 #include "../metrics/CountMetricProducer.h"
 #include "../metrics/DurationMetricProducer.h"
 #include "../metrics/EventMetricProducer.h"
@@ -294,6 +295,7 @@
                  unordered_map<int, std::vector<int>>& trackerToMetricMap,
                  unordered_map<int64_t, int>& metricMap, std::set<int64_t>& noReportMetricIds) {
     sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
+    sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchers);
     const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
                                 config.event_metric_size() + config.value_metric_size();
     allMetricProducers.reserve(allMetricsCount);
@@ -563,7 +565,8 @@
         }
 
         sp<MetricProducer> gaugeProducer = new GaugeMetricProducer(
-                key, metric, conditionIndex, wizard, pullTagId, triggerAtomId, atomTagId,
+                key, metric, conditionIndex, wizard,
+                trackerIndex, matcherWizard, pullTagId, triggerAtomId, atomTagId,
                 timeBaseTimeNs, currentTimeNs, pullerManager);
         allMetricProducers.push_back(gaugeProducer);
     }
@@ -682,6 +685,44 @@
     return true;
 }
 
+bool initMetricActivations(const ConfigKey& key, const StatsdConfig& config,
+                           const int64_t currentTimeNs,
+                           const unordered_map<int64_t, int> &logEventTrackerMap,
+                           const unordered_map<int64_t, int> &metricProducerMap,
+                           vector<sp<MetricProducer>>& allMetricProducers,
+                           unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
+                           vector<int>& metricsWithActivation) {
+    for (int i = 0; i < config.metric_activation_size(); ++i) {
+        const MetricActivation& metric_activation = config.metric_activation(i);
+        auto itr = metricProducerMap.find(metric_activation.metric_id());
+        if (itr == metricProducerMap.end()) {
+            ALOGE("Metric id not found in metric activation: %lld",
+                (long long)metric_activation.metric_id());
+            return false;
+        }
+        const int metricTrackerIndex = itr->second;
+        if (metricTrackerIndex < 0 || metricTrackerIndex >= (int)allMetricProducers.size()) {
+            ALOGE("Invalid metric tracker index.");
+            return false;
+        }
+        metricsWithActivation.push_back(metricTrackerIndex);
+        for (int j = 0; j < metric_activation.event_activation_size(); ++j) {
+            const EventActivation& activation = metric_activation.event_activation(j);
+            auto logTrackerIt = logEventTrackerMap.find(activation.atom_matcher_id());
+            if (logTrackerIt == logEventTrackerMap.end()) {
+                ALOGE("Atom matcher not found for event activation.");
+                return false;
+            }
+            const int atomMatcherIndex = logTrackerIt->second;
+            activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(
+                metricTrackerIndex);
+            allMetricProducers[metricTrackerIndex]->addActivation(
+                atomMatcherIndex, activation.ttl_seconds());
+        }
+    }
+    return true;
+}
+
 bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
                       const sp<StatsPullerManager>& pullerManager,
                       const sp<AlarmMonitor>& anomalyAlarmMonitor,
@@ -695,6 +736,8 @@
                       unordered_map<int, std::vector<int>>& conditionToMetricMap,
                       unordered_map<int, std::vector<int>>& trackerToMetricMap,
                       unordered_map<int, std::vector<int>>& trackerToConditionMap,
+                      unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
+                      vector<int>& metricsWithActivation,
                       std::set<int64_t>& noReportMetricIds) {
     unordered_map<int64_t, int> logTrackerMap;
     unordered_map<int64_t, int> conditionTrackerMap;
@@ -729,6 +772,11 @@
         ALOGE("initAlarms failed");
         return false;
     }
+    if (!initMetricActivations(key, config, currentTimeNs, logTrackerMap, metricProducerMap,
+            allMetricProducers, activationAtomTrackerToMetricMap, metricsWithActivation)) {
+        ALOGE("initMetricActivations failed");
+        return false;
+    }
 
     return true;
 }
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h
index c660149..9ffceda 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.h
+++ b/cmds/statsd/src/metrics/metrics_manager_util.h
@@ -108,6 +108,8 @@
                       std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
                       std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
                       std::unordered_map<int, std::vector<int>>& trackerToConditionMap,
+                      unordered_map<int, std::vector<int>>& lifeSpanEventTrackerToMetricMap,
+                      vector<int>& metricsWithLifeSpan,
                       std::set<int64_t>& noReportMetricIds);
 
 bool isStateTracker(const SimplePredicate& simplePredicate, std::vector<Matcher>* primaryKeys);
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index 4325f0f..37a0067 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -489,6 +489,10 @@
                                                              {"AID_RESERVED_DISK", 1065},
                                                              {"AID_STATSD", 1066},
                                                              {"AID_INCIDENTD", 1067},
+                                                             {"AID_SECURE_ELEMENT", 1068},
+                                                             {"AID_LMKD", 1069},
+                                                             {"AID_LLKD", 1070},
+                                                             {"AID_IORAPD", 1071},
                                                              {"AID_SHELL", 2000},
                                                              {"AID_CACHE", 2001},
                                                              {"AID_DIAG", 2002}};
diff --git a/cmds/statsd/src/shell/ShellSubscriber.cpp b/cmds/statsd/src/shell/ShellSubscriber.cpp
index 1306a46..dffff7a 100644
--- a/cmds/statsd/src/shell/ShellSubscriber.cpp
+++ b/cmds/statsd/src/shell/ShellSubscriber.cpp
@@ -18,9 +18,9 @@
 
 #include "ShellSubscriber.h"
 
-#include "matchers/matcher_util.h"
-
 #include <android-base/file.h>
+#include "matchers/matcher_util.h"
+#include "stats_log_util.h"
 
 using android::util::ProtoOutputStream;
 
@@ -28,6 +28,8 @@
 namespace os {
 namespace statsd {
 
+const static int FIELD_ID_ATOM = 1;
+
 void ShellSubscriber::startNewSubscription(int in, int out, sp<IResultReceiver> resultReceiver) {
     VLOG("start new shell subscription");
     {
@@ -42,25 +44,106 @@
         IInterface::asBinder(mResultReceiver)->linkToDeath(this);
     }
 
-    // Spawn another thread to read the config updates from the input file descriptor
-    std::thread reader([in, this] { readConfig(in); });
-    reader.detach();
+    // Note that the following is blocking, and it's intended as we cannot return until the shell
+    // cmd exits, otherwise all resources & FDs will be automatically closed.
 
+    // Read config forever until EOF is reached. Clients may send multiple configs -- each new
+    // config replace the previous one.
+    readConfig(in);
+
+    // Now we have read an EOF we now wait for the semaphore until the client exits.
+    VLOG("Now wait for client to exit");
     std::unique_lock<std::mutex> lk(mMutex);
-
     mShellDied.wait(lk, [this, resultReceiver] { return mResultReceiver != resultReceiver; });
-    if (reader.joinable()) {
-        reader.join();
-    }
 }
 
 void ShellSubscriber::updateConfig(const ShellSubscription& config) {
     std::lock_guard<std::mutex> lock(mMutex);
     mPushedMatchers.clear();
+    mPulledInfo.clear();
+
     for (const auto& pushed : config.pushed()) {
         mPushedMatchers.push_back(pushed);
         VLOG("adding matcher for atom %d", pushed.atom_id());
     }
+
+    int64_t token = getElapsedRealtimeNs();
+    mPullToken = token;
+
+    int64_t minInterval = -1;
+    for (const auto& pulled : config.pulled()) {
+        // All intervals need to be multiples of the min interval.
+        if (minInterval < 0 || pulled.freq_millis() < minInterval) {
+            minInterval = pulled.freq_millis();
+        }
+
+        mPulledInfo.emplace_back(pulled.matcher(), pulled.freq_millis());
+        VLOG("adding matcher for pulled atom %d", pulled.matcher().atom_id());
+    }
+
+    if (mPulledInfo.size() > 0 && minInterval > 0) {
+        // This thread is guaranteed to terminate after it detects the token is different or
+        // cleaned up.
+        std::thread puller([token, minInterval, this] { startPull(token, minInterval); });
+        puller.detach();
+    }
+}
+
+void ShellSubscriber::writeToOutputLocked(const vector<std::shared_ptr<LogEvent>>& data,
+                                          const SimpleAtomMatcher& matcher) {
+    if (mOutput == 0) return;
+    int count = 0;
+    mProto.clear();
+    for (const auto& event : data) {
+        VLOG("%s", event->ToString().c_str());
+        if (matchesSimple(*mUidMap, matcher, *event)) {
+            VLOG("matched");
+            count++;
+            uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
+                                              util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
+            event->ToProto(mProto);
+            mProto.end(atomToken);
+        }
+    }
+
+    if (count > 0) {
+        // First write the payload size.
+        size_t bufferSize = mProto.size();
+        write(mOutput, &bufferSize, sizeof(bufferSize));
+        VLOG("%d atoms, proto size: %zu", count, bufferSize);
+        // Then write the payload.
+        mProto.flush(mOutput);
+    }
+    mProto.clear();
+}
+
+void ShellSubscriber::startPull(int64_t token, int64_t intervalMillis) {
+    while (1) {
+        int64_t nowMillis = getElapsedRealtimeMillis();
+        {
+            std::lock_guard<std::mutex> lock(mMutex);
+            if (mPulledInfo.size() == 0 || mPullToken != token) {
+                VLOG("Pulling thread %lld done!", (long long)token);
+                return;
+            }
+            for (auto& pullInfo : mPulledInfo) {
+                if (pullInfo.mPrevPullElapsedRealtimeMs + pullInfo.mInterval < nowMillis) {
+                    VLOG("pull atom %d now", pullInfo.mPullerMatcher.atom_id());
+
+                    vector<std::shared_ptr<LogEvent>> data;
+                    mPullerMgr->Pull(pullInfo.mPullerMatcher.atom_id(), nowMillis * 1000000L,
+                                     &data);
+                    VLOG("pulled %zu atoms", data.size());
+                    if (data.size() > 0) {
+                        writeToOutputLocked(data, pullInfo.mPullerMatcher);
+                    }
+                    pullInfo.mPrevPullElapsedRealtimeMs = nowMillis;
+                }
+            }
+        }
+        VLOG("Pulling thread %lld sleep....", (long long)token);
+        std::this_thread::sleep_for(std::chrono::milliseconds(intervalMillis));
+    }
 }
 
 void ShellSubscriber::readConfig(int in) {
@@ -101,6 +184,8 @@
     mOutput = 0;
     mResultReceiver = nullptr;
     mPushedMatchers.clear();
+    mPulledInfo.clear();
+    mPullToken = 0;
     VLOG("done clean up");
 }
 
@@ -110,10 +195,13 @@
     if (mOutput <= 0) {
         return;
     }
-
     for (const auto& matcher : mPushedMatchers) {
         if (matchesSimple(*mUidMap, matcher, event)) {
+            VLOG("%s", event.ToString().c_str());
+            uint64_t atomToken = mProto.start(util::FIELD_TYPE_MESSAGE |
+                                              util::FIELD_COUNT_REPEATED | FIELD_ID_ATOM);
             event.ToProto(mProto);
+            mProto.end(atomToken);
             // First write the payload size.
             size_t bufferSize = mProto.size();
             write(mOutput, &bufferSize, sizeof(bufferSize));
diff --git a/cmds/statsd/src/shell/ShellSubscriber.h b/cmds/statsd/src/shell/ShellSubscriber.h
index 0ace35f..5401f31 100644
--- a/cmds/statsd/src/shell/ShellSubscriber.h
+++ b/cmds/statsd/src/shell/ShellSubscriber.h
@@ -24,6 +24,7 @@
 #include <mutex>
 #include <string>
 #include <thread>
+#include "external/StatsPullerManager.h"
 #include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
 #include "packages/UidMap.h"
@@ -51,14 +52,15 @@
  * with sizeof(size_t) bytes indicating the size of the proto message payload.
  *
  * The stream would be in the following format:
- * |size_t|atom1 proto|size_t|atom2 proto|....
+ * |size_t|shellData proto|size_t|shellData proto|....
  *
  * Only one shell subscriber allowed at a time, because each shell subscriber blocks one thread
  * until it exits.
  */
 class ShellSubscriber : public virtual IBinder::DeathRecipient {
 public:
-    ShellSubscriber(sp<UidMap> uidMap) : mUidMap(uidMap){};
+    ShellSubscriber(sp<UidMap> uidMap, sp<StatsPullerManager> pullerMgr)
+        : mUidMap(uidMap), mPullerMgr(pullerMgr){};
 
     /**
      * Start a new subscription.
@@ -70,15 +72,28 @@
     void onLogEvent(const LogEvent& event);
 
 private:
+    struct PullInfo {
+        PullInfo(const SimpleAtomMatcher& matcher, int64_t interval)
+            : mPullerMatcher(matcher), mInterval(interval), mPrevPullElapsedRealtimeMs(0) {
+        }
+        SimpleAtomMatcher mPullerMatcher;
+        int64_t mInterval;
+        int64_t mPrevPullElapsedRealtimeMs;
+    };
     void readConfig(int in);
 
     void updateConfig(const ShellSubscription& config);
 
+    void startPull(int64_t token, int64_t intervalMillis);
+
     void cleanUpLocked();
 
+    void writeToOutputLocked(const vector<std::shared_ptr<LogEvent>>& data,
+                             const SimpleAtomMatcher& matcher);
+
     sp<UidMap> mUidMap;
 
-    // bool mWritten = false;
+    sp<StatsPullerManager> mPullerMgr;
 
     android::util::ProtoOutputStream mProto;
 
@@ -93,6 +108,10 @@
     sp<IResultReceiver> mResultReceiver;
 
     std::vector<SimpleAtomMatcher> mPushedMatchers;
+
+    std::vector<PullInfo> mPulledInfo;
+
+    int64_t mPullToken = 0;  // A unique token to identify a puller thread.
 };
 
 }  // namespace statsd
diff --git a/cmds/statsd/src/shell/shell_config.proto b/cmds/statsd/src/shell/shell_config.proto
index 516693d..73cb49a 100644
--- a/cmds/statsd/src/shell/shell_config.proto
+++ b/cmds/statsd/src/shell/shell_config.proto
@@ -24,7 +24,7 @@
 import "frameworks/base/cmds/statsd/src/statsd_config.proto";
 
 message PulledAtomSubscription {
-    optional int32 atom_id = 1;
+    optional SimpleAtomMatcher matcher = 1;
 
     /* gap between two pulls in milliseconds */
     optional int32 freq_millis = 2;
diff --git a/proto/src/stats_enums.proto b/cmds/statsd/src/shell/shell_data.proto
similarity index 69%
copy from proto/src/stats_enums.proto
copy to cmds/statsd/src/shell/shell_data.proto
index 6c892cf..236bdbd 100644
--- a/proto/src/stats_enums.proto
+++ b/cmds/statsd/src/shell/shell_data.proto
@@ -17,10 +17,13 @@
 syntax = "proto2";
 
 package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "StatsEnums";
 
-enum EventType {
-  // Unknown.
-  TYPE_UNKNOWN = 0;
+option java_package = "com.android.os.statsd";
+option java_outer_classname = "ShellDataProto";
+
+import "frameworks/base/cmds/statsd/src/atoms.proto";
+
+// The output of shell subscription, including both pulled and pushed subscriptions.
+message ShellData {
+    repeated Atom atom = 1;
 }
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index ab0b23c..10ed7f3 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -271,6 +271,7 @@
       ADB_DUMP = 5;
       CONFIG_RESET = 6;
       STATSCOMPANION_DIED = 7;
+      TERMINATION_SIGNAL_RECEIVED = 8;
   }
   optional DumpReportReason dump_report_reason = 8;
 
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 805e583..2498d9f 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -25,15 +25,16 @@
 #include <utils/Log.h>
 #include <utils/SystemClock.h>
 
+using android::util::AtomsInfo;
 using android::util::FIELD_COUNT_REPEATED;
 using android::util::FIELD_TYPE_BOOL;
+using android::util::FIELD_TYPE_FIXED64;
 using android::util::FIELD_TYPE_FLOAT;
 using android::util::FIELD_TYPE_INT32;
 using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::FIELD_TYPE_FIXED64;
 using android::util::FIELD_TYPE_MESSAGE;
 using android::util::FIELD_TYPE_STRING;
+using android::util::FIELD_TYPE_UINT64;
 using android::util::ProtoOutputStream;
 
 namespace android {
@@ -294,8 +295,9 @@
 // }
 //
 //
-void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size_t* index,
-                                       int depth, int prefix, ProtoOutputStream* protoOutput) {
+void writeFieldValueTreeToStreamHelper(int tagId, const std::vector<FieldValue>& dims,
+                                       size_t* index, int depth, int prefix,
+                                       ProtoOutputStream* protoOutput) {
     size_t count = dims.size();
     while (*index < count) {
         const auto& dim = dims[*index];
@@ -319,9 +321,31 @@
                 case FLOAT:
                     protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
                     break;
-                case STRING:
-                    protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
+                case STRING: {
+                    bool isBytesField = false;
+                    // Bytes field is logged via string format in log_msg format. So here we check
+                    // if this string field is a byte field.
+                    std::map<int, std::vector<int>>::const_iterator itr;
+                    if (depth == 0 && (itr = AtomsInfo::kBytesFieldAtoms.find(tagId)) !=
+                                              AtomsInfo::kBytesFieldAtoms.end()) {
+                        const std::vector<int>& bytesFields = itr->second;
+                        for (int bytesField : bytesFields) {
+                            if (bytesField == fieldNum) {
+                                // This is a bytes field
+                                isBytesField = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (isBytesField) {
+                        protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
+                                           (const char*)dim.mValue.str_value.c_str(),
+                                           dim.mValue.str_value.length());
+                    } else {
+                        protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
+                    }
                     break;
+                }
                 case STORAGE:
                     protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
                                        (const char*)dim.mValue.storage_value.data(),
@@ -342,7 +366,7 @@
             }
             // Directly jump to the leaf value because the repeated position field is implied
             // by the position of the sub msg in the parent field.
-            writeFieldValueTreeToStreamHelper(dims, index, valueDepth,
+            writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth,
                                               dim.mField.getPrefix(valueDepth), protoOutput);
             if (msg_token != 0) {
                 protoOutput->end(msg_token);
@@ -359,7 +383,7 @@
     uint64_t atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId);
 
     size_t index = 0;
-    writeFieldValueTreeToStreamHelper(values, &index, 0, 0, protoOutput);
+    writeFieldValueTreeToStreamHelper(tagId, values, &index, 0, 0, protoOutput);
     protoOutput->end(atomToken);
 }
 
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index d19e247..d5f81a59 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -347,6 +347,17 @@
   optional float probability_of_informing = 7 [default = 1.1];
 }
 
+message EventActivation {
+  optional int64 atom_matcher_id = 1;
+  optional int64 ttl_seconds = 2;
+}
+
+message MetricActivation {
+  optional int64 metric_id = 1;
+
+  repeated EventActivation event_activation = 2;
+}
+
 message StatsdConfig {
   optional int64 id = 1;
 
@@ -384,6 +395,8 @@
 
   optional bool hash_strings_in_metric_report = 16 [default = true];
 
+  repeated MetricActivation metric_activation = 17;
+
   // Field number 1000 is reserved for later use.
   reserved 1000;
 }
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index d490701..ced65f2 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -327,7 +327,7 @@
     EXPECT_EQ(33, item5.mValue.int_value);
 
     const FieldValue& item6 = event1.getValues()[6];
-    EXPECT_EQ(0x2020382, item6.mField.getField());
+    EXPECT_EQ(0x2020383, item6.mField.getField());
     EXPECT_EQ(Type::LONG, item6.mValue.getType());
     EXPECT_EQ(678L, item6.mValue.long_value);
 
@@ -337,7 +337,7 @@
     EXPECT_EQ(44, item7.mValue.int_value);
 
     const FieldValue& item8 = event1.getValues()[8];
-    EXPECT_EQ(0x2020482, item8.mField.getField());
+    EXPECT_EQ(0x2020483, item8.mField.getField());
     EXPECT_EQ(Type::LONG, item8.mValue.getType());
     EXPECT_EQ(890L, item8.mValue.long_value);
 
@@ -347,7 +347,7 @@
     EXPECT_EQ(1, item9.mValue.int_value);
 
     const FieldValue& item10 = event1.getValues()[10];
-    EXPECT_EQ(0x2020583, item10.mField.getField());
+    EXPECT_EQ(0x2020584, item10.mField.getField());
     EXPECT_EQ(Type::STRING, item10.mValue.getType());
     EXPECT_EQ("test2", item10.mValue.str_value);
 
@@ -357,7 +357,7 @@
     EXPECT_EQ(2, item11.mValue.int_value);
 
     const FieldValue& item12 = event1.getValues()[12];
-    EXPECT_EQ(0x2020683, item12.mField.getField());
+    EXPECT_EQ(0x2020684, item12.mField.getField());
     EXPECT_EQ(Type::STRING, item12.mValue.getType());
     EXPECT_EQ("test1", item12.mValue.str_value);
 
@@ -367,7 +367,7 @@
     EXPECT_EQ(111, item13.mValue.int_value);
 
     const FieldValue& item14 = event1.getValues()[14];
-    EXPECT_EQ(0x2020784, item14.mField.getField());
+    EXPECT_EQ(0x2020785, item14.mField.getField());
     EXPECT_EQ(Type::FLOAT, item14.mValue.getType());
     EXPECT_EQ(2.2f, item14.mValue.float_value);
 
@@ -377,7 +377,7 @@
     EXPECT_EQ(222, item15.mValue.int_value);
 
     const FieldValue& item16 = event1.getValues()[16];
-    EXPECT_EQ(0x2028884, item16.mField.getField());
+    EXPECT_EQ(0x2028885, item16.mField.getField());
     EXPECT_EQ(Type::FLOAT, item16.mValue.getType());
     EXPECT_EQ(1.1f, item16.mValue.float_value);
 }
diff --git a/cmds/statsd/tests/MetricsManager_test.cpp b/cmds/statsd/tests/MetricsManager_test.cpp
index 8fbb58a..f8184d8 100644
--- a/cmds/statsd/tests/MetricsManager_test.cpp
+++ b/cmds/statsd/tests/MetricsManager_test.cpp
@@ -282,13 +282,17 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
+    vector<int> metricsWithLifeSpan;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                  periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                  allAtomMatchers, allConditionTrackers, allMetricProducers,
                                  allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-                                 trackerToMetricMap, trackerToConditionMap, noReportMetricIds));
+                                 trackerToMetricMap, trackerToConditionMap,
+                                 lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
+                                 noReportMetricIds));
     EXPECT_EQ(1u, allMetricProducers.size());
     EXPECT_EQ(1u, allAnomalyTrackers.size());
     EXPECT_EQ(1u, noReportMetricIds.size());
@@ -309,13 +313,17 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
+    vector<int> metricsWithLifeSpan;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-                                  trackerToMetricMap, trackerToConditionMap, noReportMetricIds));
+                                  trackerToMetricMap, trackerToConditionMap,
+                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
+                                  noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
@@ -333,13 +341,17 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
+    vector<int> metricsWithLifeSpan;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-                                  trackerToMetricMap, trackerToConditionMap, noReportMetricIds));
+                                  trackerToMetricMap, trackerToConditionMap,
+                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
+                                  noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestMissingMatchers) {
@@ -357,12 +369,16 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
+    vector<int> metricsWithLifeSpan;
     std::set<int64_t> noReportMetricIds;
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-                                  trackerToMetricMap, trackerToConditionMap, noReportMetricIds));
+                                  trackerToMetricMap, trackerToConditionMap,
+                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
+                                  noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestMissingPredicate) {
@@ -380,12 +396,16 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
+    vector<int> metricsWithLifeSpan;
     std::set<int64_t> noReportMetricIds;
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-                                  trackerToMetricMap, trackerToConditionMap, noReportMetricIds));
+                                  trackerToMetricMap, trackerToConditionMap,
+                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
+                                  noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, TestCirclePredicateDependency) {
@@ -403,13 +423,17 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
+    vector<int> metricsWithLifeSpan;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-                                  trackerToMetricMap, trackerToConditionMap, noReportMetricIds));
+                                  trackerToMetricMap, trackerToConditionMap,
+                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
+                                  noReportMetricIds));
 }
 
 TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
@@ -427,13 +451,17 @@
     unordered_map<int, std::vector<int>> conditionToMetricMap;
     unordered_map<int, std::vector<int>> trackerToMetricMap;
     unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> lifeSpanEventTrackerToMetricMap;
+    vector<int> metricsWithLifeSpan;
     std::set<int64_t> noReportMetricIds;
 
     EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor,
                                   periodicAlarmMonitor, timeBaseSec, timeBaseSec, allTagIds,
                                   allAtomMatchers, allConditionTrackers, allMetricProducers,
                                   allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-                                  trackerToMetricMap, trackerToConditionMap, noReportMetricIds));
+                                  trackerToMetricMap, trackerToConditionMap,
+                                  lifeSpanEventTrackerToMetricMap, metricsWithLifeSpan,
+                                  noReportMetricIds));
 }
 
 #else
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index 5b6f167..d7b9c11 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -152,7 +152,7 @@
     EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(1, data.bucket_info(1).atom_size());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 1,
@@ -161,7 +161,7 @@
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(1).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(1, data.bucket_info(2).atom_size());
     EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
@@ -170,7 +170,7 @@
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(2).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(1, data.bucket_info(3).atom_size());
     EXPECT_EQ(1, data.bucket_info(3).elapsed_timestamp_nanos_size());
@@ -179,7 +179,7 @@
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(3).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(3).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(3).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(3).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(3).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(1, data.bucket_info(4).atom_size());
     EXPECT_EQ(1, data.bucket_info(4).elapsed_timestamp_nanos_size());
@@ -188,7 +188,7 @@
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(4).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(4).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(4).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(4).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(4).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(1, data.bucket_info(5).atom_size());
     EXPECT_EQ(1, data.bucket_info(5).elapsed_timestamp_nanos_size());
@@ -197,11 +197,11 @@
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(5).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 9 * bucketSizeNs, data.bucket_info(5).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(5).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(5).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(5).atom(0).temperature().temperature_deci_celsius(), 0);
 }
 
-TEST(GaugeMetricE2eTest, TestAllConditionChangesSamplePulledEvents) {
-    auto config = CreateStatsdConfig(GaugeMetric::ALL_CONDITION_CHANGES);
+TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
+    auto config = CreateStatsdConfig(GaugeMetric::CONDITION_CHANGE_TO_TRUE);
     int64_t baseTimeNs = 10 * NS_PER_SEC;
     int64_t configAddedTimeNs = 10 * 60 * NS_PER_SEC + baseTimeNs;
     int64_t bucketSizeNs =
@@ -275,7 +275,7 @@
     EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(1, data.bucket_info(1).atom_size());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs + 100,
@@ -284,7 +284,7 @@
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 4 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(1).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(2, data.bucket_info(2).atom_size());
     EXPECT_EQ(2, data.bucket_info(2).elapsed_timestamp_nanos_size());
@@ -295,9 +295,9 @@
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 8 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(2).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_deci_celsius(), 0);
     EXPECT_TRUE(data.bucket_info(2).atom(1).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(1).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(2).atom(1).temperature().temperature_deci_celsius(), 0);
 }
 
 
@@ -378,7 +378,7 @@
     EXPECT_EQ(baseTimeNs + 2 * bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 3 * bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(0).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(0).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(1, data.bucket_info(1).atom_size());
     EXPECT_EQ(configAddedTimeNs + 3 * bucketSizeNs + 11,
@@ -387,7 +387,7 @@
     EXPECT_EQ(baseTimeNs + 5 * bucketSizeNs, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(1).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(1).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(1).atom(0).temperature().temperature_deci_celsius(), 0);
 
     EXPECT_EQ(1, data.bucket_info(2).atom_size());
     EXPECT_EQ(1, data.bucket_info(2).elapsed_timestamp_nanos_size());
@@ -396,7 +396,7 @@
     EXPECT_EQ(baseTimeNs + 6 * bucketSizeNs, data.bucket_info(2).start_bucket_elapsed_nanos());
     EXPECT_EQ(baseTimeNs + 7 * bucketSizeNs, data.bucket_info(2).end_bucket_elapsed_nanos());
     EXPECT_TRUE(data.bucket_info(2).atom(0).temperature().sensor_name().empty());
-    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_dc(), 0);
+    EXPECT_GT(data.bucket_info(2).atom(0).temperature().temperature_deci_celsius(), 0);
 
 }
 
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
new file mode 100644
index 0000000..0f13a4a
--- /dev/null
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -0,0 +1,242 @@
+// 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 <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__
+
+namespace {
+
+StatsdConfig CreateStatsdConfig() {
+    StatsdConfig config;
+    config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root.
+    auto crashMatcher = CreateProcessCrashAtomMatcher();
+    auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
+    auto saverModeMatcher = CreateBatterySaverModeStartAtomMatcher();
+
+    *config.add_atom_matcher() = saverModeMatcher;
+    *config.add_atom_matcher() = crashMatcher;
+    *config.add_atom_matcher() = screenOnMatcher;
+
+    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
+    auto event_activation2 = metric_activation1->add_event_activation();
+    event_activation2->set_atom_matcher_id(screenOnMatcher.id());
+    event_activation2->set_ttl_seconds(60 * 2);  // 2 minutes
+
+    return config;
+}
+
+}  // namespace
+
+TEST(MetricActivationE2eTest, TestCountMetric) {
+    auto config = CreateStatsdConfig();
+
+    int64_t bucketStartTimeNs = 10000000000;
+    int64_t bucketSizeNs =
+        TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000;
+
+    ConfigKey cfgKey;
+    auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
+    EXPECT_EQ(processor->mMetricsManagers.size(), 1u);
+    EXPECT_TRUE(processor->mMetricsManagers.begin()->second->isConfigValid());
+    sp<MetricProducer> metricProducer =
+        processor->mMetricsManagers.begin()->second->mAllMetricProducers[0];
+    auto& eventActivationMap = metricProducer->mEventActivationMap;
+
+    EXPECT_FALSE(metricProducer->mIsActive);
+    // Two activations: one is triggered by battery saver mode (tracker index 0), the other is
+    // triggered by screen on event (tracker index 2).
+    EXPECT_EQ(eventActivationMap.size(), 2u);
+    EXPECT_TRUE(eventActivationMap.find(0) != eventActivationMap.end());
+    EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
+    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0].activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2].activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+
+    std::unique_ptr<LogEvent> event;
+
+    event = CreateAppCrashEvent(111, bucketStartTimeNs + 5);
+    processor->OnLogEvent(event.get());
+    EXPECT_FALSE(metricProducer->mIsActive);
+
+    // Activated by battery save mode.
+    event = CreateBatterySaverOnEvent(bucketStartTimeNs + 10);
+    processor->OnLogEvent(event.get());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2].activation_ns, 0);
+    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+
+    // First processed event.
+    event = CreateAppCrashEvent(222, bucketStartTimeNs + 15);
+    processor->OnLogEvent(event.get());
+
+    // Activated by screen on event.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+                                          bucketStartTimeNs + 20);
+    processor->OnLogEvent(event.get());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2].activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+
+    // 2nd processed event.
+    // The activation by screen_on event expires, but the one by battery save mode is still active.
+    event = CreateAppCrashEvent(333, bucketStartTimeNs + NS_PER_SEC * 60 * 2 + 25);
+    processor->OnLogEvent(event.get());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2].activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+
+    // 3rd processed event.
+    event = CreateAppCrashEvent(444, bucketStartTimeNs + NS_PER_SEC * 60 * 5 + 25);
+    processor->OnLogEvent(event.get());
+
+    // All activations expired.
+    event = CreateAppCrashEvent(555, bucketStartTimeNs + NS_PER_SEC * 60 * 8);
+    processor->OnLogEvent(event.get());
+    EXPECT_FALSE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[2].activation_ns, bucketStartTimeNs + 20);
+    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+
+    // Re-activate.
+    event = CreateScreenStateChangedEvent(android::view::DISPLAY_STATE_ON,
+                                          bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    processor->OnLogEvent(event.get());
+    EXPECT_TRUE(metricProducer->mIsActive);
+    EXPECT_EQ(eventActivationMap[0].state, ActivationState::kNotActive);
+    EXPECT_EQ(eventActivationMap[0].activation_ns, bucketStartTimeNs + 10);
+    EXPECT_EQ(eventActivationMap[0].ttl_ns, 60 * 6 * NS_PER_SEC);
+    EXPECT_EQ(eventActivationMap[2].state, ActivationState::kActive);
+    EXPECT_EQ(eventActivationMap[2].activation_ns, bucketStartTimeNs + NS_PER_SEC * 60 * 10 + 10);
+    EXPECT_EQ(eventActivationMap[2].ttl_ns, 60 * 2 * NS_PER_SEC);
+
+    event = CreateAppCrashEvent(666, bucketStartTimeNs + NS_PER_SEC * 60 * 11 + 1);
+    processor->OnLogEvent(event.get());
+
+    ConfigMetricsReportList reports;
+    vector<uint8_t> buffer;
+    processor->onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, ADB_DUMP,
+                            &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(4, reports.reports(0).metrics(0).count_metrics().data_size());
+
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(
+            reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(4, countMetrics.data_size());
+
+    auto data = countMetrics.data(0);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(222, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(1);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(333, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(2);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(444, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    // Partial bucket as metric is deactivated.
+    EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + NS_PER_SEC * 60 * 8,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = countMetrics.data(3);
+    EXPECT_EQ(android::util::PROCESS_LIFE_CYCLE_STATE_CHANGED, data.dimensions_in_what().field());
+    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
+    EXPECT_EQ(1 /* uid field */,
+              data.dimensions_in_what().value_tuple().dimensions_value(0).field());
+    EXPECT_EQ(666, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
+    EXPECT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(bucketStartTimeNs + 2 * bucketSizeNs,
+              data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(bucketStartTimeNs + 3 * bucketSizeNs,
+              data.bucket_info(0).end_bucket_elapsed_nanos());
+
+}
+
+
+#else
+GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+
+}  // namespace statsd
+}  // namespace os
+}  // namespace android
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index bf58b9c..60bd4a7 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "src/matchers/SimpleLogMatchingTracker.h"
 #include "src/metrics/GaugeMetricProducer.h"
 #include "src/stats_log_util.h"
 #include "logd/LogEvent.h"
@@ -40,6 +41,8 @@
 const ConfigKey kConfigKey(0, 12345);
 const int tagId = 1;
 const int64_t metricId = 123;
+const int64_t atomMatcherId = 678;
+const int logEventMatcherIndex = 0;
 const int64_t bucketStartTimeNs = 10 * NS_PER_SEC;
 const int64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(ONE_MINUTE) * 1000000LL;
 const int64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
@@ -61,11 +64,19 @@
     gaugeFieldMatcher->add_child()->set_field(3);
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
     // statsd started long ago.
     // The metric starts in the middle of the bucket
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard,
                                       -1, -1, tagId, 5, 600 * NS_PER_SEC + NS_PER_SEC / 2,
                                       pullerManager);
 
@@ -86,6 +97,12 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
@@ -103,6 +120,7 @@
             }));
 
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard,
                                       tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
 
@@ -178,7 +196,15 @@
     alert.set_num_buckets(100);
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard,
                                       -1 /* -1 means no pulling */, -1, tagId, bucketStartTimeNs,
                                       bucketStartTimeNs, pullerManager);
 
@@ -246,6 +272,12 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
@@ -263,6 +295,7 @@
             }));
 
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard,
                                       tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
 
@@ -315,6 +348,12 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
     EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
@@ -330,7 +369,8 @@
                 return true;
             }));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, -1, tagId,
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
                                       bucketStartTimeNs, bucketStartTimeNs, pullerManager);
 
     gaugeProducer.onConditionChanged(true, bucketStartTimeNs + 8);
@@ -388,6 +428,12 @@
     dim->set_field(conditionTag);
     dim->add_child()->set_field(1);
 
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
     EXPECT_CALL(*wizard, query(_, _, _, _, _, _))
             .WillRepeatedly(
@@ -420,7 +466,8 @@
                 return true;
             }));
 
-    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, -1, tagId,
+    GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
                                       bucketStartTimeNs, bucketStartTimeNs, pullerManager);
 
     gaugeProducer.onSlicedConditionMayChange(true, bucketStartTimeNs + 8);
@@ -463,7 +510,15 @@
     auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
     gaugeFieldMatcher->set_field(tagId);
     gaugeFieldMatcher->add_child()->set_field(2);
+
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard,
                                       tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
 
@@ -542,6 +597,12 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
             .WillOnce(Invoke([](int tagId, int64_t timeNs,
@@ -574,6 +635,7 @@
 
     int triggerId = 5;
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard,
                                       tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
 
@@ -632,6 +694,12 @@
 
     sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
 
+    UidMap uidMap;
+    SimpleAtomMatcher atomMatcher;
+    atomMatcher.set_atom_id(tagId);
+    sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+        new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
     EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
             .WillOnce(Invoke([](int tagId, int64_t timeNs,
@@ -667,6 +735,7 @@
 
     int triggerId = 5;
     GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+                                      logEventMatcherIndex, eventMatcherWizard,
                                       tagId, triggerId, tagId, bucketStartTimeNs, bucketStartTimeNs,
                                       pullerManager);
 
diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
index b380b03..dd00561 100644
--- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
+++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp
@@ -17,6 +17,7 @@
 #include <unistd.h>
 #include "frameworks/base/cmds/statsd/src/atoms.pb.h"
 #include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h"
+#include "frameworks/base/cmds/statsd/src/shell/shell_data.pb.h"
 #include "src/shell/ShellSubscriber.h"
 #include "tests/metrics/metrics_test_helper.h"
 
@@ -26,7 +27,10 @@
 using namespace android::os::statsd;
 using android::sp;
 using std::vector;
+using testing::_;
+using testing::Invoke;
 using testing::NaggyMock;
+using testing::StrictMock;
 
 #ifdef __ANDROID__
 
@@ -51,7 +55,10 @@
     }
 };
 
-TEST(ShellSubscriberTest, testPushedSubscription) {
+void runShellTest(ShellSubscription config, sp<MockUidMap> uidMap,
+                  sp<MockStatsPullerManager> pullerManager,
+                  const vector<std::shared_ptr<LogEvent>>& pushedEvents,
+                  const ShellData& expectedData) {
     // set up 2 pipes for read/write config and data
     int fds_config[2];
     ASSERT_EQ(0, pipe(fds_config));
@@ -59,10 +66,6 @@
     int fds_data[2];
     ASSERT_EQ(0, pipe(fds_data));
 
-    // create a simple config to get screen events
-    ShellSubscription config;
-    config.add_pushed()->set_atom_id(29);
-
     size_t bufferSize = config.ByteSize();
 
     // write the config to pipe, first write size of the config
@@ -75,15 +78,9 @@
     write(fds_config[1], buffer.data(), bufferSize);
     close(fds_config[1]);
 
-    // create a shell subscriber.
-    sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
-    sp<ShellSubscriber> shellClient = new ShellSubscriber(uidMap);
+    sp<ShellSubscriber> shellClient = new ShellSubscriber(uidMap, pullerManager);
     sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
 
-    LogEvent event1(29, 1000);
-    event1.write(2);
-    event1.init();
-
     // mimic a binder thread that a shell subscriber runs on. it would block.
     std::thread reader([&resultReceiver, &fds_config, &fds_data, &shellClient] {
         shellClient->startNewSubscription(fds_config[0], fds_data[1], resultReceiver);
@@ -93,44 +90,127 @@
     // let the shell subscriber to receive the config from pipe.
     std::this_thread::sleep_for(100ms);
 
-    // send a log event that matches the config.
-    std::thread log_reader([&shellClient, &event1] { shellClient->onLogEvent(event1); });
-    log_reader.detach();
+    if (pushedEvents.size() > 0) {
+        // send a log event that matches the config.
+        std::thread log_reader([&shellClient, &pushedEvents] {
+            for (const auto& event : pushedEvents) {
+                shellClient->onLogEvent(*event);
+            }
+        });
 
-    if (log_reader.joinable()) {
-        log_reader.join();
+        log_reader.detach();
+
+        if (log_reader.joinable()) {
+            log_reader.join();
+        }
     }
 
     // wait for the data to be written.
     std::this_thread::sleep_for(100ms);
 
-    // this is the expected screen event atom.
-    Atom atom;
-    atom.mutable_screen_state_changed()->set_state(
-            ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
-
-    int atom_size = atom.ByteSize();
+    int expected_data_size = expectedData.ByteSize();
 
     // now read from the pipe. firstly read the atom size.
     size_t dataSize = 0;
     EXPECT_EQ((int)sizeof(dataSize), read(fds_data[0], &dataSize, sizeof(dataSize)));
-    EXPECT_EQ(atom_size, (int)dataSize);
+    EXPECT_EQ(expected_data_size, (int)dataSize);
 
     // then read that much data which is the atom in proto binary format
     vector<uint8_t> dataBuffer(dataSize);
     EXPECT_EQ((int)dataSize, read(fds_data[0], dataBuffer.data(), dataSize));
 
     // make sure the received bytes can be parsed to an atom
-    Atom receivedAtom;
+    ShellData receivedAtom;
     EXPECT_TRUE(receivedAtom.ParseFromArray(dataBuffer.data(), dataSize) != 0);
 
     // serialze the expected atom to bytes. and compare. to make sure they are the same.
-    vector<uint8_t> atomBuffer(atom_size);
-    atom.SerializeToArray(&atomBuffer[0], atom_size);
+    vector<uint8_t> atomBuffer(expected_data_size);
+    expectedData.SerializeToArray(&atomBuffer[0], expected_data_size);
     EXPECT_EQ(atomBuffer, dataBuffer);
     close(fds_data[0]);
 }
 
+TEST(ShellSubscriberTest, testPushedSubscription) {
+    sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    vector<std::shared_ptr<LogEvent>> pushedList;
+
+    std::shared_ptr<LogEvent> event1 =
+            std::make_shared<LogEvent>(29 /*screen_state_atom_id*/, 1000 /*timestamp*/);
+    event1->write(::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
+    event1->init();
+    pushedList.push_back(event1);
+
+    // create a simple config to get screen events
+    ShellSubscription config;
+    config.add_pushed()->set_atom_id(29);
+
+    // this is the expected screen event atom.
+    ShellData shellData;
+    shellData.add_atom()->mutable_screen_state_changed()->set_state(
+            ::android::view::DisplayStateEnum::DISPLAY_STATE_ON);
+
+    runShellTest(config, uidMap, pullerManager, pushedList, shellData);
+}
+
+namespace {
+
+int kUid1 = 1000;
+int kUid2 = 2000;
+
+int kCpuTime1 = 100;
+int kCpuTime2 = 200;
+
+ShellData getExpectedShellData() {
+    ShellData shellData;
+    auto* atom1 = shellData.add_atom()->mutable_cpu_active_time();
+    atom1->set_uid(kUid1);
+    atom1->set_time_millis(kCpuTime1);
+
+    auto* atom2 = shellData.add_atom()->mutable_cpu_active_time();
+    atom2->set_uid(kUid2);
+    atom2->set_time_millis(kCpuTime2);
+
+    return shellData;
+}
+
+ShellSubscription getPulledConfig() {
+    ShellSubscription config;
+    auto* pull_config = config.add_pulled();
+    pull_config->mutable_matcher()->set_atom_id(10016);
+    pull_config->set_freq_millis(2000);
+    return config;
+}
+
+}  // namespace
+
+TEST(ShellSubscriberTest, testPulledSubscription) {
+    sp<MockUidMap> uidMap = new NaggyMock<MockUidMap>();
+
+    sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+    EXPECT_CALL(*pullerManager, Pull(10016, _, _))
+            .WillRepeatedly(
+                    Invoke([](int tagId, int64_t timeNs, vector<std::shared_ptr<LogEvent>>* data) {
+                        data->clear();
+                        shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, timeNs);
+                        event->write(kUid1);
+                        event->write(kCpuTime1);
+                        event->init();
+                        data->push_back(event);
+                        // another event
+                        event = make_shared<LogEvent>(tagId, timeNs);
+                        event->write(kUid2);
+                        event->write(kCpuTime2);
+                        event->init();
+                        data->push_back(event);
+                        return true;
+                    }));
+
+    runShellTest(getPulledConfig(), uidMap, pullerManager, vector<std::shared_ptr<LogEvent>>(),
+                 getExpectedShellData());
+}
+
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java b/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java
index 2b7da6a..4f4dd01 100644
--- a/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java
+++ b/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java
@@ -319,7 +319,7 @@
         int[] uids = new int[]{mUids[id]};
         String[] tags = new String[]{"acquire"};
         StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags,
-                StatsLog.WAKELOCK_STATE_CHANGED__LEVEL__PARTIAL_WAKE_LOCK, name,
+                StatsLog.WAKELOCK_STATE_CHANGED__TYPE__PARTIAL_WAKE_LOCK, name,
                 StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE);
         StringBuilder sb = new StringBuilder();
         sb.append("StagsLog.write(10, ").append(mUids[id]).append(", ").append(0)
@@ -335,7 +335,7 @@
         int[] uids = new int[]{mUids[id]};
         String[] tags = new String[]{"release"};
         StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags,
-                StatsLog.WAKELOCK_STATE_CHANGED__LEVEL__PARTIAL_WAKE_LOCK, name,
+                StatsLog.WAKELOCK_STATE_CHANGED__TYPE__PARTIAL_WAKE_LOCK, name,
                 StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE);
         StringBuilder sb = new StringBuilder();
         sb.append("StagsLog.write(10, ").append(mUids[id]).append(", ").append(0)
diff --git a/cmds/statsd/tools/statsd-testdrive/Android.bp b/cmds/statsd/tools/statsd-testdrive/Android.bp
new file mode 100644
index 0000000..f566bc7
--- /dev/null
+++ b/cmds/statsd/tools/statsd-testdrive/Android.bp
@@ -0,0 +1,11 @@
+java_binary_host {
+    name: "statsd_testdrive",
+    manifest: "manifest.txt",
+    srcs: [
+        "src/**/*.java",
+    ],
+    static_libs: [
+        "platformprotos",
+        "guava",
+    ],
+}
diff --git a/cmds/statsd/tools/statsd-testdrive/manifest.txt b/cmds/statsd/tools/statsd-testdrive/manifest.txt
new file mode 100644
index 0000000..0266d11
--- /dev/null
+++ b/cmds/statsd/tools/statsd-testdrive/manifest.txt
@@ -0,0 +1 @@
+Main-class: com.android.statsd.testdrive.TestDrive
diff --git a/cmds/statsd/tools/statsd-testdrive/src/com/android/statsd/testdrive/TestDrive.java b/cmds/statsd/tools/statsd-testdrive/src/com/android/statsd/testdrive/TestDrive.java
new file mode 100644
index 0000000..cc4e386
--- /dev/null
+++ b/cmds/statsd/tools/statsd-testdrive/src/com/android/statsd/testdrive/TestDrive.java
@@ -0,0 +1,302 @@
+/*
+ * 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.statsd.testdrive;
+
+import com.android.internal.os.StatsdConfigProto.AtomMatcher;
+import com.android.internal.os.StatsdConfigProto.SimpleAtomMatcher;
+import com.android.internal.os.StatsdConfigProto.StatsdConfig;
+import com.android.os.AtomsProto.Atom;
+import com.android.os.StatsLog.ConfigMetricsReport;
+import com.android.os.StatsLog.ConfigMetricsReportList;
+
+import com.google.common.io.Files;
+import com.google.protobuf.TextFormat;
+import com.google.protobuf.TextFormat.ParseException;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+public class TestDrive {
+
+    public static final int PULL_ATOM_START = 10000;
+    public static final long ATOM_MATCHER_ID = 1234567;
+
+    public static final String UPDATE_CONFIG_CMD = "cmd stats config update";
+    public static final String DUMP_REPORT_CMD = "cmd stats dump-report";
+    public static final String REMOVE_CONFIG_CMD = "cmd stats config remove";
+    public static final String CONFIG_UID = "2000"; // shell uid
+    public static final long CONFIG_ID = 54321;
+
+    private static boolean mIsPushedAtom = false;
+
+    private static final Logger logger = Logger.getLogger(TestDrive.class.getName());
+
+    public static void main(String[] args) {
+        if (args.length != 1) {
+            logger.log(Level.SEVERE, "Usage: ./test_drive <atomId>");
+            return;
+        }
+        int atomId;
+        try {
+            atomId = Integer.valueOf(args[0]);
+        } catch (NumberFormatException e) {
+            logger.log(Level.SEVERE, "Bad atom id provided: " + args[0]);
+            return;
+        }
+        if (Atom.getDescriptor().findFieldByNumber(atomId) == null) {
+            logger.log(Level.SEVERE, "No such atom found: " + args[0]);
+            return;
+        }
+        mIsPushedAtom = atomId < PULL_ATOM_START;
+
+        TestDrive testDrive = new TestDrive();
+        TestDriveFormatter formatter = new TestDriveFormatter();
+        ConsoleHandler handler = new ConsoleHandler();
+        handler.setFormatter(formatter);
+        logger.addHandler(handler);
+        logger.setUseParentHandlers(false);
+
+        try {
+            StatsdConfig config = testDrive.createConfig(atomId);
+            if (config == null) {
+                logger.log(Level.SEVERE, "Failed to create valid config.");
+                return;
+            }
+            testDrive.pushConfig(config);
+            logger.info("Pushed the following config to statsd:");
+            logger.info(config.toString());
+            if (mIsPushedAtom) {
+                logger.info(
+                        "Now please play with the device to trigger the event. All events should "
+                                + "be dumped after 1 min ...");
+                Thread.sleep(60_000);
+            } else {
+                // wait for 2 min
+                logger.info("Now wait for 2 minutes ...");
+                Thread.sleep(120_000);
+            }
+            testDrive.dumpMetrics();
+        } catch (Exception e) {
+            logger.log(Level.SEVERE, "Failed to test drive: " + e.getMessage());
+        } finally {
+            testDrive.removeConfig();
+        }
+    }
+
+    private void pushConfig(StatsdConfig config) throws IOException, InterruptedException {
+        File configFile = File.createTempFile("statsdconfig", ".config");
+        configFile.deleteOnExit();
+        Files.write(config.toByteArray(), configFile);
+        String remotePath = "/data/local/tmp/" + configFile.getName();
+        runCommand(null, "adb", "push", configFile.getAbsolutePath(), remotePath);
+        runCommand(
+                null, "adb", "shell", "cat", remotePath, "|", UPDATE_CONFIG_CMD,
+                String.valueOf(CONFIG_ID));
+    }
+
+    private void removeConfig() {
+        try {
+            runCommand(null, "adb", "shell", REMOVE_CONFIG_CMD, String.valueOf(CONFIG_ID));
+        } catch (Exception e) {
+            logger.log(Level.SEVERE, "Failed to remove config: " + e.getMessage());
+        }
+    }
+
+    // Runs a shell command. Output should go to outputFile. Returns error string.
+    private String runCommand(File outputFile, String... commands)
+            throws IOException, InterruptedException {
+        // Run macro on target
+        ProcessBuilder pb = new ProcessBuilder(commands);
+        // pb.redirectErrorStream(true);
+
+        if (outputFile != null && outputFile.exists() && outputFile.canWrite()) {
+            pb.redirectOutput(outputFile);
+        }
+        Process process = pb.start();
+
+        // capture any errors
+        StringBuilder out = new StringBuilder();
+        // Read output
+        BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+        String line = null, previous = null;
+        while ((line = br.readLine()) != null) {
+            if (!line.equals(previous)) {
+                previous = line;
+                out.append(line).append('\n');
+                logger.fine(line);
+            }
+        }
+
+        // Check result
+        if (process.waitFor() == 0) {
+            logger.fine("Success!");
+        } else {
+            // Abnormal termination: Log command parameters and output and throw ExecutionException
+            logger.log(Level.SEVERE, out.toString());
+        }
+        return out.toString();
+    }
+
+    private StatsdConfig createConfig(int atomId) {
+        try {
+            if (mIsPushedAtom) {
+                return createSimpleEventMetricConfig(atomId);
+            } else {
+                return createSimpleGaugeMetricConfig(atomId);
+            }
+        } catch (ParseException e) {
+            logger.log(
+                    Level.SEVERE,
+                    "Failed to parse the config! line: "
+                            + e.getLine()
+                            + " col: "
+                            + e.getColumn()
+                            + " "
+                            + e.getMessage());
+        }
+        return null;
+    }
+
+    private StatsdConfig createSimpleEventMetricConfig(int atomId) throws ParseException {
+        StatsdConfig.Builder baseBuilder = getSimpleEventMetricBaseConfig();
+        baseBuilder.addAtomMatcher(createAtomMatcher(atomId));
+        return baseBuilder.build();
+    }
+
+    private StatsdConfig createSimpleGaugeMetricConfig(int atomId) throws ParseException {
+        StatsdConfig.Builder baseBuilder = getSimpleGaugeMetricBaseConfig();
+        baseBuilder.addAtomMatcher(createAtomMatcher(atomId));
+        return baseBuilder.build();
+    }
+
+    private AtomMatcher createAtomMatcher(int atomId) {
+        AtomMatcher.Builder atomMatcherBuilder = AtomMatcher.newBuilder();
+        atomMatcherBuilder
+                .setId(ATOM_MATCHER_ID)
+                .setSimpleAtomMatcher(SimpleAtomMatcher.newBuilder().setAtomId(atomId));
+        return atomMatcherBuilder.build();
+    }
+
+    private StatsdConfig.Builder getSimpleEventMetricBaseConfig() throws ParseException {
+        StatsdConfig.Builder builder = StatsdConfig.newBuilder();
+        TextFormat.merge(EVENT_BASE_CONFIG_SRTR, builder);
+        return builder;
+    }
+
+    private StatsdConfig.Builder getSimpleGaugeMetricBaseConfig() throws ParseException {
+        StatsdConfig.Builder builder = StatsdConfig.newBuilder();
+        TextFormat.merge(GAUGE_BASE_CONFIG_STR, builder);
+        return builder;
+    }
+
+    private ConfigMetricsReportList getReportList() throws Exception {
+        try {
+            File outputFile = File.createTempFile("statsdret", ".bin");
+            outputFile.deleteOnExit();
+            runCommand(
+                    outputFile,
+                    "adb",
+                    "shell",
+                    DUMP_REPORT_CMD,
+                    String.valueOf(CONFIG_ID),
+                    "--include_current_bucket",
+                    "--proto");
+            ConfigMetricsReportList reportList =
+                    ConfigMetricsReportList.parseFrom(new FileInputStream(outputFile));
+            return reportList;
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+            logger.log(
+                    Level.SEVERE,
+                    "Failed to fetch and parse the statsd output report. "
+                            + "Perhaps there is not a valid statsd config for the requested "
+                            + "uid="
+                            + CONFIG_UID
+                            + ", id="
+                            + CONFIG_ID
+                            + ".");
+            throw (e);
+        }
+    }
+
+    private void dumpMetrics() throws Exception {
+        ConfigMetricsReportList reportList = getReportList();
+        // We may get multiple reports. Take the last one.
+        ConfigMetricsReport report = reportList.getReports(reportList.getReportsCount() - 1);
+        // Really should be only one metric.
+        if (report.getMetricsCount() != 1) {
+            logger.log(Level.SEVERE,
+                    "Only one report metric expected, got " + report.getMetricsCount());
+            return;
+        }
+
+        logger.info("Got following metric data dump:");
+        logger.info(report.getMetrics(0).toString());
+    }
+
+    private static final String EVENT_BASE_CONFIG_SRTR =
+            "id: 12345\n"
+                    + "event_metric {\n"
+                    + "  id: 1111\n"
+                    + "  what: 1234567\n"
+                    + "}\n"
+                    + "allowed_log_source: \"AID_GRAPHICS\"\n"
+                    + "allowed_log_source: \"AID_INCIDENTD\"\n"
+                    + "allowed_log_source: \"AID_STATSD\"\n"
+                    + "allowed_log_source: \"AID_RADIO\"\n"
+                    + "allowed_log_source: \"com.android.systemui\"\n"
+                    + "allowed_log_source: \"com.android.vending\"\n"
+                    + "allowed_log_source: \"AID_SYSTEM\"\n"
+                    + "allowed_log_source: \"AID_ROOT\"\n"
+                    + "allowed_log_source: \"AID_BLUETOOTH\"\n"
+                    + "\n"
+                    + "hash_strings_in_metric_report: false";
+
+    private static final String GAUGE_BASE_CONFIG_STR =
+            "id: 56789\n"
+                    + "gauge_metric {\n"
+                    + "  id: 2222\n"
+                    + "  what: 1234567\n"
+                    + "  gauge_fields_filter {\n"
+                    + "    include_all: true\n"
+                    + "  }\n"
+                    + "  bucket: ONE_MINUTE\n"
+                    + "}\n"
+                    + "allowed_log_source: \"AID_GRAPHICS\"\n"
+                    + "allowed_log_source: \"AID_INCIDENTD\"\n"
+                    + "allowed_log_source: \"AID_STATSD\"\n"
+                    + "allowed_log_source: \"AID_RADIO\"\n"
+                    + "allowed_log_source: \"com.android.systemui\"\n"
+                    + "allowed_log_source: \"com.android.vending\"\n"
+                    + "allowed_log_source: \"AID_SYSTEM\"\n"
+                    + "allowed_log_source: \"AID_ROOT\"\n"
+                    + "allowed_log_source: \"AID_BLUETOOTH\"\n"
+                    + "\n"
+                    + "hash_strings_in_metric_report: false";
+
+    public static class TestDriveFormatter extends Formatter {
+        public String format(LogRecord record) {
+            return record.getMessage() + "\n";
+        }
+    }
+}
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index be9ccec..2d51038 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -6414,6 +6414,38 @@
 HPLandroid/util/proto/EncodedBuffer;->writeFromThisBuffer(II)V
 HPLandroid/util/proto/EncodedBuffer;->writeRawBuffer([BII)V
 HPLandroid/util/proto/EncodedBuffer;->writeRawFixed64(J)V
+HPLandroid/util/proto/ProtoInputStream;-><init>(Ljava/io/InputStream;I)V
+HPLandroid/util/proto/ProtoInputStream;-><init>(Ljava/io/InputStream;)V
+HPLandroid/util/proto/ProtoInputStream;-><init>([B)V
+HPLandroid/util/proto/ProtoInputStream;->getFieldNumber()I
+HPLandroid/util/proto/ProtoInputStream;->getWireType()I
+HPLandroid/util/proto/ProtoInputStream;->getOffset()I
+HPLandroid/util/proto/ProtoInputStream;->nextField()I
+HPLandroid/util/proto/ProtoInputStream;->isNextField(J)Z
+HPLandroid/util/proto/ProtoInputStream;->readDouble(J)D
+HPLandroid/util/proto/ProtoInputStream;->readFloat(J)F
+HPLandroid/util/proto/ProtoInputStream;->readInt(J)I
+HPLandroid/util/proto/ProtoInputStream;->readLong(J)J
+HPLandroid/util/proto/ProtoInputStream;->readBoolean(J)Z
+HPLandroid/util/proto/ProtoInputStream;->readString(J)Ljava/lang/String;
+HPLandroid/util/proto/ProtoInputStream;->readBytes(J)[B
+HPLandroid/util/proto/ProtoInputStream;->start(J)J
+HPLandroid/util/proto/ProtoInputStream;->end(J)V
+HPLandroid/util/proto/ProtoInputStream;->readTag()V
+HPLandroid/util/proto/ProtoInputStream;->decodeZigZag32(I)I
+HPLandroid/util/proto/ProtoInputStream;->decodeZigZag64(J)J
+HPLandroid/util/proto/ProtoInputStream;->readVarint()J
+HPLandroid/util/proto/ProtoInputStream;->readFixed32()I
+HPLandroid/util/proto/ProtoInputStream;->readFixed64()J
+HPLandroid/util/proto/ProtoInputStream;->readRawBytes(I)[B
+HPLandroid/util/proto/ProtoInputStream;->readRawString(I)Ljava/lang/String;
+HPLandroid/util/proto/ProtoInputStream;->fillBuffer()V
+HPLandroid/util/proto/ProtoInputStream;->skip()V
+HPLandroid/util/proto/ProtoInputStream;->incOffset(I)V
+HPLandroid/util/proto/ProtoInputStream;->checkPacked(J)V
+HPLandroid/util/proto/ProtoInputStream;->assertFieldNumber(J)V
+HPLandroid/util/proto/ProtoInputStream;->assertWireType(I)V
+HPLandroid/util/proto/ProtoInputStream;->assertFreshData()V
 HPLandroid/util/proto/ProtoOutputStream;-><init>(Ljava/io/FileDescriptor;)V
 HPLandroid/util/proto/ProtoOutputStream;-><init>(Ljava/io/OutputStream;)V
 HPLandroid/util/proto/ProtoOutputStream;->compactIfNecessary()V
@@ -58580,6 +58612,7 @@
 Landroid/util/apk/ZipUtils;
 Landroid/util/jar/StrictJarFile;
 Landroid/util/proto/EncodedBuffer;
+Landroid/util/proto/ProtoInputStream;
 Landroid/util/proto/ProtoOutputStream;
 Landroid/view/-$$Lambda$FocusFinder$FocusSorter$h0f2ZYL6peSaaEeCCkAoYs_YZvU;
 Landroid/view/-$$Lambda$FocusFinder$FocusSorter$kW7K1t9q7Y62V38r-7g6xRzqqq8;
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 6af34f9..bbc3f35 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -523,7 +523,6 @@
 Landroid/net/IConnectivityManager;->getTetheredIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->getTetheringErroredIfaces()[Ljava/lang/String;
 Landroid/net/IConnectivityManager;->reportInetCondition(II)V
-Landroid/net/IConnectivityManager;->setAirplaneMode(Z)V
 Landroid/net/IConnectivityManager;->startLegacyVpn(Lcom/android/internal/net/VpnProfile;)V
 Landroid/net/INetworkManagementEventObserver$Stub;-><init>()V
 Landroid/net/INetworkPolicyListener$Stub;-><init>()V
@@ -1384,62 +1383,6 @@
 Landroid/service/wallpaper/IWallpaperEngine;->setVisibility(Z)V
 Landroid/service/wallpaper/IWallpaperService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/wallpaper/IWallpaperService;
 Landroid/speech/IRecognitionListener;->onEvent(ILandroid/os/Bundle;)V
-Landroid/system/Int32Ref;->value:I
-Landroid/system/OsConstants;-><init>()V
-Landroid/system/OsConstants;->AF_NETLINK:I
-Landroid/system/OsConstants;->AF_PACKET:I
-Landroid/system/OsConstants;->ARPHRD_ETHER:I
-Landroid/system/OsConstants;->ARPHRD_LOOPBACK:I
-Landroid/system/OsConstants;->CAP_TO_INDEX(I)I
-Landroid/system/OsConstants;->CAP_TO_MASK(I)I
-Landroid/system/OsConstants;->ENONET:I
-Landroid/system/OsConstants;->ETH_P_ALL:I
-Landroid/system/OsConstants;->ETH_P_ARP:I
-Landroid/system/OsConstants;->ETH_P_IP:I
-Landroid/system/OsConstants;->ETH_P_IPV6:I
-Landroid/system/OsConstants;->EUSERS:I
-Landroid/system/OsConstants;->ICMP6_ECHO_REPLY:I
-Landroid/system/OsConstants;->ICMP6_ECHO_REQUEST:I
-Landroid/system/OsConstants;->ICMP_ECHO:I
-Landroid/system/OsConstants;->ICMP_ECHOREPLY:I
-Landroid/system/OsConstants;->initConstants()V
-Landroid/system/OsConstants;->IP_MULTICAST_ALL:I
-Landroid/system/OsConstants;->IP_RECVTOS:I
-Landroid/system/OsConstants;->MAP_POPULATE:I
-Landroid/system/OsConstants;->NETLINK_NETFILTER:I
-Landroid/system/OsConstants;->NETLINK_ROUTE:I
-Landroid/system/OsConstants;->O_DIRECT:I
-Landroid/system/OsConstants;->placeholder()I
-Landroid/system/OsConstants;->PR_CAP_AMBIENT:I
-Landroid/system/OsConstants;->PR_CAP_AMBIENT_RAISE:I
-Landroid/system/OsConstants;->RLIMIT_NOFILE:I
-Landroid/system/OsConstants;->RTMGRP_IPV4_IFADDR:I
-Landroid/system/OsConstants;->RTMGRP_IPV4_MROUTE:I
-Landroid/system/OsConstants;->RTMGRP_IPV4_ROUTE:I
-Landroid/system/OsConstants;->RTMGRP_IPV4_RULE:I
-Landroid/system/OsConstants;->RTMGRP_IPV6_IFADDR:I
-Landroid/system/OsConstants;->RTMGRP_IPV6_IFINFO:I
-Landroid/system/OsConstants;->RTMGRP_IPV6_MROUTE:I
-Landroid/system/OsConstants;->RTMGRP_IPV6_PREFIX:I
-Landroid/system/OsConstants;->RTMGRP_IPV6_ROUTE:I
-Landroid/system/OsConstants;->RTMGRP_LINK:I
-Landroid/system/OsConstants;->RTMGRP_NEIGH:I
-Landroid/system/OsConstants;->RTMGRP_NOTIFY:I
-Landroid/system/OsConstants;->RTMGRP_TC:I
-Landroid/system/OsConstants;->SO_DOMAIN:I
-Landroid/system/OsConstants;->SO_PROTOCOL:I
-Landroid/system/OsConstants;->SPLICE_F_MORE:I
-Landroid/system/OsConstants;->SPLICE_F_MOVE:I
-Landroid/system/OsConstants;->SPLICE_F_NONBLOCK:I
-Landroid/system/OsConstants;->TIOCOUTQ:I
-Landroid/system/OsConstants;->UDP_ENCAP:I
-Landroid/system/OsConstants;->UDP_ENCAP_ESPINUDP:I
-Landroid/system/OsConstants;->UDP_ENCAP_ESPINUDP_NON_IKE:I
-Landroid/system/OsConstants;->UNIX_PATH_MAX:I
-Landroid/system/OsConstants;->XATTR_CREATE:I
-Landroid/system/OsConstants;->XATTR_REPLACE:I
-Landroid/system/OsConstants;->_LINUX_CAPABILITY_VERSION_3:I
-Landroid/system/StructTimeval;->fromMillis(J)Landroid/system/StructTimeval;
 Landroid/telephony/CarrierMessagingServiceManager;-><init>()V
 Landroid/telephony/TelephonyManager$MultiSimVariants;->values()[Landroid/telephony/TelephonyManager$MultiSimVariants;
 Landroid/util/Singleton;-><init>()V
@@ -2216,6 +2159,7 @@
 Lcom/android/org/conscrypt/OpenSSLKey;->getNativeRef()Lcom/android/org/conscrypt/NativeRef$EVP_PKEY;
 Lcom/android/org/conscrypt/OpenSSLKey;->getPublicKey()Ljava/security/PublicKey;
 Lcom/android/org/conscrypt/OpenSSLProvider;-><init>()V
+Lcom/android/org/conscrypt/OpenSSLRandom;-><init>()V
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String;
@@ -2339,93 +2283,6 @@
 Lcom/google/android/mms/util/PduCache;->purgeAll()V
 Lcom/google/android/mms/util/PduCacheEntry;->getPdu()Lcom/google/android/mms/pdu/GenericPdu;
 Lcom/google/android/mms/util/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
-Ldalvik/system/BaseDexClassLoader;-><init>(Ljava/lang/String;Ljava/io/File;Ljava/lang/String;Ljava/lang/ClassLoader;Z)V
-Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;)V
-Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;Z)V
-Ldalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String;
-Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;
-Ldalvik/system/BlockGuard$BlockGuardPolicyException;-><init>(IILjava/lang/String;)V
-Ldalvik/system/BlockGuard$BlockGuardPolicyException;->mMessage:Ljava/lang/String;
-Ldalvik/system/BlockGuard$BlockGuardPolicyException;->mPolicyState:I
-Ldalvik/system/BlockGuard$BlockGuardPolicyException;->mPolicyViolated:I
-Ldalvik/system/BlockGuard$Policy;->onNetwork()V
-Ldalvik/system/BlockGuard$Policy;->onReadFromDisk()V
-Ldalvik/system/BlockGuard;->getThreadPolicy()Ldalvik/system/BlockGuard$Policy;
-Ldalvik/system/BlockGuard;->LAX_POLICY:Ldalvik/system/BlockGuard$Policy;
-Ldalvik/system/BlockGuard;->setThreadPolicy(Ldalvik/system/BlockGuard$Policy;)V
-Ldalvik/system/BlockGuard;->threadPolicy:Ljava/lang/ThreadLocal;
-Ldalvik/system/CloseGuard$DefaultReporter;-><init>()V
-Ldalvik/system/CloseGuard$Reporter;->report(Ljava/lang/String;Ljava/lang/Throwable;)V
-Ldalvik/system/CloseGuard;-><init>()V
-Ldalvik/system/CloseGuard;->close()V
-Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard;
-Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V
-Ldalvik/system/CloseGuard;->setEnabled(Z)V
-Ldalvik/system/CloseGuard;->setReporter(Ldalvik/system/CloseGuard$Reporter;)V
-Ldalvik/system/CloseGuard;->warnIfOpen()V
-Ldalvik/system/DexFile$DFEnum;->mNameList:[Ljava/lang/String;
-Ldalvik/system/DexFile;->getClassNameList(Ljava/lang/Object;)[Ljava/lang/String;
-Ldalvik/system/DexFile;->isBackedByOatFile()Z
-Ldalvik/system/DexFile;->loadClassBinaryName(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/util/List;)Ljava/lang/Class;
-Ldalvik/system/DexFile;->loadDex(Ljava/lang/String;Ljava/lang/String;ILjava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ldalvik/system/DexFile;
-Ldalvik/system/DexFile;->mCookie:Ljava/lang/Object;
-Ldalvik/system/DexFile;->mFileName:Ljava/lang/String;
-Ldalvik/system/DexFile;->mInternalCookie:Ljava/lang/Object;
-Ldalvik/system/DexFile;->openDexFile(Ljava/lang/String;Ljava/lang/String;ILjava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ljava/lang/Object;
-Ldalvik/system/DexFile;->openDexFileNative(Ljava/lang/String;Ljava/lang/String;ILjava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ljava/lang/Object;
-Ldalvik/system/DexPathList$Element;-><init>(Ldalvik/system/DexFile;Ljava/io/File;)V
-Ldalvik/system/DexPathList$Element;-><init>(Ljava/io/File;ZLjava/io/File;Ldalvik/system/DexFile;)V
-Ldalvik/system/DexPathList$Element;->dexFile:Ldalvik/system/DexFile;
-Ldalvik/system/DexPathList$Element;->path:Ljava/io/File;
-Ldalvik/system/DexPathList$NativeLibraryElement;-><init>(Ljava/io/File;)V
-Ldalvik/system/DexPathList$NativeLibraryElement;->path:Ljava/io/File;
-Ldalvik/system/DexPathList;-><init>(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;)V
-Ldalvik/system/DexPathList;->addDexPath(Ljava/lang/String;Ljava/io/File;)V
-Ldalvik/system/DexPathList;->addNativePath(Ljava/util/Collection;)V
-Ldalvik/system/DexPathList;->definingContext:Ljava/lang/ClassLoader;
-Ldalvik/system/DexPathList;->dexElements:[Ldalvik/system/DexPathList$Element;
-Ldalvik/system/DexPathList;->dexElementsSuppressedExceptions:[Ljava/io/IOException;
-Ldalvik/system/DexPathList;->loadDexFile(Ljava/io/File;Ljava/io/File;Ljava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ldalvik/system/DexFile;
-Ldalvik/system/DexPathList;->makeDexElements(Ljava/util/List;Ljava/io/File;Ljava/util/List;Ljava/lang/ClassLoader;)[Ldalvik/system/DexPathList$Element;
-Ldalvik/system/DexPathList;->makeInMemoryDexElements([Ljava/nio/ByteBuffer;Ljava/util/List;)[Ldalvik/system/DexPathList$Element;
-Ldalvik/system/DexPathList;->makePathElements(Ljava/util/List;)[Ldalvik/system/DexPathList$NativeLibraryElement;
-Ldalvik/system/DexPathList;->makePathElements(Ljava/util/List;Ljava/io/File;Ljava/util/List;)[Ldalvik/system/DexPathList$Element;
-Ldalvik/system/DexPathList;->nativeLibraryDirectories:Ljava/util/List;
-Ldalvik/system/DexPathList;->nativeLibraryPathElements:[Ldalvik/system/DexPathList$NativeLibraryElement;
-Ldalvik/system/DexPathList;->splitPaths(Ljava/lang/String;Z)Ljava/util/List;
-Ldalvik/system/DexPathList;->systemNativeLibraryDirectories:Ljava/util/List;
-Ldalvik/system/SocketTagger;->get()Ldalvik/system/SocketTagger;
-Ldalvik/system/SocketTagger;->tag(Ljava/net/Socket;)V
-Ldalvik/system/SocketTagger;->untag(Ljava/net/Socket;)V
-Ldalvik/system/VMDebug;->allowHiddenApiReflectionFrom(Ljava/lang/Class;)V
-Ldalvik/system/VMDebug;->dumpReferenceTables()V
-Ldalvik/system/VMDebug;->isDebuggerConnected()Z
-Ldalvik/system/VMRuntime;->addressOf(Ljava/lang/Object;)J
-Ldalvik/system/VMRuntime;->clearGrowthLimit()V
-Ldalvik/system/VMRuntime;->gcSoftReferences()V
-Ldalvik/system/VMRuntime;->getCurrentInstructionSet()Ljava/lang/String;
-Ldalvik/system/VMRuntime;->getExternalBytesAllocated()J
-Ldalvik/system/VMRuntime;->getInstructionSet(Ljava/lang/String;)Ljava/lang/String;
-Ldalvik/system/VMRuntime;->getMinimumHeapSize()J
-Ldalvik/system/VMRuntime;->getRuntime()Ldalvik/system/VMRuntime;
-Ldalvik/system/VMRuntime;->is64Bit()Z
-Ldalvik/system/VMRuntime;->is64BitAbi(Ljava/lang/String;)Z
-Ldalvik/system/VMRuntime;->newNonMovableArray(Ljava/lang/Class;I)Ljava/lang/Object;
-Ldalvik/system/VMRuntime;->registerNativeAllocation(I)V
-Ldalvik/system/VMRuntime;->registerNativeFree(I)V
-Ldalvik/system/VMRuntime;->runFinalization(J)V
-Ldalvik/system/VMRuntime;->runFinalizationSync()V
-Ldalvik/system/VMRuntime;->setMinimumHeapSize(J)J
-Ldalvik/system/VMRuntime;->setTargetHeapUtilization(F)F
-Ldalvik/system/VMRuntime;->setTargetSdkVersion(I)V
-Ldalvik/system/VMRuntime;->trackExternalAllocation(J)Z
-Ldalvik/system/VMRuntime;->trackExternalFree(J)V
-Ldalvik/system/VMRuntime;->vmInstructionSet()Ljava/lang/String;
-Ldalvik/system/VMRuntime;->vmLibrary()Ljava/lang/String;
-Ldalvik/system/VMStack;->fillStackTraceElements(Ljava/lang/Thread;[Ljava/lang/StackTraceElement;)I
-Ldalvik/system/VMStack;->getCallingClassLoader()Ljava/lang/ClassLoader;
-Ldalvik/system/VMStack;->getStackClass2()Ljava/lang/Class;
-Ldalvik/system/VMStack;->getThreadStackTrace(Ljava/lang/Thread;)[Ljava/lang/StackTraceElement;
 Ljava/io/Console;->encoding()Ljava/lang/String;
 Ljava/io/File;->filePath:Ljava/nio/file/Path;
 Ljava/io/File;->fs:Ljava/io/FileSystem;
@@ -2501,18 +2358,6 @@
 Ljava/lang/Class;->objectSize:I
 Ljava/lang/Class;->status:I
 Ljava/lang/ClassLoader;->parent:Ljava/lang/ClassLoader;
-Ljava/lang/Daemons$Daemon;->isRunning()Z
-Ljava/lang/Daemons$Daemon;->start()V
-Ljava/lang/Daemons$Daemon;->stop()V
-Ljava/lang/Daemons$Daemon;->thread:Ljava/lang/Thread;
-Ljava/lang/Daemons$FinalizerDaemon;->finalizingObject:Ljava/lang/Object;
-Ljava/lang/Daemons$FinalizerDaemon;->INSTANCE:Ljava/lang/Daemons$FinalizerDaemon;
-Ljava/lang/Daemons$FinalizerWatchdogDaemon;->INSTANCE:Ljava/lang/Daemons$FinalizerWatchdogDaemon;
-Ljava/lang/Daemons$ReferenceQueueDaemon;->INSTANCE:Ljava/lang/Daemons$ReferenceQueueDaemon;
-Ljava/lang/Daemons;->MAX_FINALIZE_NANOS:J
-Ljava/lang/Daemons;->requestHeapTrim()V
-Ljava/lang/Daemons;->start()V
-Ljava/lang/Daemons;->stop()V
 Ljava/lang/Double;->value:D
 Ljava/lang/Enum;->getSharedConstants(Ljava/lang/Class;)[Ljava/lang/Enum;
 Ljava/lang/Enum;->name:Ljava/lang/String;
@@ -2522,11 +2367,6 @@
 Ljava/lang/invoke/MethodHandles$Lookup;-><init>(Ljava/lang/Class;I)V
 Ljava/lang/Long;->value:J
 Ljava/lang/Object;->identityHashCode(Ljava/lang/Object;)I
-Ljava/lang/ref/FinalizerReference;->add(Ljava/lang/Object;)V
-Ljava/lang/ref/FinalizerReference;->head:Ljava/lang/ref/FinalizerReference;
-Ljava/lang/ref/FinalizerReference;->next:Ljava/lang/ref/FinalizerReference;
-Ljava/lang/ref/FinalizerReference;->queue:Ljava/lang/ref/ReferenceQueue;
-Ljava/lang/ref/FinalizerReference;->remove(Ljava/lang/ref/FinalizerReference;)V
 Ljava/lang/ref/Reference;->getReferent()Ljava/lang/Object;
 Ljava/lang/ref/Reference;->referent:Ljava/lang/Object;
 Ljava/lang/ref/ReferenceQueue;->add(Ljava/lang/ref/Reference;)V
@@ -2669,12 +2509,6 @@
 Ljava/nio/charset/Charset;->defaultCharset:Ljava/nio/charset/Charset;
 Ljava/nio/charset/CharsetEncoder;->canEncode(Ljava/nio/CharBuffer;)Z
 Ljava/nio/DirectByteBuffer;-><init>(JI)V
-Ljava/nio/NIOAccess;->getBaseArray(Ljava/nio/Buffer;)Ljava/lang/Object;
-Ljava/nio/NIOAccess;->getBaseArrayOffset(Ljava/nio/Buffer;)I
-Ljava/nio/NIOAccess;->getBasePointer(Ljava/nio/Buffer;)J
-Ljava/nio/NioUtils;->freeDirectBuffer(Ljava/nio/ByteBuffer;)V
-Ljava/nio/NioUtils;->unsafeArray(Ljava/nio/ByteBuffer;)[B
-Ljava/nio/NioUtils;->unsafeArrayOffset(Ljava/nio/ByteBuffer;)I
 Ljava/security/KeyPairGenerator;->getInstance(Lsun/security/jca/GetInstance$Instance;Ljava/lang/String;)Ljava/security/KeyPairGenerator;
 Ljava/security/KeyStore;->keyStoreSpi:Ljava/security/KeyStoreSpi;
 Ljava/security/Signature;->getInstance(Lsun/security/jca/GetInstance$Instance;Ljava/lang/String;)Ljava/security/Signature;
@@ -2790,18 +2624,6 @@
 Ljavax/net/ssl/SSLServerSocketFactory;->defaultServerSocketFactory:Ljavax/net/ssl/SSLServerSocketFactory;
 Ljavax/net/ssl/SSLSocketFactory;->createSocket(Ljava/net/Socket;Ljava/io/InputStream;Z)Ljava/net/Socket;
 Ljavax/net/ssl/SSLSocketFactory;->defaultSocketFactory:Ljavax/net/ssl/SSLSocketFactory;
-Llibcore/icu/ICU;->addLikelySubtags(Ljava/util/Locale;)Ljava/util/Locale;
-Llibcore/io/Memory;->peekByte(J)B
-Llibcore/io/Memory;->peekByteArray(J[BII)V
-Llibcore/io/Memory;->peekInt(JZ)I
-Llibcore/io/Memory;->peekLong(JZ)J
-Llibcore/io/Memory;->pokeByte(JB)V
-Llibcore/io/Memory;->pokeByteArray(J[BII)V
-Llibcore/io/Memory;->pokeInt(JIZ)V
-Llibcore/io/Memory;->pokeLong(JJZ)V
-Llibcore/io/Streams;->copy(Ljava/io/InputStream;Ljava/io/OutputStream;)I
-Llibcore/util/BasicLruCache;->map:Ljava/util/LinkedHashMap;
-Llibcore/util/ZoneInfo;->mTransitions:[J
 Lorg/ccil/cowan/tagsoup/AttributesImpl;->data:[Ljava/lang/String;
 Lorg/ccil/cowan/tagsoup/AttributesImpl;->length:I
 Lorg/ccil/cowan/tagsoup/ElementType;->theAtts:Lorg/ccil/cowan/tagsoup/AttributesImpl;
@@ -2820,100 +2642,6 @@
 Lorg/ccil/cowan/tagsoup/Schema;->thePrefix:Ljava/lang/String;
 Lorg/ccil/cowan/tagsoup/Schema;->theRoot:Lorg/ccil/cowan/tagsoup/ElementType;
 Lorg/ccil/cowan/tagsoup/Schema;->theURI:Ljava/lang/String;
-Lorg/json/JSONArray;->values:Ljava/util/List;
-Lorg/json/JSONArray;->writeTo(Lorg/json/JSONStringer;)V
-Lorg/json/JSONObject;->append(Ljava/lang/String;Ljava/lang/Object;)Lorg/json/JSONObject;
-Lorg/json/JSONObject;->checkName(Ljava/lang/String;)Ljava/lang/String;
-Lorg/json/JSONObject;->keySet()Ljava/util/Set;
-Lorg/json/JSONObject;->nameValuePairs:Ljava/util/LinkedHashMap;
-Lorg/json/JSONObject;->NEGATIVE_ZERO:Ljava/lang/Double;
-Lorg/json/JSONObject;->writeTo(Lorg/json/JSONStringer;)V
-Lorg/json/JSONStringer;-><init>(I)V
-Lorg/json/JSONStringer;->beforeKey()V
-Lorg/json/JSONStringer;->beforeValue()V
-Lorg/json/JSONStringer;->close(Lorg/json/JSONStringer$Scope;Lorg/json/JSONStringer$Scope;Ljava/lang/String;)Lorg/json/JSONStringer;
-Lorg/json/JSONStringer;->indent:Ljava/lang/String;
-Lorg/json/JSONStringer;->newline()V
-Lorg/json/JSONStringer;->open(Lorg/json/JSONStringer$Scope;Ljava/lang/String;)Lorg/json/JSONStringer;
-Lorg/json/JSONStringer;->out:Ljava/lang/StringBuilder;
-Lorg/json/JSONStringer;->peek()Lorg/json/JSONStringer$Scope;
-Lorg/json/JSONStringer;->replaceTop(Lorg/json/JSONStringer$Scope;)V
-Lorg/json/JSONStringer;->stack:Ljava/util/List;
-Lorg/json/JSONStringer;->string(Ljava/lang/String;)V
-Lorg/json/JSONTokener;->in:Ljava/lang/String;
-Lorg/json/JSONTokener;->nextCleanInternal()I
-Lorg/json/JSONTokener;->nextToInternal(Ljava/lang/String;)Ljava/lang/String;
-Lorg/json/JSONTokener;->pos:I
-Lorg/json/JSONTokener;->readArray()Lorg/json/JSONArray;
-Lorg/json/JSONTokener;->readEscapeCharacter()C
-Lorg/json/JSONTokener;->readLiteral()Ljava/lang/Object;
-Lorg/json/JSONTokener;->readObject()Lorg/json/JSONObject;
-Lorg/json/JSONTokener;->skipToEndOfLine()V
-Lorg/w3c/dom/ls/LSSerializerFilter;->getWhatToShow()I
-Lorg/w3c/dom/traversal/NodeFilter;->acceptNode(Lorg/w3c/dom/Node;)S
-Lorg/w3c/dom/traversal/NodeIterator;->detach()V
-Lorg/w3c/dom/traversal/NodeIterator;->nextNode()Lorg/w3c/dom/Node;
-Lorg/xml/sax/ext/Attributes2Impl;->declared:[Z
-Lorg/xml/sax/ext/Attributes2Impl;->specified:[Z
-Lorg/xml/sax/ext/Locator2Impl;->encoding:Ljava/lang/String;
-Lorg/xml/sax/ext/Locator2Impl;->version:Ljava/lang/String;
-Lorg/xml/sax/helpers/AttributesImpl;->badIndex(I)V
-Lorg/xml/sax/helpers/AttributesImpl;->data:[Ljava/lang/String;
-Lorg/xml/sax/helpers/AttributesImpl;->ensureCapacity(I)V
-Lorg/xml/sax/helpers/AttributesImpl;->length:I
-Lorg/xml/sax/helpers/LocatorImpl;->columnNumber:I
-Lorg/xml/sax/helpers/LocatorImpl;->lineNumber:I
-Lorg/xml/sax/helpers/LocatorImpl;->publicId:Ljava/lang/String;
-Lorg/xml/sax/helpers/LocatorImpl;->systemId:Ljava/lang/String;
-Lorg/xml/sax/helpers/NamespaceSupport;->contextPos:I
-Lorg/xml/sax/helpers/NamespaceSupport;->contexts:[Lorg/xml/sax/helpers/NamespaceSupport$Context;
-Lorg/xml/sax/helpers/NamespaceSupport;->currentContext:Lorg/xml/sax/helpers/NamespaceSupport$Context;
-Lorg/xml/sax/helpers/NamespaceSupport;->EMPTY_ENUMERATION:Ljava/util/Enumeration;
-Lorg/xml/sax/helpers/NamespaceSupport;->namespaceDeclUris:Z
-Lorg/xml/sax/helpers/ParserAdapter;->attAdapter:Lorg/xml/sax/helpers/ParserAdapter$AttributeListAdapter;
-Lorg/xml/sax/helpers/ParserAdapter;->atts:Lorg/xml/sax/helpers/AttributesImpl;
-Lorg/xml/sax/helpers/ParserAdapter;->checkNotParsing(Ljava/lang/String;Ljava/lang/String;)V
-Lorg/xml/sax/helpers/ParserAdapter;->contentHandler:Lorg/xml/sax/ContentHandler;
-Lorg/xml/sax/helpers/ParserAdapter;->dtdHandler:Lorg/xml/sax/DTDHandler;
-Lorg/xml/sax/helpers/ParserAdapter;->entityResolver:Lorg/xml/sax/EntityResolver;
-Lorg/xml/sax/helpers/ParserAdapter;->errorHandler:Lorg/xml/sax/ErrorHandler;
-Lorg/xml/sax/helpers/ParserAdapter;->locator:Lorg/xml/sax/Locator;
-Lorg/xml/sax/helpers/ParserAdapter;->makeException(Ljava/lang/String;)Lorg/xml/sax/SAXParseException;
-Lorg/xml/sax/helpers/ParserAdapter;->nameParts:[Ljava/lang/String;
-Lorg/xml/sax/helpers/ParserAdapter;->namespaces:Z
-Lorg/xml/sax/helpers/ParserAdapter;->nsSupport:Lorg/xml/sax/helpers/NamespaceSupport;
-Lorg/xml/sax/helpers/ParserAdapter;->parser:Lorg/xml/sax/Parser;
-Lorg/xml/sax/helpers/ParserAdapter;->parsing:Z
-Lorg/xml/sax/helpers/ParserAdapter;->prefixes:Z
-Lorg/xml/sax/helpers/ParserAdapter;->processName(Ljava/lang/String;ZZ)[Ljava/lang/String;
-Lorg/xml/sax/helpers/ParserAdapter;->reportError(Ljava/lang/String;)V
-Lorg/xml/sax/helpers/ParserAdapter;->setup(Lorg/xml/sax/Parser;)V
-Lorg/xml/sax/helpers/ParserAdapter;->setupParser()V
-Lorg/xml/sax/helpers/ParserAdapter;->uris:Z
-Lorg/xml/sax/helpers/XMLFilterImpl;->contentHandler:Lorg/xml/sax/ContentHandler;
-Lorg/xml/sax/helpers/XMLFilterImpl;->dtdHandler:Lorg/xml/sax/DTDHandler;
-Lorg/xml/sax/helpers/XMLFilterImpl;->entityResolver:Lorg/xml/sax/EntityResolver;
-Lorg/xml/sax/helpers/XMLFilterImpl;->errorHandler:Lorg/xml/sax/ErrorHandler;
-Lorg/xml/sax/helpers/XMLFilterImpl;->locator:Lorg/xml/sax/Locator;
-Lorg/xml/sax/helpers/XMLFilterImpl;->parent:Lorg/xml/sax/XMLReader;
-Lorg/xml/sax/helpers/XMLFilterImpl;->setupParse()V
-Lorg/xml/sax/helpers/XMLReaderAdapter;->documentHandler:Lorg/xml/sax/DocumentHandler;
-Lorg/xml/sax/helpers/XMLReaderAdapter;->qAtts:Lorg/xml/sax/helpers/XMLReaderAdapter$AttributesAdapter;
-Lorg/xml/sax/helpers/XMLReaderAdapter;->setup(Lorg/xml/sax/XMLReader;)V
-Lorg/xml/sax/helpers/XMLReaderAdapter;->setupXMLReader()V
-Lorg/xml/sax/helpers/XMLReaderAdapter;->xmlReader:Lorg/xml/sax/XMLReader;
-Lorg/xml/sax/helpers/XMLReaderFactory;->loadClass(Ljava/lang/ClassLoader;Ljava/lang/String;)Lorg/xml/sax/XMLReader;
-Lorg/xml/sax/InputSource;->byteStream:Ljava/io/InputStream;
-Lorg/xml/sax/InputSource;->characterStream:Ljava/io/Reader;
-Lorg/xml/sax/InputSource;->encoding:Ljava/lang/String;
-Lorg/xml/sax/InputSource;->publicId:Ljava/lang/String;
-Lorg/xml/sax/InputSource;->systemId:Ljava/lang/String;
-Lorg/xml/sax/SAXException;->exception:Ljava/lang/Exception;
-Lorg/xml/sax/SAXParseException;->columnNumber:I
-Lorg/xml/sax/SAXParseException;->init(Ljava/lang/String;Ljava/lang/String;II)V
-Lorg/xml/sax/SAXParseException;->lineNumber:I
-Lorg/xml/sax/SAXParseException;->publicId:Ljava/lang/String;
-Lorg/xml/sax/SAXParseException;->systemId:Ljava/lang/String;
 Lsun/misc/Cleaner;->clean()V
 Lsun/misc/Unsafe;->addressSize()I
 Lsun/misc/Unsafe;->allocateInstance(Ljava/lang/Class;)Ljava/lang/Object;
diff --git a/config/hiddenapi-max-sdk-p-blacklist.txt b/config/hiddenapi-max-sdk-p-blacklist.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/config/hiddenapi-max-sdk-p-blacklist.txt
diff --git a/config/hiddenapi-vendor-list.txt b/config/hiddenapi-vendor-list.txt
index 45e38cf..e5e64d3 100644
--- a/config/hiddenapi-vendor-list.txt
+++ b/config/hiddenapi-vendor-list.txt
@@ -122,14 +122,6 @@
 Landroid/os/UserManager;->hasUserRestriction(Ljava/lang/String;Landroid/os/UserHandle;)Z
 Landroid/os/UserManager;->isAdminUser()Z
 Landroid/R$styleable;->CheckBoxPreference:[I
-Landroid/system/NetlinkSocketAddress;-><init>(II)V
-Landroid/system/Os;->bind(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V
-Landroid/system/Os;->connect(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V
-Landroid/system/Os;->sendto(Ljava/io/FileDescriptor;[BIIILjava/net/SocketAddress;)I
-Landroid/system/Os;->setsockoptIfreq(Ljava/io/FileDescriptor;IILjava/lang/String;)V
-Landroid/system/Os;->setsockoptTimeval(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V
-Landroid/system/PacketSocketAddress;-><init>(I[B)V
-Landroid/system/PacketSocketAddress;-><init>(SI)V
 Landroid/telephony/ims/compat/feature/MMTelFeature;-><init>()V
 Landroid/telephony/ims/compat/ImsService;-><init>()V
 Landroid/telephony/ims/compat/stub/ImsCallSessionImplBase;-><init>()V
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 56ca98f..95bcf0e 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -2354,6 +2354,7 @@
 android.nfc.NfcAdapter$CreateNdefMessageCallback
 android.nfc.NfcManager
 android.opengl.EGL14
+android.opengl.EGL15
 android.opengl.EGLConfig
 android.opengl.EGLContext
 android.opengl.EGLDisplay
@@ -3226,7 +3227,7 @@
 android.view.DisplayEventReceiver
 android.view.DisplayInfo
 android.view.DisplayInfo$1
-android.view.DisplayListCanvas
+android.graphics.RecordingCanvas
 android.view.FallbackEventHandler
 android.view.FocusFinder
 android.view.FocusFinder$1
@@ -3304,8 +3305,8 @@
 android.view.OrientationEventListener$SensorEventListenerImpl
 android.view.PointerIcon
 android.view.PointerIcon$1
-android.view.RenderNode
-android.view.RenderNode$NoImagePreloadHolder
+android.graphics.RenderNode
+android.graphics.RenderNode$NoImagePreloadHolder
 android.view.RenderNodeAnimator
 android.view.RenderNodeAnimator$1
 android.view.RenderNodeAnimatorSetHelper
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index aa0275a..d7cca15 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -201,8 +201,8 @@
      * semantics in the context of the screen content. For example, a three by three
      * grid can be implemented as three horizontal linear layouts and one vertical,
      * or three vertical linear layouts and one horizontal, or one grid layout, etc.
-     * In this context the actual layout mangers used to achieve the grid configuration
-     * are not important, rather it is important that there are nine evenly distributed
+     * In this context, the actual layout managers used to achieve the grid configuration
+     * are not important; rather it is important that there are nine evenly distributed
      * elements.
      * </p>
      */
diff --git a/core/java/android/accounts/AbstractAccountAuthenticator.java b/core/java/android/accounts/AbstractAccountAuthenticator.java
index a3b3a9f..25cd342 100644
--- a/core/java/android/accounts/AbstractAccountAuthenticator.java
+++ b/core/java/android/accounts/AbstractAccountAuthenticator.java
@@ -17,7 +17,6 @@
 package android.accounts;
 
 import android.Manifest;
-import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -32,8 +31,8 @@
 
 /**
  * Abstract base class for creating AccountAuthenticators.
- * In order to be an authenticator one must extend this class, provider implementations for the
- * abstract methods and write a service that returns the result of {@link #getIBinder()}
+ * In order to be an authenticator one must extend this class, provide implementations for the
+ * abstract methods, and write a service that returns the result of {@link #getIBinder()}
  * in the service's {@link android.app.Service#onBind(android.content.Intent)} when invoked
  * with an intent with action {@link AccountManager#ACTION_AUTHENTICATOR_INTENT}. This service
  * must specify the following intent filter and metadata tags in its AndroidManifest.xml file
@@ -974,7 +973,8 @@
      *
      * @param response to send the result back to the AccountManager, will never be null.
      * @param account the account to check, will never be null
-     * @param statusToken a String of token to check if update of credentials is suggested.
+     * @param statusToken a String of token which can be used to check the status of locally
+     *            stored credentials and if update of credentials is suggested
      * @return a Bundle result or null if the result is to be returned via the response. The result
      *         will contain either:
      *         <ul>
diff --git a/core/java/android/accounts/AccountAuthenticatorActivity.java b/core/java/android/accounts/AccountAuthenticatorActivity.java
index f9284e6..967aa04 100644
--- a/core/java/android/accounts/AccountAuthenticatorActivity.java
+++ b/core/java/android/accounts/AccountAuthenticatorActivity.java
@@ -48,7 +48,7 @@
     }
 
     /**
-     * Retreives the AccountAuthenticatorResponse from either the intent of the icicle, if the
+     * Retrieves the AccountAuthenticatorResponse from either the intent of the icicle, if the
      * icicle is non-zero.
      * @param icicle the save instance data of this Activity, may be null
      */
diff --git a/core/java/android/animation/Keyframe.java b/core/java/android/animation/Keyframe.java
index 5483c49..bcb94d1 100644
--- a/core/java/android/animation/Keyframe.java
+++ b/core/java/android/animation/Keyframe.java
@@ -76,7 +76,7 @@
      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
      * of time elapsed of the overall animation duration.
      * @param value The value that the object will animate to as the animation time approaches
-     * the time in this keyframe, and the the value animated from as the time passes the time in
+     * the time in this keyframe, and the value animated from as the time passes the time in
      * this keyframe.
      */
     public static Keyframe ofInt(float fraction, int value) {
@@ -108,7 +108,7 @@
      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
      * of time elapsed of the overall animation duration.
      * @param value The value that the object will animate to as the animation time approaches
-     * the time in this keyframe, and the the value animated from as the time passes the time in
+     * the time in this keyframe, and the value animated from as the time passes the time in
      * this keyframe.
      */
     public static Keyframe ofFloat(float fraction, float value) {
@@ -140,7 +140,7 @@
      * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
      * of time elapsed of the overall animation duration.
      * @param value The value that the object will animate to as the animation time approaches
-     * the time in this keyframe, and the the value animated from as the time passes the time in
+     * the time in this keyframe, and the value animated from as the time passes the time in
      * this keyframe.
      */
     public static Keyframe ofObject(float fraction, Object value) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 482ef2d..3cc5e37 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2952,7 +2952,7 @@
     /**
      * Use with {@link #setDefaultKeyMode} to specify that unhandled keystrokes
      * will start an application-defined search.  (If the application or activity does not
-     * actually define a search, the the keys will be ignored.)
+     * actually define a search, the keys will be ignored.)
      *
      * <p>See {@link android.app.SearchManager android.app.SearchManager} for more details.
      *
@@ -3252,7 +3252,7 @@
      * interacted with the device in some way while your activity is running.
      * This callback and {@link #onUserLeaveHint} are intended to help
      * activities manage status bar notifications intelligently; specifically,
-     * for helping activities determine the proper time to cancel a notfication.
+     * for helping activities determine the proper time to cancel a notification.
      *
      * <p>All calls to your activity's {@link #onUserLeaveHint} callback will
      * be accompanied by calls to {@link #onUserInteraction}.  This
@@ -4678,7 +4678,7 @@
         if (decor != null) {
             decor.cancelPendingInputEvents();
         }
-        if (options != null && !isTopOfTask()) {
+        if (options != null) {
             mActivityTransitionState.startExitOutTransition(this, options);
         }
     }
@@ -4882,6 +4882,7 @@
             Bundle options)
             throws IntentSender.SendIntentException {
         try {
+            options = transferSpringboardActivityOptions(options);
             String resolvedType = null;
             if (fillInIntent != null) {
                 fillInIntent.migrateExtraStreamToClipData();
@@ -4898,6 +4899,12 @@
                 throw new IntentSender.SendIntentException();
             }
             Instrumentation.checkStartActivityResult(result, null);
+
+            if (options != null) {
+                // Only when the options are not null, as the intent can point to something other
+                // than an Activity.
+                cancelInputsAndStartExitTransition(options);
+            }
         } catch (RemoteException e) {
         }
         if (requestCode >= 0) {
@@ -6471,7 +6478,7 @@
      *
      * @return true if this is the topmost, non-finishing activity in its task.
      */
-    private boolean isTopOfTask() {
+    final boolean isTopOfTask() {
         if (mToken == null || mWindow == null) {
             return false;
         }
@@ -7906,7 +7913,7 @@
     }
 
     /**
-     * Specifies whether an {@link Activity} should be shown on top of the the lock screen whenever
+     * Specifies whether an {@link Activity} should be shown on top of the lock screen whenever
      * the lockscreen is up and the activity is resumed. Normally an activity will be transitioned
      * to the stopped state if it is started while the lockscreen is up, but with this flag set the
      * activity will remain in the resumed state visible on-top of the lock screen. This value can
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 14b8ae4..7330da3 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -137,6 +137,17 @@
     private static final int FIRST_START_NON_FATAL_ERROR_CODE = 100;
     private static final int LAST_START_NON_FATAL_ERROR_CODE = 199;
 
+    /**
+     * Disable hidden API checks for the newly started instrumentation.
+     * @hide
+     */
+    public static final int INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
+    /**
+     * Mount full external storage for the newly started instrumentation.
+     * @hide
+     */
+    public static final int INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL = 1 << 1;
+
     static final class UidObserver extends IUidObserver.Stub {
         final OnUidImportanceListener mListener;
         final Context mContext;
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 294a3ec..069effd 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -22,6 +22,7 @@
 import android.content.IIntentReceiver;
 import android.content.IIntentSender;
 import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.UserInfo;
 import android.os.Bundle;
@@ -123,17 +124,6 @@
     public abstract void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq);
 
     /**
-     * Saves the current activity manager state and includes the saved state in the next dump of
-     * activity manager.
-     */
-    public abstract void saveANRState(String reason);
-
-    /**
-     * Clears the previously saved activity manager ANR state.
-     */
-    public abstract void clearSavedANRState();
-
-    /**
      * @return true if runtime was restarted, false if it's normal boot
      */
     public abstract boolean isRuntimeRestarted();
@@ -165,10 +155,19 @@
 
     /**
      * Returns a list that contains the memory stats for currently running processes.
+     *
+     * Only processes managed by ActivityManagerService are included.
      */
     public abstract List<ProcessMemoryState> getMemoryStateForProcesses();
 
     /**
+     * Returns a list that contains the memory stats for monitored native processes.
+     *
+     * The list of the monitored processes is defined in MemoryStatUtil class.
+     */
+    public abstract List<ProcessMemoryState> getMemoryStateForNativeProcesses();
+
+    /**
      * Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as
      * needed.
      */
@@ -187,9 +186,6 @@
     /** Trims memory usage in the system by removing/stopping unused application processes. */
     public abstract void trimApplications();
 
-    /** Closes all system dialogs. */
-    public abstract void closeSystemDialogs(String reason);
-
     /** Kill the processes in the list due to their tasks been removed. */
     public abstract void killProcessesForRemovedTask(ArrayList<Object> procsToKill);
 
@@ -212,11 +208,6 @@
      */
     public abstract boolean shouldConfirmCredentials(int userId);
 
-    /**
-     * @return The intent used to launch the home activity.
-     */
-    public abstract Intent getHomeIntent();
-
     public abstract int[] getCurrentProfileIds();
     public abstract UserInfo getCurrentUser();
     public abstract void ensureNotSpecialUser(int userId);
@@ -245,4 +236,48 @@
     public abstract ComponentName startServiceInPackage(int uid, Intent service,
             String resolvedType, boolean fgRequired, String callingPackage, int userId)
             throws TransactionTooLargeException;
+
+    public abstract void disconnectActivityFromServices(Object connectionHolder);
+    public abstract void cleanUpServices(int userId, ComponentName component, Intent baseIntent);
+    public abstract ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId);
+    public abstract void ensureBootCompleted();
+    public abstract void updateOomLevelsForDisplay(int displayId);
+    public abstract boolean isActivityStartsLoggingEnabled();
+    public abstract void reportCurKeyguardUsageEvent(boolean keyguardShowing);
+
+    /** Input dispatch timeout to a window, start the ANR process. */
+    public abstract long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason);
+    public abstract boolean inputDispatchingTimedOut(Object proc, String activityShortComponentName,
+            ApplicationInfo aInfo, String parentShortComponentName, Object parentProc,
+            boolean aboveSystem, String reason);
+
+    /**
+     * Sends {@link android.content.Intent#ACTION_CONFIGURATION_CHANGED} with all the appropriate
+     * flags.
+     */
+    public abstract void broadcastGlobalConfigurationChanged(int changes, boolean initLocale);
+
+    /**
+     * Sends {@link android.content.Intent#ACTION_CLOSE_SYSTEM_DIALOGS} with all the appropriate
+     * flags.
+     */
+    public abstract void broadcastCloseSystemDialogs(String reason);
+
+    /**
+     * Kills all background processes, except those matching any of the specified properties.
+     *
+     * @param minTargetSdk the target SDK version at or above which to preserve processes,
+     *                     or {@code -1} to ignore the target SDK
+     * @param maxProcState the process state at or below which to preserve processes,
+     *                     or {@code -1} to ignore the process state
+     */
+    public abstract void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState);
+
+    /** Starts a given process. */
+    public abstract void startProcess(String processName, ApplicationInfo info,
+            boolean knownToBeDead, String hostingType, ComponentName hostingName);
+
+    /** Starts up the starting activity process for debugging if needed. */
+    public abstract void setDebugFlagsForStartingActivity(ActivityInfo aInfo, int startFlags,
+            ProfilerInfo profilerInfo);
 }
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 63c61d3..94b42ff 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -195,6 +195,13 @@
     private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId";
 
     /**
+     * See {@link #setPendingIntentLaunchFlags(int)}
+     * @hide
+     */
+    private static final String KEY_PENDING_INTENT_LAUNCH_FLAGS =
+            "android.activity.pendingIntentLaunchFlags";
+
+    /**
      * See {@link #setTaskOverlay}.
      * @hide
      */
@@ -309,6 +316,7 @@
     @WindowConfiguration.ActivityType
     private int mLaunchActivityType = ACTIVITY_TYPE_UNDEFINED;
     private int mLaunchTaskId = -1;
+    private int mPendingIntentLaunchFlags;
     private int mSplitScreenCreateMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
     private boolean mLockTaskMode = false;
     private boolean mDisallowEnterPictureInPictureWhileLaunching;
@@ -932,6 +940,7 @@
         mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED);
         mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED);
         mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
+        mPendingIntentLaunchFlags = opts.getInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, 0);
         mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false);
         mTaskOverlayCanResume = opts.getBoolean(KEY_TASK_OVERLAY_CAN_RESUME, false);
         mAvoidMoveToFront = opts.getBoolean(KEY_AVOID_MOVE_TO_FRONT, false);
@@ -1233,6 +1242,22 @@
     }
 
     /**
+     * Specifies intent flags to be applied for any activity started from a PendingIntent.
+     *
+     * @hide
+     */
+    public void setPendingIntentLaunchFlags(@android.content.Intent.Flags int flags) {
+        mPendingIntentLaunchFlags = flags;
+    }
+
+    /**
+     * @hide
+     */
+    public int getPendingIntentLaunchFlags() {
+        return mPendingIntentLaunchFlags;
+    }
+
+    /**
      * Set's whether the activity launched with this option should be a task overlay. That is the
      * activity will always be the top activity of the task.  If {@param canResume} is true, then
      * the task will also not be moved to the front of the stack.
@@ -1463,6 +1488,9 @@
         if (mLaunchTaskId != -1) {
             b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
         }
+        if (mPendingIntentLaunchFlags != 0) {
+            b.putInt(KEY_PENDING_INTENT_LAUNCH_FLAGS, mPendingIntentLaunchFlags);
+        }
         if (mTaskOverlay) {
             b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
         }
@@ -1501,7 +1529,7 @@
     }
 
     /**
-     * Ask the the system track that time the user spends in the app being launched, and
+     * Ask the system track that time the user spends in the app being launched, and
      * report it back once done.  The report will be sent to the given receiver, with
      * the extras {@link #EXTRA_USAGE_TIME_REPORT} and {@link #EXTRA_USAGE_TIME_REPORT_PACKAGES}
      * filled in.
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index af8aa4e..b8fe2f1 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -45,6 +45,12 @@
     public static final int INVALID_STACK_ID = -1;
 
     /**
+     * Invalid task ID.
+     * @hide
+     */
+    public static final int INVALID_TASK_ID = -1;
+
+    /**
      * Parameter to {@link IActivityTaskManager#setTaskWindowingModeSplitScreenPrimary} which
      * specifies the position of the created docked stack at the top half of the screen if
      * in portrait mode or at the left half of the screen if in landscape mode.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 6754df9..4756bf4 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1425,60 +1425,10 @@
             PrintWriter pw = new FastPrintWriter(
                     new FileOutputStream(pfd.getFileDescriptor()));
             PrintWriterPrinter printer = new PrintWriterPrinter(pw);
-            SQLiteDebug.dump(printer, args);
-
-            if (isSystem) {
-                dumpDatabaseFileSizes(pw, Environment.getDataSystemDirectory(), true);
-                dumpDatabaseFileSizes(pw, Environment.getDataSystemDeDirectory(), true);
-                dumpDatabaseFileSizes(pw, Environment.getDataSystemCeDirectory(), true);
-            } else {
-                Context context = getApplication();
-                if (context != null) {
-                    dumpDatabaseFileSizes(pw,
-                            getDatabasesDir(context.createDeviceProtectedStorageContext()),
-                            false);
-                    dumpDatabaseFileSizes(pw,
-                            getDatabasesDir(context.createCredentialProtectedStorageContext()),
-                            false);
-                }
-            }
+            SQLiteDebug.dump(printer, args, isSystem);
             pw.flush();
         }
 
-        private void dumpDatabaseFileSizes(PrintWriter pw, File dir, boolean isSystem) {
-            final File[] files = dir.listFiles();
-            if (files == null || files.length == 0) {
-                return;
-            }
-            Arrays.sort(files, (a, b) -> a.getName().compareTo(b.getName()));
-
-            boolean needHeader = true;
-            for (File f : files) {
-                if (isSystem) {
-                    // If it's the system server, the directory contains other files too, so
-                    // filter by file extensions.
-                    // (If it's an app, just print all files because they may not use *.db
-                    // extension.)
-                    final String name = f.getName();
-                    if (!(name.endsWith(".db") || name.endsWith(".db-wal")
-                            || name.endsWith(".db-journal"))) {
-                        continue;
-                    }
-                }
-                if (needHeader) {
-                    pw.println();
-                    pw.println("Database files in " + dir.getAbsolutePath() + ":");
-                    needHeader = false;
-                }
-
-                pw.print("  ");
-                pw.print(f.getName());
-                pw.print("  ");
-                pw.print(f.length());
-                pw.println(" bytes");
-            }
-        }
-
         @Override
         public void dumpDbInfo(final ParcelFileDescriptor pfd, final String[] args) {
             if (mSystemThread) {
@@ -5054,7 +5004,7 @@
     private void performConfigurationChangedForActivity(ActivityClientRecord r,
             Configuration newBaseConfig) {
         performConfigurationChangedForActivity(r, newBaseConfig,
-                r.activity.getDisplay().getDisplayId(), false /* movedToDifferentDisplay */);
+                r.activity.getDisplayId(), false /* movedToDifferentDisplay */);
     }
 
     /**
@@ -5406,7 +5356,7 @@
             return;
         }
         final boolean movedToDifferentDisplay = displayId != INVALID_DISPLAY
-                && displayId != r.activity.getDisplay().getDisplayId();
+                && displayId != r.activity.getDisplayId();
 
         // Perform updates.
         r.overrideConfig = overrideConfig;
@@ -5666,7 +5616,7 @@
             }
         }
 
-        GraphicsEnvironment.getInstance().setup(context);
+        GraphicsEnvironment.getInstance().setup(context, mCoreSettings);
         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     }
 
diff --git a/core/java/android/app/ActivityTransitionCoordinator.java b/core/java/android/app/ActivityTransitionCoordinator.java
index 9b2bfc5..4b87a64 100644
--- a/core/java/android/app/ActivityTransitionCoordinator.java
+++ b/core/java/android/app/ActivityTransitionCoordinator.java
@@ -193,6 +193,13 @@
      */
     public static final int MSG_SHARED_ELEMENT_DESTINATION = 107;
 
+    /**
+     * Sent by Activity#startActivity to notify the entering activity that enter animation for
+     * back is allowed. If this message is not received, the default exit animation will run when
+     * backing out of an activity (instead of the 'reverse' shared element transition).
+     */
+    public static final int MSG_ALLOW_RETURN_TRANSITION = 108;
+
     private Window mWindow;
     final protected ArrayList<String> mAllSharedElementNames;
     final protected ArrayList<View> mSharedElements = new ArrayList<View>();
@@ -346,8 +353,6 @@
         return new ArrayList<View>(mSharedElements);
     }
 
-    public ArrayList<String> getAllSharedElementNames() { return mAllSharedElementNames; }
-
     protected Transition setTargets(Transition transition, boolean add) {
         if (transition == null || (add &&
                 (mTransitioningViews == null || mTransitioningViews.isEmpty()))) {
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index b8f5a8e..3201feb 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -35,7 +35,7 @@
  */
 class ActivityTransitionState {
 
-    private static final String ENTERING_SHARED_ELEMENTS = "android:enteringSharedElements";
+    private static final String PENDING_EXIT_SHARED_ELEMENTS = "android:pendingExitSharedElements";
 
     private static final String EXITING_MAPPED_FROM = "android:exitingMappedFrom";
 
@@ -43,9 +43,9 @@
 
     /**
      * The shared elements that the calling Activity has said that they transferred to this
-     * Activity.
+     * Activity and will be transferred back during exit animation.
      */
-    private ArrayList<String> mEnteringNames;
+    private ArrayList<String> mPendingExitNames;
 
     /**
      * The names of shared elements that were shared to the called Activity.
@@ -112,8 +112,7 @@
 
     public int addExitTransitionCoordinator(ExitTransitionCoordinator exitTransitionCoordinator) {
         if (mExitTransitionCoordinators == null) {
-            mExitTransitionCoordinators =
-                    new SparseArray<WeakReference<ExitTransitionCoordinator>>();
+            mExitTransitionCoordinators = new SparseArray<>();
         }
         WeakReference<ExitTransitionCoordinator> ref = new WeakReference(exitTransitionCoordinator);
         // clean up old references:
@@ -132,7 +131,7 @@
     public void readState(Bundle bundle) {
         if (bundle != null) {
             if (mEnterTransitionCoordinator == null || mEnterTransitionCoordinator.isReturning()) {
-                mEnteringNames = bundle.getStringArrayList(ENTERING_SHARED_ELEMENTS);
+                mPendingExitNames = bundle.getStringArrayList(PENDING_EXIT_SHARED_ELEMENTS);
             }
             if (mEnterTransitionCoordinator == null) {
                 mExitingFrom = bundle.getStringArrayList(EXITING_MAPPED_FROM);
@@ -141,9 +140,21 @@
         }
     }
 
+    /**
+     * Returns the element names to be used for exit animation. It caches the list internally so
+     * that it is preserved through activty destroy and restore.
+     */
+    private ArrayList<String> getPendingExitNames() {
+        if (mPendingExitNames == null && mEnterTransitionCoordinator != null) {
+            mPendingExitNames = mEnterTransitionCoordinator.getPendingExitSharedElementNames();
+        }
+        return mPendingExitNames;
+    }
+
     public void saveState(Bundle bundle) {
-        if (mEnteringNames != null) {
-            bundle.putStringArrayList(ENTERING_SHARED_ELEMENTS, mEnteringNames);
+        ArrayList<String> pendingExitNames = getPendingExitNames();
+        if (pendingExitNames != null) {
+            bundle.putStringArrayList(PENDING_EXIT_SHARED_ELEMENTS, pendingExitNames);
         }
         if (mExitingFrom != null) {
             bundle.putStringArrayList(EXITING_MAPPED_FROM, mExitingFrom);
@@ -226,7 +237,7 @@
             }
         } else {
             mEnterTransitionCoordinator.namedViewsReady(null, null);
-            mEnteringNames = mEnterTransitionCoordinator.getAllSharedElementNames();
+            mPendingExitNames = null;
         }
 
         mExitingFrom = null;
@@ -268,7 +279,7 @@
     }
 
     public void clear() {
-        mEnteringNames = null;
+        mPendingExitNames = null;
         mExitingFrom = null;
         mExitingTo = null;
         mExitingToView = null;
@@ -296,7 +307,8 @@
     }
 
     public boolean startExitBackTransition(final Activity activity) {
-        if (mEnteringNames == null || mCalledExitCoordinator != null) {
+        ArrayList<String> pendingExitNames = getPendingExitNames();
+        if (pendingExitNames == null || mCalledExitCoordinator != null) {
             return false;
         } else {
             if (!mHasExited) {
@@ -315,7 +327,7 @@
                 }
 
                 mReturnExitCoordinator = new ExitTransitionCoordinator(activity,
-                        activity.getWindow(), activity.mEnterTransitionListener, mEnteringNames,
+                        activity.getWindow(), activity.mEnterTransitionListener, pendingExitNames,
                         null, null, true);
                 if (enterViewsTransition != null && decor != null) {
                     enterViewsTransition.resume(decor);
diff --git a/core/java/android/app/AppDetailsActivity.java b/core/java/android/app/AppDetailsActivity.java
new file mode 100644
index 0000000..cd36e63
--- /dev/null
+++ b/core/java/android/app/AppDetailsActivity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+package android.app;
+
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * Helper activity that forwards you to app details page.
+ *
+ * @hide
+ */
+public class AppDetailsActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+        intent.setData(android.net.Uri.fromParts("package", getPackageName(), null));
+        startActivity(intent);
+        finish();
+    }
+}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 9c47e79..3b05566 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -431,9 +431,11 @@
     public static final int OP_BLUETOOTH_SCAN = 77;
     /** @hide Use the BiometricPrompt/BiometricManager APIs. */
     public static final int OP_USE_BIOMETRIC = 78;
+    /** @hide Physical activity recognition. */
+    public static final int OP_ACTIVITY_RECOGNITION = 79;
     /** @hide */
     @UnsupportedAppUsage
-    public static final int _NUM_OP = 79;
+    public static final int _NUM_OP = 80;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -681,6 +683,9 @@
     /** @hide Use the BiometricPrompt/BiometricManager APIs. */
     public static final String OPSTR_USE_BIOMETRIC = "android:use_biometric";
 
+    /** @hide Recognize physical activity. */
+    public static final String OPSTR_ACTIVITY_RECOGNITION = "android:activity_recognition";
+
     // Warning: If an permission is added here it also has to be added to
     // com.android.packageinstaller.permission.utils.EventLogger
     private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
@@ -722,6 +727,8 @@
             OP_CAMERA,
             // Body sensors
             OP_BODY_SENSORS,
+            // Activity recognition
+            OP_ACTIVITY_RECOGNITION,
 
             // APPOP PERMISSIONS
             OP_ACCESS_NOTIFICATIONS,
@@ -819,6 +826,7 @@
             OP_START_FOREGROUND,                // START_FOREGROUND
             OP_COARSE_LOCATION,                 // BLUETOOTH_SCAN
             OP_USE_BIOMETRIC,                   // BIOMETRIC
+            OP_ACTIVITY_RECOGNITION,            // ACTIVITY_RECOGNITION
     };
 
     /**
@@ -904,6 +912,7 @@
             OPSTR_START_FOREGROUND,
             OPSTR_BLUETOOTH_SCAN,
             OPSTR_USE_BIOMETRIC,
+            OPSTR_ACTIVITY_RECOGNITION,
     };
 
     /**
@@ -990,6 +999,7 @@
             "START_FOREGROUND",
             "BLUETOOTH_SCAN",
             "USE_BIOMETRIC",
+            "ACTIVITY_RECOGNITION",
     };
 
     /**
@@ -1077,6 +1087,7 @@
             Manifest.permission.FOREGROUND_SERVICE,
             null, // no permission for OP_BLUETOOTH_SCAN
             Manifest.permission.USE_BIOMETRIC,
+            Manifest.permission.ACTIVITY_RECOGNITION,
     };
 
     /**
@@ -1164,6 +1175,7 @@
             null, // START_FOREGROUND
             null, // maybe should be UserManager.DISALLOW_SHARE_LOCATION, //BLUETOOTH_SCAN
             null, // USE_BIOMETRIC
+            null, // ACTIVITY_RECOGNITION
     };
 
     /**
@@ -1250,91 +1262,93 @@
             false, // START_FOREGROUND
             true, // BLUETOOTH_SCAN
             false, // USE_BIOMETRIC
+            false, // ACTIVITY_RECOGNITION
     };
 
     /**
      * This specifies the default mode for each operation.
      */
     private static int[] sOpDefaultMode = new int[] {
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_IGNORED, // OP_WRITE_SMS
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_DEFAULT, // OP_WRITE_SETTINGS
-            AppOpsManager.MODE_DEFAULT, // OP_SYSTEM_ALERT_WINDOW
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA
-            AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ERRORED,  // OP_MOCK_LOCATION
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,  // OP_TURN_ON_SCREEN
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_ALLOWED,  // OP_RUN_IN_BACKGROUND
-            AppOpsManager.MODE_ALLOWED,  // OP_AUDIO_ACCESSIBILITY_VOLUME
-            AppOpsManager.MODE_ALLOWED,
-            AppOpsManager.MODE_DEFAULT,  // OP_REQUEST_INSTALL_PACKAGES
-            AppOpsManager.MODE_ALLOWED,  // OP_PICTURE_IN_PICTURE
-            AppOpsManager.MODE_DEFAULT,  // OP_INSTANT_APP_START_FOREGROUND
-            AppOpsManager.MODE_ALLOWED,  // ANSWER_PHONE_CALLS
-            AppOpsManager.MODE_ALLOWED,  // OP_RUN_ANY_IN_BACKGROUND
-            AppOpsManager.MODE_ALLOWED,  // OP_CHANGE_WIFI_STATE
-            AppOpsManager.MODE_ALLOWED,  // REQUEST_DELETE_PACKAGES
-            AppOpsManager.MODE_ALLOWED,  // OP_BIND_ACCESSIBILITY_SERVICE
-            AppOpsManager.MODE_ALLOWED,  // ACCEPT_HANDOVER
-            AppOpsManager.MODE_ERRORED,  // MANAGE_IPSEC_TUNNELS
-            AppOpsManager.MODE_ALLOWED,  // OP_START_FOREGROUND
-            AppOpsManager.MODE_ALLOWED,  // OP_BLUETOOTH_SCAN
-            AppOpsManager.MODE_ALLOWED,  // USE_BIOMETRIC
+            AppOpsManager.MODE_ALLOWED, // COARSE_LOCATION
+            AppOpsManager.MODE_ALLOWED, // FINE_LOCATION
+            AppOpsManager.MODE_ALLOWED, // GPS
+            AppOpsManager.MODE_ALLOWED, // VIBRATE
+            AppOpsManager.MODE_ALLOWED, // READ_CONTACTS
+            AppOpsManager.MODE_ALLOWED, // WRITE_CONTACTS
+            AppOpsManager.MODE_ALLOWED, // READ_CALL_LOG
+            AppOpsManager.MODE_ALLOWED, // WRITE_CALL_LOG
+            AppOpsManager.MODE_ALLOWED, // READ_CALENDAR
+            AppOpsManager.MODE_ALLOWED, // WRITE_CALENDAR
+            AppOpsManager.MODE_ALLOWED, // WIFI_SCAN
+            AppOpsManager.MODE_ALLOWED, // POST_NOTIFICATION
+            AppOpsManager.MODE_ALLOWED, // NEIGHBORING_CELLS
+            AppOpsManager.MODE_ALLOWED, // CALL_PHONE
+            AppOpsManager.MODE_ALLOWED, // READ_SMS
+            AppOpsManager.MODE_IGNORED, // WRITE_SMS
+            AppOpsManager.MODE_DEFAULT, // RECEIVE_SMS
+            AppOpsManager.MODE_ALLOWED, // RECEIVE_EMERGENCY_BROADCAST
+            AppOpsManager.MODE_ALLOWED, // RECEIVE_MMS
+            AppOpsManager.MODE_DEFAULT, // RECEIVE_WAP_PUSH
+            AppOpsManager.MODE_DEFAULT, // SEND_SMS
+            AppOpsManager.MODE_ALLOWED, // READ_ICC_SMS
+            AppOpsManager.MODE_ALLOWED, // WRITE_ICC_SMS
+            AppOpsManager.MODE_DEFAULT, // WRITE_SETTINGS
+            AppOpsManager.MODE_DEFAULT, // SYSTEM_ALERT_WINDOW
+            AppOpsManager.MODE_ALLOWED, // ACCESS_NOTIFICATIONS
+            AppOpsManager.MODE_ALLOWED, // CAMERA
+            AppOpsManager.MODE_ALLOWED, // RECORD_AUDIO
+            AppOpsManager.MODE_ALLOWED, // PLAY_AUDIO
+            AppOpsManager.MODE_ALLOWED, // READ_CLIPBOARD
+            AppOpsManager.MODE_ALLOWED, // WRITE_CLIPBOARD
+            AppOpsManager.MODE_ALLOWED, // TAKE_MEDIA_BUTTONS
+            AppOpsManager.MODE_ALLOWED, // TAKE_AUDIO_FOCUS
+            AppOpsManager.MODE_ALLOWED, // AUDIO_MASTER_VOLUME
+            AppOpsManager.MODE_ALLOWED, // AUDIO_VOICE_VOLUME
+            AppOpsManager.MODE_ALLOWED, // AUDIO_RING_VOLUME
+            AppOpsManager.MODE_ALLOWED, // AUDIO_MEDIA_VOLUME
+            AppOpsManager.MODE_ALLOWED, // AUDIO_ALARM_VOLUME
+            AppOpsManager.MODE_ALLOWED, // AUDIO_NOTIFICATION_VOLUME
+            AppOpsManager.MODE_ALLOWED, // AUDIO_BLUETOOTH_VOLUME
+            AppOpsManager.MODE_ALLOWED, // WAKE_LOCK
+            AppOpsManager.MODE_ALLOWED, // MONITOR_LOCATION
+            AppOpsManager.MODE_ALLOWED, // MONITOR_HIGH_POWER_LOCATION
+            AppOpsManager.MODE_DEFAULT, // GET_USAGE_STATS
+            AppOpsManager.MODE_ALLOWED, // MUTE_MICROPHONE
+            AppOpsManager.MODE_ALLOWED, // TOAST_WINDOW
+            AppOpsManager.MODE_IGNORED, // PROJECT_MEDIA
+            AppOpsManager.MODE_IGNORED, // ACTIVATE_VPN
+            AppOpsManager.MODE_ALLOWED, // WRITE_WALLPAPER
+            AppOpsManager.MODE_ALLOWED, // ASSIST_STRUCTURE
+            AppOpsManager.MODE_ALLOWED, // ASSIST_SCREENSHOT
+            AppOpsManager.MODE_ALLOWED, // READ_PHONE_STATE
+            AppOpsManager.MODE_ALLOWED, // ADD_VOICEMAIL
+            AppOpsManager.MODE_ALLOWED, // USE_SIP
+            AppOpsManager.MODE_ALLOWED, // PROCESS_OUTGOING_CALLS
+            AppOpsManager.MODE_ALLOWED, // USE_FINGERPRINT
+            AppOpsManager.MODE_ALLOWED, // BODY_SENSORS
+            AppOpsManager.MODE_DEFAULT, // READ_CELL_BROADCASTS
+            AppOpsManager.MODE_ERRORED, // MOCK_LOCATION
+            AppOpsManager.MODE_ALLOWED, // READ_EXTERNAL_STORAGE
+            AppOpsManager.MODE_ALLOWED, // WRITE_EXTERNAL_STORAGE
+            AppOpsManager.MODE_ALLOWED, // TURN_SCREEN_ON
+            AppOpsManager.MODE_ALLOWED, // GET_ACCOUNTS
+            AppOpsManager.MODE_ALLOWED, // RUN_IN_BACKGROUND
+            AppOpsManager.MODE_ALLOWED, // AUDIO_ACCESSIBILITY_VOLUME
+            AppOpsManager.MODE_ALLOWED, // READ_PHONE_NUMBERS
+            AppOpsManager.MODE_DEFAULT, // REQUEST_INSTALL_PACKAGES
+            AppOpsManager.MODE_ALLOWED, // PICTURE_IN_PICTURE
+            AppOpsManager.MODE_DEFAULT, // INSTANT_APP_START_FOREGROUND
+            AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
+            AppOpsManager.MODE_ALLOWED, // RUN_ANY_IN_BACKGROUND
+            AppOpsManager.MODE_ALLOWED, // CHANGE_WIFI_STATE
+            AppOpsManager.MODE_ALLOWED, // REQUEST_DELETE_PACKAGES
+            AppOpsManager.MODE_ALLOWED, // BIND_ACCESSIBILITY_SERVICE
+            AppOpsManager.MODE_ALLOWED, // ACCEPT_HANDOVER
+            AppOpsManager.MODE_ERRORED, // MANAGE_IPSEC_TUNNELS
+            AppOpsManager.MODE_ALLOWED, // START_FOREGROUND
+            AppOpsManager.MODE_ALLOWED, // BLUETOOTH_SCAN
+            AppOpsManager.MODE_ALLOWED, // USE_BIOMETRIC
+            AppOpsManager.MODE_ALLOWED, // ACTIVITY_RECOGNITION
     };
 
     /**
@@ -1345,85 +1359,86 @@
      * for whichever app is selected as the current SMS app).
      */
     private static boolean[] sOpDisableReset = new boolean[] {
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            true,      // OP_WRITE_SMS
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false,
-            false, // OP_AUDIO_ACCESSIBILITY_VOLUME
-            false,
-            false, // OP_REQUEST_INSTALL_PACKAGES
-            false, // OP_PICTURE_IN_PICTURE
-            false,
+            false, // COARSE_LOCATION
+            false, // FINE_LOCATION
+            false, // GPS
+            false, // VIBRATE
+            false, // READ_CONTACTS
+            false, // WRITE_CONTACTS
+            false, // READ_CALL_LOG
+            false, // WRITE_CALL_LOG
+            false, // READ_CALENDAR
+            false, // WRITE_CALENDAR
+            false, // WIFI_SCAN
+            false, // POST_NOTIFICATION
+            false, // NEIGHBORING_CELLS
+            false, // CALL_PHONE
+            true, // READ_SMS
+            true, // WRITE_SMS
+            true, // RECEIVE_SMS
+            false, // RECEIVE_EMERGENCY_BROADCAST
+            false, // RECEIVE_MMS
+            true, // RECEIVE_WAP_PUSH
+            true, // SEND_SMS
+            false, // READ_ICC_SMS
+            false, // WRITE_ICC_SMS
+            false, // WRITE_SETTINGS
+            false, // SYSTEM_ALERT_WINDOW
+            false, // ACCESS_NOTIFICATIONS
+            false, // CAMERA
+            false, // RECORD_AUDIO
+            false, // PLAY_AUDIO
+            false, // READ_CLIPBOARD
+            false, // WRITE_CLIPBOARD
+            false, // TAKE_MEDIA_BUTTONS
+            false, // TAKE_AUDIO_FOCUS
+            false, // AUDIO_MASTER_VOLUME
+            false, // AUDIO_VOICE_VOLUME
+            false, // AUDIO_RING_VOLUME
+            false, // AUDIO_MEDIA_VOLUME
+            false, // AUDIO_ALARM_VOLUME
+            false, // AUDIO_NOTIFICATION_VOLUME
+            false, // AUDIO_BLUETOOTH_VOLUME
+            false, // WAKE_LOCK
+            false, // MONITOR_LOCATION
+            false, // MONITOR_HIGH_POWER_LOCATION
+            false, // GET_USAGE_STATS
+            false, // MUTE_MICROPHONE
+            false, // TOAST_WINDOW
+            false, // PROJECT_MEDIA
+            false, // ACTIVATE_VPN
+            false, // WRITE_WALLPAPER
+            false, // ASSIST_STRUCTURE
+            false, // ASSIST_SCREENSHOT
+            false, // READ_PHONE_STATE
+            false, // ADD_VOICEMAIL
+            false, // USE_SIP
+            false, // PROCESS_OUTGOING_CALLS
+            false, // USE_FINGERPRINT
+            false, // BODY_SENSORS
+            true, // READ_CELL_BROADCASTS
+            false, // MOCK_LOCATION
+            false, // READ_EXTERNAL_STORAGE
+            false, // WRITE_EXTERNAL_STORAGE
+            false, // TURN_SCREEN_ON
+            false, // GET_ACCOUNTS
+            false, // RUN_IN_BACKGROUND
+            false, // AUDIO_ACCESSIBILITY_VOLUME
+            false, // READ_PHONE_NUMBERS
+            false, // REQUEST_INSTALL_PACKAGES
+            false, // PICTURE_IN_PICTURE
+            false, // INSTANT_APP_START_FOREGROUND
             false, // ANSWER_PHONE_CALLS
-            false, // OP_RUN_ANY_IN_BACKGROUND
-            false, // OP_CHANGE_WIFI_STATE
-            false, // OP_REQUEST_DELETE_PACKAGES
-            false, // OP_BIND_ACCESSIBILITY_SERVICE
+            false, // RUN_ANY_IN_BACKGROUND
+            false, // CHANGE_WIFI_STATE
+            false, // REQUEST_DELETE_PACKAGES
+            false, // BIND_ACCESSIBILITY_SERVICE
             false, // ACCEPT_HANDOVER
             false, // MANAGE_IPSEC_TUNNELS
             false, // START_FOREGROUND
             false, // BLUETOOTH_SCAN
             false, // USE_BIOMETRIC
+            false, // ACTIVITY_RECOGNITION
     };
 
     /**
@@ -1957,6 +1972,7 @@
      * @hide
      */
     @SystemApi
+    @TestApi
     @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
     public void setUidMode(String appOp, int uid, int mode) {
         try {
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 264029b..fcd9a05 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -55,6 +55,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.SharedLibraryInfo;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VersionedPackage;
 import android.content.pm.dex.ArtManager;
@@ -85,6 +86,7 @@
 import android.system.Os;
 import android.system.OsConstants;
 import android.system.StructStat;
+import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.IconDrawableFactory;
 import android.util.LauncherIcons;
@@ -2255,9 +2257,19 @@
     public String[] setPackagesSuspended(String[] packageNames, boolean suspended,
             PersistableBundle appExtras, PersistableBundle launcherExtras,
             String dialogMessage) {
+        final SuspendDialogInfo dialogInfo = !TextUtils.isEmpty(dialogMessage)
+                ? new SuspendDialogInfo.Builder().setMessage(dialogMessage).build()
+                : null;
+        return setPackagesSuspended(packageNames, suspended, appExtras, launcherExtras, dialogInfo);
+    }
+
+    @Override
+    public String[] setPackagesSuspended(String[] packageNames, boolean suspended,
+            PersistableBundle appExtras, PersistableBundle launcherExtras,
+            SuspendDialogInfo dialogInfo) {
         try {
             return mPM.setPackagesSuspendedAsUser(packageNames, suspended, appExtras,
-                    launcherExtras, dialogMessage, mContext.getOpPackageName(),
+                    launcherExtras, dialogInfo, mContext.getOpPackageName(),
                     getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 77f6395..dc707e8 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2088,8 +2088,7 @@
             ContextImpl c = new ContextImpl(this, mMainThread, pi, null, mActivityToken,
                     new UserHandle(UserHandle.getUserId(application.uid)), flags, null);
 
-            final int displayId = mDisplay != null
-                    ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+            final int displayId = getDisplayId();
 
             c.setResources(createResources(mActivityToken, pi, null, displayId, null,
                     getDisplayAdjustments(displayId).getCompatibilityInfo()));
@@ -2124,8 +2123,7 @@
             ContextImpl c = new ContextImpl(this, mMainThread, pi, null, mActivityToken, user,
                     flags, null);
 
-            final int displayId = mDisplay != null
-                    ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+            final int displayId = getDisplayId();
 
             c.setResources(createResources(mActivityToken, pi, null, displayId, null,
                     getDisplayAdjustments(displayId).getCompatibilityInfo()));
@@ -2152,8 +2150,7 @@
         final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, splitName,
                 mActivityToken, mUser, mFlags, classLoader);
 
-        final int displayId = mDisplay != null
-                ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+        final int displayId = getDisplayId();
 
         context.setResources(ResourcesManager.getInstance().getResources(
                 mActivityToken,
@@ -2177,7 +2174,7 @@
         ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mSplitName,
                 mActivityToken, mUser, mFlags, mClassLoader);
 
-        final int displayId = mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+        final int displayId = getDisplayId();
         context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId,
                 overrideConfiguration, getDisplayAdjustments(displayId).getCompatibilityInfo()));
         return context;
@@ -2250,6 +2247,11 @@
     }
 
     @Override
+    public int getDisplayId() {
+        return mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
+    }
+
+    @Override
     public void updateDisplay(int displayId) {
         mDisplay = mResourcesManager.getAdjustedDisplay(displayId, mResources);
     }
diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java
index ab847fd..bce243c 100644
--- a/core/java/android/app/EnterTransitionCoordinator.java
+++ b/core/java/android/app/EnterTransitionCoordinator.java
@@ -65,6 +65,7 @@
     private OneShotPreDrawListener mViewsReadyListener;
     private final boolean mIsCrossTask;
     private Drawable mReplacedBackground;
+    private ArrayList<String> mPendingExitNames;
 
     public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
             ArrayList<String> sharedElementNames, boolean isReturning, boolean isCrossTask) {
@@ -249,6 +250,11 @@
             case MSG_CANCEL:
                 cancel();
                 break;
+            case MSG_ALLOW_RETURN_TRANSITION:
+                if (!mIsCanceled) {
+                    mPendingExitNames = mAllSharedElementNames;
+                }
+                break;
         }
     }
 
@@ -256,6 +262,10 @@
         return mIsReturning && mResultReceiver != null;
     }
 
+    public ArrayList<String> getPendingExitSharedElementNames() {
+        return mPendingExitNames;
+    }
+
     /**
      * This is called onResume. If an Activity is resuming and the transitions
      * haven't started yet, force the views to appear. This is likely to be
diff --git a/core/java/android/app/ExitTransitionCoordinator.java b/core/java/android/app/ExitTransitionCoordinator.java
index df31da9..48a711e 100644
--- a/core/java/android/app/ExitTransitionCoordinator.java
+++ b/core/java/android/app/ExitTransitionCoordinator.java
@@ -433,6 +433,11 @@
             if (!mSharedElementNotified) {
                 mSharedElementNotified = true;
                 delayCancel();
+
+                if (!mActivity.isTopOfTask()) {
+                    mResultReceiver.send(MSG_ALLOW_RETURN_TRANSITION, null);
+                }
+
                 if (mListener == null) {
                     mResultReceiver.send(MSG_TAKE_SHARED_ELEMENTS, mSharedElementBundle);
                     notifyExitComplete();
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 49917b4..dbc4e34 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -2259,7 +2259,7 @@
     }
 
     /**
-     * Sets whether the the exit transition and enter transition overlap or not.
+     * Sets whether the exit transition and enter transition overlap or not.
      * When true, the enter transition will start as soon as possible. When false, the
      * enter transition will wait until the exit transition completes before starting.
      *
@@ -2272,7 +2272,7 @@
     }
 
     /**
-     * Returns whether the the exit transition and enter transition overlap or not.
+     * Returns whether the exit transition and enter transition overlap or not.
      * When true, the enter transition will start as soon as possible. When false, the
      * enter transition will wait until the exit transition completes before starting.
      *
@@ -2286,7 +2286,7 @@
     }
 
     /**
-     * Sets whether the the return transition and reenter transition overlap or not.
+     * Sets whether the return transition and reenter transition overlap or not.
      * When true, the reenter transition will start as soon as possible. When false, the
      * reenter transition will wait until the return transition completes before starting.
      *
@@ -2299,7 +2299,7 @@
     }
 
     /**
-     * Returns whether the the return transition and reenter transition overlap or not.
+     * Returns whether the return transition and reenter transition overlap or not.
      * When true, the reenter transition will start as soon as possible. When false, the
      * reenter transition will wait until the return transition completes before starting.
      *
diff --git a/core/java/android/app/FragmentHostCallback.java b/core/java/android/app/FragmentHostCallback.java
index 1a12fdc..26b4a11 100644
--- a/core/java/android/app/FragmentHostCallback.java
+++ b/core/java/android/app/FragmentHostCallback.java
@@ -53,7 +53,7 @@
     private ArrayMap<String, LoaderManager> mAllLoaderManagers;
     /** Whether or not fragment loaders should retain their state */
     private boolean mRetainLoaders;
-    /** The loader manger for the fragment host [i.e. Activity#getLoaderManager()] */
+    /** The loader manager for the fragment host [i.e. Activity#getLoaderManager()] */
     private LoaderManagerImpl mLoaderManager;
     private boolean mCheckedForLoaderManager;
     /** Whether or not the fragment host loader manager was started */
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index ceb828b..0e428ae 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -1013,6 +1013,11 @@
                     replaceTargets(sharedElementTransition, sharedElementsIn, null);
                 }
             }
+
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                transition.removeListener(this);
+            }
         });
     }
 
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 34c2282..1144e26 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1760,7 +1760,7 @@
     /**
      * Like {@link #execStartActivity(android.content.Context, android.os.IBinder,
      * android.os.IBinder, String, android.content.Intent, int, android.os.Bundle)},
-     * but for calls from a {#link Fragment}.
+     * but for calls from a {@link Fragment}.
      * 
      * @param who The Context from which the activity is being started.
      * @param contextThread The main thread of the Context from which the activity
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index b720df8..853fccf 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -561,7 +561,7 @@
      * This will, if the keyguard is secure, bring up the unlock screen of
      * the keyguard.
      *
-     * @param callback Let's you know whether the operation was succesful and
+     * @param callback Lets you know whether the operation was successful and
      *   it is safe to launch anything that would normally be considered safe
      *   once the user has gotten past the keyguard.
      */
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 81df447..4f41da6 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -20,6 +20,7 @@
 
 import android.annotation.ColorInt;
 import android.annotation.DrawableRes;
+import android.annotation.IdRes;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -37,6 +38,7 @@
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -68,6 +70,7 @@
 import android.text.style.TextAppearanceSpan;
 import android.util.ArraySet;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 import android.util.proto.ProtoOutputStream;
 import android.view.Gravity;
@@ -3129,6 +3132,37 @@
         return false;
     }
 
+
+    /**
+     * Finds and returns a remote input and its corresponding action.
+     *
+     * @param requiresFreeform requires the remoteinput to allow freeform or not.
+     * @return the result pair, {@code null} if no result is found.
+     *
+     * @hide
+     */
+    @Nullable
+    public Pair<RemoteInput, Action> findRemoteInputActionPair(boolean requiresFreeform) {
+        if (actions == null) {
+            return null;
+        }
+        for (Notification.Action action : actions) {
+            if (action.getRemoteInputs() == null) {
+                continue;
+            }
+            RemoteInput resultRemoteInput = null;
+            for (RemoteInput remoteInput : action.getRemoteInputs()) {
+                if (remoteInput.getAllowFreeFormInput() || !requiresFreeform) {
+                    resultRemoteInput = remoteInput;
+                }
+            }
+            if (resultRemoteInput != null) {
+                return Pair.create(resultRemoteInput, action);
+            }
+        }
+        return null;
+    }
+
     /**
      * Builder class for {@link Notification} objects.
      *
@@ -6203,7 +6237,7 @@
         public abstract boolean areNotificationsVisiblyDifferent(Style other);
 
         /**
-         * @return the the text that should be displayed in the statusBar when heads-upped.
+         * @return the text that should be displayed in the statusBar when heads-upped.
          * If {@code null} is returned, the default implementation will be used.
          *
          * @hide
@@ -6690,7 +6724,7 @@
         }
 
         /**
-         * @return the the text that should be displayed in the statusBar when heads upped.
+         * @return the text that should be displayed in the statusBar when heads upped.
          * If {@code null} is returned, the default implementation will be used.
          *
          * @hide
@@ -7346,7 +7380,7 @@
             }
 
             /**
-             * Get the the Uri pointing to the content of the message. Can be null, in which case
+             * Get the Uri pointing to the content of the message. Can be null, in which case
              * {@see #getText()} is used.
              */
             public Uri getDataUri() {
@@ -7727,8 +7761,17 @@
      * @see Notification.Builder#setColorized(boolean)
      */
     public static class MediaStyle extends Style {
+        // Changing max media buttons requires also changing templates
+        // (notification_template_material_media and notification_template_material_big_media).
         static final int MAX_MEDIA_BUTTONS_IN_COMPACT = 3;
         static final int MAX_MEDIA_BUTTONS = 5;
+        @IdRes private static final int[] MEDIA_BUTTON_IDS = {
+                R.id.action0,
+                R.id.action1,
+                R.id.action2,
+                R.id.action3,
+                R.id.action4,
+        };
 
         private int[] mActionsToShowInCompact = null;
         private MediaSession.Token mToken;
@@ -7842,15 +7885,16 @@
             return false;
         }
 
-        private RemoteViews generateMediaActionButton(Action action, int color) {
+        private void bindMediaActionButton(RemoteViews container, @IdRes int buttonId,
+                Action action, int color) {
             final boolean tombstone = (action.actionIntent == null);
-            RemoteViews button = new BuilderRemoteViews(mBuilder.mContext.getApplicationInfo(),
-                    R.layout.notification_material_media_action);
-            button.setImageViewIcon(R.id.action0, action.getIcon());
+            container.setViewVisibility(buttonId, View.VISIBLE);
+            container.setImageViewIcon(buttonId, action.getIcon());
 
             // If the action buttons should not be tinted, then just use the default
             // notification color. Otherwise, just use the passed-in color.
-            Configuration currentConfig = mBuilder.mContext.getResources().getConfiguration();
+            Resources resources = mBuilder.mContext.getResources();
+            Configuration currentConfig = resources.getConfiguration();
             boolean inNightMode = (currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
                     == Configuration.UI_MODE_NIGHT_YES;
             int tintColor = mBuilder.shouldTintActionButtons() || mBuilder.isColorized()
@@ -7858,13 +7902,21 @@
                     : ContrastColorUtil.resolveColor(mBuilder.mContext,
                             Notification.COLOR_DEFAULT, inNightMode);
 
-            button.setDrawableTint(R.id.action0, false, tintColor,
+            container.setDrawableTint(buttonId, false, tintColor,
                     PorterDuff.Mode.SRC_ATOP);
+
+            final TypedArray typedArray = mBuilder.mContext.obtainStyledAttributes(
+                    new int[]{ android.R.attr.colorControlHighlight });
+            int rippleAlpha = Color.alpha(typedArray.getColor(0, 0));
+            typedArray.recycle();
+            int rippleColor = Color.argb(rippleAlpha, Color.red(tintColor), Color.green(tintColor),
+                    Color.blue(tintColor));
+            container.setRippleDrawableColor(buttonId, ColorStateList.valueOf(rippleColor));
+
             if (!tombstone) {
-                button.setOnClickPendingIntent(R.id.action0, action.actionIntent);
+                container.setOnClickPendingIntent(buttonId, action.actionIntent);
             }
-            button.setContentDescription(R.id.action0, action.title);
-            return button;
+            container.setContentDescription(buttonId, action.title);
         }
 
         private RemoteViews makeMediaContentView() {
@@ -7873,21 +7925,20 @@
                     null /* result */);
 
             final int numActions = mBuilder.mActions.size();
-            final int N = mActionsToShowInCompact == null
+            final int numActionsToShow = mActionsToShowInCompact == null
                     ? 0
                     : Math.min(mActionsToShowInCompact.length, MAX_MEDIA_BUTTONS_IN_COMPACT);
-            view.removeAllViews(com.android.internal.R.id.media_actions);
-            if (N > 0) {
-                for (int i = 0; i < N; i++) {
-                    if (i >= numActions) {
-                        throw new IllegalArgumentException(String.format(
-                                "setShowActionsInCompactView: action %d out of bounds (max %d)",
-                                i, numActions - 1));
-                    }
-
+            if (numActionsToShow > numActions) {
+                throw new IllegalArgumentException(String.format(
+                        "setShowActionsInCompactView: action %d out of bounds (max %d)",
+                        numActions, numActions - 1));
+            }
+            for (int i = 0; i < MAX_MEDIA_BUTTONS_IN_COMPACT; i++) {
+                if (i < numActionsToShow) {
                     final Action action = mBuilder.mActions.get(mActionsToShowInCompact[i]);
-                    final RemoteViews button = generateMediaActionButton(action, getActionColor());
-                    view.addView(com.android.internal.R.id.media_actions, button);
+                    bindMediaActionButton(view, MEDIA_BUTTON_IDS[i], action, getActionColor());
+                } else {
+                    view.setViewVisibility(MEDIA_BUTTON_IDS[i], View.GONE);
                 }
             }
             handleImage(view);
@@ -7917,12 +7968,12 @@
             RemoteViews big = mBuilder.applyStandardTemplate(
                     R.layout.notification_template_material_big_media, false, null /* result */);
 
-            if (actionCount > 0) {
-                big.removeAllViews(com.android.internal.R.id.media_actions);
-                for (int i = 0; i < actionCount; i++) {
-                    final RemoteViews button = generateMediaActionButton(mBuilder.mActions.get(i),
+            for (int i = 0; i < MAX_MEDIA_BUTTONS; i++) {
+                if (i < actionCount) {
+                    bindMediaActionButton(big, MEDIA_BUTTON_IDS[i], mBuilder.mActions.get(i),
                             getActionColor());
-                    big.addView(com.android.internal.R.id.media_actions, button);
+                } else {
+                    big.setViewVisibility(MEDIA_BUTTON_IDS[i], View.GONE);
                 }
             }
             handleImage(big);
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 848def6..9f93e17 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -603,9 +603,10 @@
     }
 
     /**
-     * @hide
+     * 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.
      */
-    public boolean isImportanceLocked() {
+    public boolean hasUserSetImportance() {
         return (mUserLockedFields & USER_LOCKED_IMPORTANCE) != 0;
     }
 
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 07a8504..3f07024 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -48,6 +48,7 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -722,10 +723,15 @@
     public List<NotificationChannelGroup> getNotificationChannelGroups() {
         INotificationManager service = getService();
         try {
-            return service.getNotificationChannelGroups(mContext.getPackageName()).getList();
+            final ParceledListSlice<NotificationChannelGroup> parceledList =
+                    service.getNotificationChannelGroups(mContext.getPackageName());
+            if (parceledList != null) {
+                return parceledList.getList();
+            }
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
+        return new ArrayList<>();
     }
 
     /**
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 9539f34..acca6fc 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -169,7 +169,7 @@
      * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
      * {@link android.content.Intent#getStringExtra content.Intent.getStringExtra()}
      * to obtain the action message that was defined for a particular search action key and/or
-     * suggestion.  It will be null if the search was launched by typing "enter", touched the the
+     * suggestion.  It will be null if the search was launched by typing "enter", touching the
      * "GO" button, or other means not involving any action key.
      */
     public final static String ACTION_MSG = "action_msg";
@@ -404,7 +404,7 @@
      * Column name for suggestions cursor. <i>Optional.</i>  If your content is rentable, you
      * should provide this column to specify the displayable string representation of the rental
      * price of your content including the currency and the amount. If it's free, you should
-     * provide localized string to specify that it's free. This column can be ommitted if the
+     * provide localized string to specify that it's free. This column can be omitted if the
      * content is not applicable to rent.
      */
     public final static String SUGGEST_COLUMN_RENTAL_PRICE = "suggest_rental_price";
@@ -579,7 +579,7 @@
      *
      * @param initialQuery A search string can be pre-entered here, but this
      * is typically null or empty.
-     * @param selectInitialQuery If true, the intial query will be preselected, which means that
+     * @param selectInitialQuery If true, the initial query will be preselected, which means that
      * any further typing will replace it.  This is useful for cases where an entire pre-formed
      * query is being inserted.  If false, the selection point will be placed at the end of the
      * inserted query.  This is useful when the inserted query is text that the user entered,
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 67acfe9..16f6bda 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -21,13 +21,13 @@
 import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentCallbacks2;
 import android.content.ComponentName;
-import android.content.Intent;
-import android.content.ContextWrapper;
 import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
 import android.content.res.Configuration;
 import android.os.Build;
-import android.os.RemoteException;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.util.Log;
 
 import java.io.FileDescriptor;
@@ -391,7 +391,7 @@
      * don't recreate until a future explicit call to
      * {@link Context#startService Context.startService(Intent)}.  The
      * service will not receive a {@link #onStartCommand(Intent, int, int)}
-     * call with a null Intent because it will not be re-started if there
+     * call with a null Intent because it will not be restarted if there
      * are no pending Intents to deliver.
      * 
      * <p>This mode makes sense for things that want to do some work as a
@@ -416,7 +416,7 @@
      * redelivery until the service calls {@link #stopSelf(int)} with the
      * start ID provided to {@link #onStartCommand}.  The
      * service will not receive a {@link #onStartCommand(Intent, int, int)}
-     * call with a null Intent because it will will only be re-started if
+     * call with a null Intent because it will only be restarted if
      * it is not finished processing all Intents sent to it (and any such
      * pending events will be delivered at the point of restart).
      */
diff --git a/core/java/android/app/SmsAppService.java b/core/java/android/app/SmsAppService.java
index 3f2b025..3829d71 100644
--- a/core/java/android/app/SmsAppService.java
+++ b/core/java/android/app/SmsAppService.java
@@ -24,21 +24,42 @@
  * it so that the process is always running, which allows the app to have a persistent connection
  * to the server.
  *
- * <p>The service must have {@link android.telephony.TelephonyManager#ACTION_SMS_APP_SERVICE}
+ * <p>The service must have an {@link android.telephony.TelephonyManager#ACTION_SMS_APP_SERVICE}
  * action in the intent handler, and be protected with
  * {@link android.Manifest.permission#BIND_SMS_APP_SERVICE}. However the service does not have to
  * be exported.
  *
- * <p>Apps can use
+ * <p>The service must be associated with a non-main process, meaning it must have an
+ * {@code android:process} tag in its manifest entry.
+ *
+ * <p>An app can use
  * {@link android.content.pm.PackageManager#setComponentEnabledSetting(ComponentName, int, int)}
- * to disable/enable the service. Apps should use it to disable the service when it no longer needs
- * to be running.
+ * to disable or enable the service. An app should use it to disable the service when it no longer
+ * needs to be running.
  *
  * <p>When the owner process crashes, the service will be re-bound automatically after a
  * back-off.
  *
  * <p>Note the process may still be killed if the system is under heavy memory pressure, in which
  * case the process will be re-started later.
+ *
+ * <p>Example: First, define a subclass in the application:
+ * <pre>
+ * public class MySmsAppService extends SmsAppService {
+ * }
+ * </pre>
+ * Then, declare it in its {@code AndroidManifest.xml}:
+ * <pre>
+ * &lt;service
+ *    android:name=".MySmsAppService"
+ *    android:exported="false"
+ *    android:process=":persistent"
+ *    android:permission="android.permission.BIND_SMS_APP_SERVICE"&gt;
+ *    &lt;intent-filter&gt;
+ *        &lt;action android:name="android.telephony.action.SMS_APP_SERVICE" /&gt;
+ *    &lt;/intent-filter&gt;
+ * &lt;/service&gt;
+ * </pre>
  */
 public class SmsAppService extends Service {
     private final ISmsAppService mImpl;
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 0044005..77cebc8 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -377,11 +377,15 @@
                 return new DisplayManager(ctx.getOuterContext());
             }});
 
+        // InputMethodManager has its own cache strategy based on display id to support apps that
+        // still assume InputMethodManager is a per-process singleton and it's safe to directly
+        // access internal fields via reflection.  Hence directly use ServiceFetcher instead of
+        // StaticServiceFetcher/CachedServiceFetcher.
         registerService(Context.INPUT_METHOD_SERVICE, InputMethodManager.class,
-                new StaticServiceFetcher<InputMethodManager>() {
+                new ServiceFetcher<InputMethodManager>() {
             @Override
-            public InputMethodManager createService() {
-                return InputMethodManager.getInstanceInternal();
+            public InputMethodManager getService(ContextImpl ctx) {
+                return InputMethodManager.forContext(ctx.getOuterContext());
             }});
 
         registerService(Context.TEXT_SERVICES_MANAGER_SERVICE, TextServicesManager.class,
diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java
index 9873a81..e33d1fe 100644
--- a/core/java/android/app/WallpaperInfo.java
+++ b/core/java/android/app/WallpaperInfo.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import android.app.slice.Slice;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -77,6 +78,7 @@
     final int mContextDescriptionResource;
     final boolean mShowMetadataInPreview;
     final boolean mSupportsAmbientMode;
+    final String mSettingsSliceUri;
 
     /**
      * Constructor.
@@ -118,7 +120,6 @@
                     com.android.internal.R.styleable.Wallpaper);
             mSettingsActivityName = sa.getString(
                     com.android.internal.R.styleable.Wallpaper_settingsActivity);
-
             mThumbnailResource = sa.getResourceId(
                     com.android.internal.R.styleable.Wallpaper_thumbnail,
                     -1);
@@ -140,6 +141,8 @@
             mSupportsAmbientMode = sa.getBoolean(
                     com.android.internal.R.styleable.Wallpaper_supportsAmbientMode,
                     false);
+            mSettingsSliceUri = sa.getString(
+                    com.android.internal.R.styleable.Wallpaper_settingsSliceUri);
 
             sa.recycle();
         } catch (NameNotFoundException e) {
@@ -159,6 +162,7 @@
         mContextDescriptionResource = source.readInt();
         mShowMetadataInPreview = source.readInt() != 0;
         mSupportsAmbientMode = source.readInt() != 0;
+        mSettingsSliceUri = source.readString();
         mService = ResolveInfo.CREATOR.createFromParcel(source);
     }
     
@@ -332,13 +336,28 @@
      * explicit {@link android.content.ComponentName}
      * composed of {@link #getPackageName} and the class name returned here.
      * 
-     * <p>A null will be returned if there is no settings activity associated
+     * <p>{@code null} will be returned if there is no settings activity associated
      * with the wallpaper.
      */
     public String getSettingsActivity() {
         return mSettingsActivityName;
     }
     
+    /**
+     * Returns an URI that provides a settings {@link Slice} for this wallpaper.
+     *
+     * <p>{@code null} will be returned if there is no settings Slice URI associated
+     * with the wallpaper.
+     *
+     * @return The URI.
+     */
+    public Uri getSettingsSliceUri() {
+        if (mSettingsSliceUri == null) {
+            return null;
+        }
+        return Uri.parse(mSettingsSliceUri);
+    }
+
     public void dump(Printer pw, String prefix) {
         pw.println(prefix + "Service:");
         mService.dump(pw, prefix + "  ");
@@ -367,6 +386,7 @@
         dest.writeInt(mContextDescriptionResource);
         dest.writeInt(mShowMetadataInPreview ? 1 : 0);
         dest.writeInt(mSupportsAmbientMode ? 1 : 0);
+        dest.writeString(mSettingsSliceUri);
         mService.writeToParcel(dest, flags);
     }
 
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 1839263..92daf08 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -51,6 +51,7 @@
 import android.graphics.Bitmap;
 import android.net.ProxyInfo;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.PersistableBundle;
@@ -664,8 +665,8 @@
 
     /**
      * A String extra indicating the security type of the wifi network in
-     * {@link #EXTRA_PROVISIONING_WIFI_SSID} and could be one of {@code NONE}, {@code WPA} or
-     * {@code WEP}.
+     * {@link #EXTRA_PROVISIONING_WIFI_SSID} and could be one of {@code NONE}, {@code WPA},
+     * {@code WEP} or {@code EAP}.
      *
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
      * provisioning via an NFC bump.
@@ -680,8 +681,89 @@
      * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
      * provisioning via an NFC bump.
      */
-    public static final String EXTRA_PROVISIONING_WIFI_PASSWORD
-        = "android.app.extra.PROVISIONING_WIFI_PASSWORD";
+    public static final String EXTRA_PROVISIONING_WIFI_PASSWORD =
+            "android.app.extra.PROVISIONING_WIFI_PASSWORD";
+
+    /**
+     * The EAP method of the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}
+     * and could be one of {@code PEAP}, {@code TLS}, {@code TTLS}, {@code PWD}, {@code SIM},
+     * {@code AKA} or {@code AKA_PRIME}. This is only used if the
+     * {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE} is {@code EAP}.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_EAP_METHOD =
+            "android.app.extra.PROVISIONING_WIFI_EAP_METHOD";
+
+    /**
+     * The phase 2 authentication of the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}
+     * and could be one of {@code NONE}, {@code PAP}, {@code MSCHAP}, {@code MSCHAPV2}, {@code GTC},
+     * {@code SIM}, {@code AKA} or {@code AKA_PRIME}. This is only used if the
+     * {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE} is {@code EAP}.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_PHASE2_AUTH =
+            "android.app.extra.PROVISIONING_WIFI_PHASE2_AUTH";
+
+    /**
+     * The CA certificate of the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}. This should
+     * be an X.509 certificate Base64 encoded DER format, ie. PEM representation of a certificate
+     * without header, footer and line breaks. <a href=
+     * "https://tools.ietf.org/html/rfc7468"> More information</a> This is only
+     * used if the {@link
+     * #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE} is {@code EAP}.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE =
+            "android.app.extra.PROVISIONING_WIFI_CA_CERTIFICATE";
+
+    /**
+     * The user certificate of the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}. This
+     * should be an X.509 certificate and private key Base64 encoded DER format, ie. PEM
+     * representation of a certificate and key without header, footer and line breaks. <a href=
+     * "https://tools.ietf.org/html/rfc7468"> More information</a> This is only
+     * used if the {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE} is {@code EAP}.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE =
+            "android.app.extra.PROVISIONING_WIFI_USER_CERTIFICATE";
+
+    /**
+     * The identity of the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}. This is only used
+     * if the {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE} is {@code EAP}.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_IDENTITY =
+            "android.app.extra.PROVISIONING_WIFI_IDENTITY";
+
+    /**
+     * The anonymous identity of the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}. This is
+     * only used if the {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE} is {@code EAP}.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
+     */
+
+    public static final String EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY =
+            "android.app.extra.PROVISIONING_WIFI_ANONYMOUS_IDENTITY";
+    /**
+     * The domain of the wifi network in {@link #EXTRA_PROVISIONING_WIFI_SSID}. This is only used if
+     * the {@link #EXTRA_PROVISIONING_WIFI_SECURITY_TYPE} is {@code EAP}.
+     *
+     * <p>Use in an NFC record with {@link #MIME_TYPE_PROVISIONING_NFC} that starts device owner
+     * provisioning via an NFC bump. It can also be used for QR code provisioning.
+     */
+    public static final String EXTRA_PROVISIONING_WIFI_DOMAIN =
+            "android.app.extra.PROVISIONING_WIFI_DOMAIN";
 
     /**
      * A String extra holding the proxy host for the wifi network in
@@ -1067,8 +1149,22 @@
      * <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_PORT} (convert to String), optional</li>
      * <li>{@link #EXTRA_PROVISIONING_WIFI_PROXY_BYPASS}, optional</li>
      * <li>{@link #EXTRA_PROVISIONING_WIFI_PAC_URL}, optional</li>
-     * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional, supported from
-     * {@link android.os.Build.VERSION_CODES#M} </li></ul>
+     * <li>{@link #EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE}, optional, supported from {@link
+     * android.os.Build.VERSION_CODES#M} </li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_EAP_METHOD}, optional, supported from {@link
+     * android.os.Build.VERSION_CODES#Q}</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_PHASE2_AUTH}, optional, supported from {@link
+     * android.os.Build.VERSION_CODES#Q}</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_CA_CERTIFICATE}, optional, supported from {@link
+     * android.os.Build.VERSION_CODES#Q}</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_USER_CERTIFICATE}, optional, supported from {@link
+     * android.os.Build.VERSION_CODES#Q}</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_IDENTITY}, optional, supported from {@link
+     * android.os.Build.VERSION_CODES#Q}</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_ANONYMOUS_IDENTITY}, optional, supported from {@link
+     * android.os.Build.VERSION_CODES#Q}</li>
+     * <li>{@link #EXTRA_PROVISIONING_WIFI_DOMAIN}, optional, supported from {@link
+     * android.os.Build.VERSION_CODES#Q}</li></ul>
      *
      * <p>
      * As of {@link android.os.Build.VERSION_CODES#M}, the properties should contain
@@ -1803,6 +1899,36 @@
     public static final String ACTION_PROFILE_OWNER_CHANGED =
             "android.app.action.PROFILE_OWNER_CHANGED";
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, prefix = {"PRIVATE_DNS_MODE_"}, value = {
+            PRIVATE_DNS_MODE_UNKNOWN,
+            PRIVATE_DNS_MODE_OFF,
+            PRIVATE_DNS_MODE_OPPORTUNISTIC,
+            PRIVATE_DNS_MODE_PROVIDER_HOSTNAME
+    })
+    public @interface PrivateDnsMode {}
+
+    /**
+     * Specifies that the Private DNS setting is in an unknown state.
+     */
+    public static final int PRIVATE_DNS_MODE_UNKNOWN = 0;
+
+    /**
+     * Specifies that Private DNS was turned off completely.
+     */
+    public static final int PRIVATE_DNS_MODE_OFF = 1;
+
+    /**
+     * Specifies that the device owner requested opportunistic DNS over TLS
+     */
+    public static final int PRIVATE_DNS_MODE_OPPORTUNISTIC = 2;
+
+    /**
+     * Specifies that the device owner configured a specific host to use for Private DNS.
+     */
+    public static final int PRIVATE_DNS_MODE_PROVIDER_HOSTNAME = 3;
+
     /**
      * Return true if the given administrator component is currently active (enabled) in the system.
      *
@@ -3304,7 +3430,7 @@
      * restrictions on the parent profile.
      *
      * @param admin The name of the admin component to check, or {@code null} to aggregate
-     *         accross all participating admins.
+     *         across all participating admins.
      * @return The timeout in milliseconds or 0 if not configured for the provided admin.
      */
     public long getRequiredStrongAuthTimeout(@Nullable ComponentName admin) {
@@ -5129,13 +5255,30 @@
     }
 
     /**
-     * @return ID of the user who runs device owner, or {@link UserHandle#USER_NULL} if there's
-     * no device owner.
+     * @return Handle of the user who runs device owner, or {@code null} if there's no device owner.
      *
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
     @SystemApi
+    public @Nullable UserHandle getDeviceOwnerUser() {
+        if (mService != null) {
+            try {
+                int userId = mService.getDeviceOwnerUserId();
+
+                if (userId != UserHandle.USER_NULL) {
+                    return UserHandle.of(userId);
+                }
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     */
     public int getDeviceOwnerUserId() {
         if (mService != null) {
             try {
@@ -5558,6 +5701,20 @@
     @RequiresPermission(value = android.Manifest.permission.INTERACT_ACROSS_USERS,
             conditional = true)
     @SystemApi
+    public @Nullable ComponentName getProfileOwnerAsUser(@NonNull UserHandle user) {
+        if (mService != null) {
+            try {
+                return mService.getProfileOwnerAsUser(user.getIdentifier());
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     */
     public @Nullable ComponentName getProfileOwnerAsUser(final int userId) {
         if (mService != null) {
             try {
@@ -5608,6 +5765,38 @@
     }
 
     /**
+     * Returns whether the specified package can read the device identifiers.
+     *
+     * @param packageName The package name of the app to check for device identifier access.
+     * @return whether the package can read the device identifiers.
+     *
+     * @hide
+     */
+    public boolean checkDeviceIdentifierAccess(String packageName) {
+        return checkDeviceIdentifierAccessAsUser(packageName, myUserId());
+    }
+
+    /**
+     * @hide
+     */
+    @RequiresPermission(value = android.Manifest.permission.MANAGE_USERS, conditional = true)
+    public boolean checkDeviceIdentifierAccessAsUser(String packageName, int userId) {
+        throwIfParentInstance("checkDeviceIdentifierAccessAsUser");
+        if (packageName == null) {
+            return false;
+        }
+        if (mService != null) {
+            try {
+                return mService.checkDeviceIdentifierAccess(packageName, userId,
+                        Binder.getCallingPid(), Binder.getCallingUid());
+            } catch (RemoteException re) {
+                throw re.rethrowFromSystemServer();
+            }
+        }
+        return false;
+    }
+
+    /**
      * Called by a profile owner or device owner to set a default activity that the system selects
      * to handle intents that match the given {@link IntentFilter}. This activity will remain the
      * default intent handler even if the set of potential event handlers for the intent filter
@@ -9597,4 +9786,80 @@
             throw re.rethrowFromSystemServer();
         }
     }
+
+
+    /**
+     * Sets the global Private DNS mode and host to be used.
+     * May only be called by the device owner.
+     *
+     * @param admin which {@link DeviceAdminReceiver} this request is associated with.
+     * @param mode Which mode to set - either {@code PRIVATE_DNS_MODE_OPPORTUNISTIC} or
+     *             {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME}.
+     *             Since the opportunistic mode defaults to ordinary DNS lookups, the
+     *             option to turn it completely off is not available, so this method
+     *             may not be called with {@code PRIVATE_DNS_MODE_OFF}.
+     * @param privateDnsHost The hostname of a server that implements DNS over TLS (RFC7858), if
+     *                       {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME} was specified as the mode,
+     *                       null otherwise.
+     * @throws IllegalArgumentException in the following cases: if a {@code privateDnsHost} was
+     * provided but the mode was not {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME}, if the mode
+     * specified was {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME} but {@code privateDnsHost} does
+     * not look like a valid hostname, or if the mode specified is not one of the two valid modes.
+     *
+     * @throws SecurityException if the caller is not the device owner.
+     */
+    public void setGlobalPrivateDns(@NonNull ComponentName admin,
+            @PrivateDnsMode int mode, @Nullable String privateDnsHost) {
+        throwIfParentInstance("setGlobalPrivateDns");
+        if (mService == null) {
+            return;
+        }
+
+        try {
+            mService.setGlobalPrivateDns(admin, mode, privateDnsHost);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the system-wide Private DNS mode.
+     *
+     * @param admin which {@link DeviceAdminReceiver} this request is associated with.
+     * @return one of {@code PRIVATE_DNS_MODE_OFF}, {@code PRIVATE_DNS_MODE_OPPORTUNISTIC},
+     * {@code PRIVATE_DNS_MODE_PROVIDER_HOSTNAME} or {@code PRIVATE_DNS_MODE_UNKNOWN}.
+     * @throws SecurityException if the caller is not the device owner.
+     */
+    public int getGlobalPrivateDnsMode(@NonNull ComponentName admin) {
+        throwIfParentInstance("setGlobalPrivateDns");
+        if (mService == null) {
+            return PRIVATE_DNS_MODE_UNKNOWN;
+        }
+
+        try {
+            return mService.getGlobalPrivateDnsMode(admin);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the system-wide Private DNS host.
+     *
+     * @param admin which {@link DeviceAdminReceiver} this request is associated with.
+     * @return The hostname used for Private DNS queries.
+     * @throws SecurityException if the caller is not the device owner.
+     */
+    public String getGlobalPrivateDnsHost(@NonNull ComponentName admin) {
+        throwIfParentInstance("setGlobalPrivateDns");
+        if (mService == null) {
+            return null;
+        }
+
+        try {
+            return mService.getGlobalPrivateDnsHost(admin);
+        } catch (RemoteException re) {
+            throw re.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index 35ea250..ce1f4ef 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -153,6 +153,8 @@
     void clearProfileOwner(in ComponentName who);
     boolean hasUserSetupCompleted();
 
+    boolean checkDeviceIdentifierAccess(in String packageName, int userHandle, int pid, int uid);
+
     void setDeviceOwnerLockScreenInfo(in ComponentName who, CharSequence deviceOwnerInfo);
     CharSequence getDeviceOwnerLockScreenInfo();
 
@@ -411,4 +413,8 @@
     boolean isOverrideApnEnabled(in ComponentName admin);
 
     boolean isMeteredDataDisabledPackageForUser(in ComponentName admin, String packageName, int userId);
+
+    void setGlobalPrivateDns(in ComponentName admin, int mode, in String privateDnsHost);
+    int getGlobalPrivateDnsMode(in ComponentName admin);
+    String getGlobalPrivateDnsHost(in ComponentName admin);
 }
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 173b766..fefb8d3 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -74,6 +74,7 @@
     ComponentName mActivityComponent;
     private boolean mIsHomeActivity;
     private int mFlags;
+    private int mAutofillFlags;
 
     final ArrayList<WindowNode> mWindowNodes = new ArrayList<>();
 
@@ -197,6 +198,7 @@
             mWriteStructure = as.waitForReady();
             ComponentName.writeToParcel(as.mActivityComponent, out);
             out.writeInt(as.mFlags);
+            out.writeInt(as.mAutofillFlags);
             out.writeLong(as.mAcquisitionStartTime);
             out.writeLong(as.mAcquisitionEndTime);
             mNumWindows = as.mWindowNodes.size();
@@ -352,6 +354,7 @@
             fetchData();
             mActivityComponent = ComponentName.readFromParcel(mCurParcel);
             mFlags = mCurParcel.readInt();
+            mAutofillFlags = mCurParcel.readInt();
             mAcquisitionStartTime = mCurParcel.readLong();
             mAcquisitionEndTime = mCurParcel.readLong();
             final int N = mCurParcel.readInt();
@@ -625,8 +628,6 @@
         String mIdType;
         String mIdEntry;
 
-        // TODO(b/37567426): once we have more flags, it might be better to store the individual
-        // fields (viewId and childId) of the field.
         AutofillId mAutofillId;
         @View.AutofillType int mAutofillType = View.AUTOFILL_TYPE_NONE;
         @Nullable String[] mAutofillHints;
@@ -669,11 +670,6 @@
         static final int FLAGS_CONTEXT_CLICKABLE = 0x00004000;
         static final int FLAGS_OPAQUE = 0x00008000;
 
-        // TODO(b/37567426): autofill data is made of many fields and ideally we should verify
-        // one-by-one to optimize what's sent over, but there isn't enough flag bits for that, we'd
-        // need to create a 'flags2' or 'autoFillFlags' field and add these flags there.
-        // So, to keep thinkg simpler for now, let's just use on flag for all of them...
-        static final int FLAGS_HAS_AUTOFILL_DATA = 0x80000000;
         static final int FLAGS_HAS_MATRIX = 0x40000000;
         static final int FLAGS_HAS_ALPHA = 0x20000000;
         static final int FLAGS_HAS_ELEVATION = 0x10000000;
@@ -690,7 +686,20 @@
         static final int FLAGS_HAS_LOCALE_LIST = 0x00010000;
         static final int FLAGS_ALL_CONTROL = 0xfff00000;
 
+        static final int AUTOFILL_FLAGS_HAS_AUTOFILL_VIEW_ID =         0x001;
+        static final int AUTOFILL_FLAGS_HAS_AUTOFILL_VIRTUAL_VIEW_ID = 0x002;
+        static final int AUTOFILL_FLAGS_HAS_AUTOFILL_VALUE =           0x004;
+        static final int AUTOFILL_FLAGS_HAS_AUTOFILL_TYPE =            0x008;
+        static final int AUTOFILL_FLAGS_HAS_AUTOFILL_HINTS =           0x010;
+        static final int AUTOFILL_FLAGS_HAS_AUTOFILL_OPTIONS =         0x020;
+        static final int AUTOFILL_FLAGS_HAS_HTML_INFO =                0x040;
+        static final int AUTOFILL_FLAGS_HAS_TEXT_ID_ENTRY =            0x080;
+        static final int AUTOFILL_FLAGS_HAS_MIN_TEXT_EMS =             0x100;
+        static final int AUTOFILL_FLAGS_HAS_MAX_TEXT_EMS =             0x200;
+        static final int AUTOFILL_FLAGS_HAS_MAX_TEXT_LENGTH =          0x400;
+
         int mFlags;
+        int mAutofillFlags;
 
         String mClassName;
         CharSequence mContentDescription;
@@ -714,6 +723,8 @@
             mClassName = preader.readString();
             mFlags = in.readInt();
             final int flags = mFlags;
+            mAutofillFlags = in.readInt();
+            final int autofillFlags = mAutofillFlags;
             if ((flags&FLAGS_HAS_ID) != 0) {
                 mId = in.readInt();
                 if (mId != View.NO_ID) {
@@ -725,22 +736,45 @@
                 }
             }
 
-            if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0) {
+            if (autofillFlags != 0) {
                 mSanitized = in.readInt() == 1;
-                mAutofillId = in.readParcelable(null);
-                mAutofillType = in.readInt();
-                mAutofillHints = in.readStringArray();
-                mAutofillValue = in.readParcelable(null);
-                mAutofillOptions = in.readCharSequenceArray();
-                final Parcelable p = in.readParcelable(null);
-                if (p instanceof HtmlInfo) {
-                    mHtmlInfo = (HtmlInfo) p;
-                }
-                mMinEms = in.readInt();
-                mMaxEms = in.readInt();
-                mMaxLength = in.readInt();
-                mTextIdEntry = preader.readString();
                 mImportantForAutofill = in.readInt();
+
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_VIEW_ID) != 0) {
+                    int autofillViewId = in.readInt();
+                    if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_VIRTUAL_VIEW_ID) != 0) {
+                        mAutofillId = new AutofillId(autofillViewId, in.readInt());
+                    } else {
+                        mAutofillId = new AutofillId(autofillViewId);
+                    }
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_TYPE) != 0) {
+                    mAutofillType = in.readInt();
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_HINTS) != 0) {
+                    mAutofillHints = in.readStringArray();
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_VALUE) != 0) {
+                    mAutofillValue = in.readParcelable(null);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_OPTIONS) != 0) {
+                    mAutofillOptions = in.readCharSequenceArray();
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_HTML_INFO) != 0) {
+                    mHtmlInfo = in.readParcelable(null);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_MIN_TEXT_EMS) != 0) {
+                    mMinEms = in.readInt();
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_MAX_TEXT_EMS) != 0) {
+                    mMaxEms = in.readInt();
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_MAX_TEXT_LENGTH) != 0) {
+                    mMaxLength = in.readInt();
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_TEXT_ID_ENTRY) != 0) {
+                    mTextIdEntry = preader.readString();
+                }
             }
             if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
                 mX = in.readInt();
@@ -808,13 +842,11 @@
             boolean writeSensitive = true;
 
             int flags = mFlags & ~FLAGS_ALL_CONTROL;
+            int autofillFlags = 0;
 
             if (mId != View.NO_ID) {
                 flags |= FLAGS_HAS_ID;
             }
-            if (mAutofillId != null) {
-                flags |= FLAGS_HAS_AUTOFILL_DATA;
-            }
             if ((mX&~0x7fff) != 0 || (mY&~0x7fff) != 0
                     || (mWidth&~0x7fff) != 0 | (mHeight&~0x7fff) != 0) {
                 flags |= FLAGS_HAS_LARGE_COORDS;
@@ -855,11 +887,44 @@
             if (mChildren != null) {
                 flags |= FLAGS_HAS_CHILDREN;
             }
+            if (mAutofillId != null) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_AUTOFILL_VIEW_ID;
+                if (mAutofillId.isVirtual()) {
+                    autofillFlags |= AUTOFILL_FLAGS_HAS_AUTOFILL_VIRTUAL_VIEW_ID;
+                }
+            }
+            if (mAutofillValue != null) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_AUTOFILL_VALUE;
+            }
+            if (mAutofillType != View.AUTOFILL_TYPE_NONE) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_AUTOFILL_TYPE;
+            }
+            if (mAutofillHints != null) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_AUTOFILL_HINTS;
+            }
+            if (mAutofillOptions != null) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_AUTOFILL_OPTIONS;
+            }
+            if (mHtmlInfo instanceof Parcelable) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_HTML_INFO;
+            }
+            if (mMinEms > -1) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_MIN_TEXT_EMS;
+            }
+            if (mMaxEms > -1) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_MAX_TEXT_EMS;
+            }
+            if (mMaxLength > -1) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_MAX_TEXT_LENGTH;
+            }
+            if (mTextIdEntry != null) {
+                autofillFlags |= AUTOFILL_FLAGS_HAS_TEXT_ID_ENTRY;
+            }
 
             pwriter.writeString(mClassName);
 
             int writtenFlags = flags;
-            if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0 && (mSanitized || !sanitizeOnWrite)) {
+            if (autofillFlags != 0 && (mSanitized || !sanitizeOnWrite)) {
                 // Remove 'checked' from sanitized autofill request.
                 writtenFlags = flags & ~FLAGS_CHECKED;
             }
@@ -872,6 +937,7 @@
             }
 
             out.writeInt(writtenFlags);
+            out.writeInt(autofillFlags);
             if ((flags&FLAGS_HAS_ID) != 0) {
                 out.writeInt(mId);
                 if (mId != View.NO_ID) {
@@ -883,32 +949,51 @@
                 }
             }
 
-            if ((flags&FLAGS_HAS_AUTOFILL_DATA) != 0) {
-                writeSensitive = mSanitized || !sanitizeOnWrite;
+            if (autofillFlags != 0) {
                 out.writeInt(mSanitized ? 1 : 0);
-                out.writeParcelable(mAutofillId, 0);
-                out.writeInt(mAutofillType);
-                out.writeStringArray(mAutofillHints);
-                final AutofillValue sanitizedValue;
-                if (writeSensitive) {
-                    sanitizedValue = mAutofillValue;
-                } else if (mAutofillOverlay != null && mAutofillOverlay.value != null) {
-                    sanitizedValue = mAutofillOverlay.value;
-                } else {
-                    sanitizedValue = null;
-                }
-                out.writeParcelable(sanitizedValue,  0);
-                out.writeCharSequenceArray(mAutofillOptions);
-                if (mHtmlInfo instanceof Parcelable) {
-                    out.writeParcelable((Parcelable) mHtmlInfo, 0);
-                } else {
-                    out.writeParcelable(null, 0);
-                }
-                out.writeInt(mMinEms);
-                out.writeInt(mMaxEms);
-                out.writeInt(mMaxLength);
-                pwriter.writeString(mTextIdEntry);
                 out.writeInt(mImportantForAutofill);
+                writeSensitive = mSanitized || !sanitizeOnWrite;
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_VIEW_ID) != 0) {
+                    out.writeInt(mAutofillId.getViewId());
+                    if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_VIRTUAL_VIEW_ID) != 0) {
+                        out.writeInt(mAutofillId.getVirtualChildId());
+                    }
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_TYPE) != 0) {
+                    out.writeInt(mAutofillType);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_HINTS) != 0) {
+                    out.writeStringArray(mAutofillHints);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_VALUE) != 0) {
+                    final AutofillValue sanitizedValue;
+                    if (writeSensitive) {
+                        sanitizedValue = mAutofillValue;
+                    } else if (mAutofillOverlay != null && mAutofillOverlay.value != null) {
+                        sanitizedValue = mAutofillOverlay.value;
+                    } else {
+                        sanitizedValue = null;
+                    }
+                    out.writeParcelable(sanitizedValue, 0);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_OPTIONS) != 0) {
+                    out.writeCharSequenceArray(mAutofillOptions);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_HTML_INFO) != 0) {
+                    out.writeParcelable((Parcelable) mHtmlInfo, 0);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_MIN_TEXT_EMS) != 0) {
+                    out.writeInt(mMinEms);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_MAX_TEXT_EMS) != 0) {
+                    out.writeInt(mMaxEms);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_MAX_TEXT_LENGTH) != 0) {
+                    out.writeInt(mMaxLength);
+                }
+                if ((autofillFlags & AUTOFILL_FLAGS_HAS_TEXT_ID_ENTRY) != 0) {
+                    pwriter.writeString(mTextIdEntry);
+                }
             }
             if ((flags&FLAGS_HAS_LARGE_COORDS) != 0) {
                 out.writeInt(mX);
@@ -1002,7 +1087,7 @@
         }
 
         /**
-         * Gets the the type of value that can be used to autofill the view contents.
+         * Gets the type of value that can be used to autofill the view contents.
          *
          * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes.
          *
@@ -1028,7 +1113,7 @@
         }
 
         /**
-         * Gets the the value of this view.
+         * Gets the value of this view.
          *
          * <p>It's only relevant when the {@link AssistStructure} is used for autofill purposes,
          * not for assist purposes.
@@ -1350,7 +1435,7 @@
         }
 
         /**
-         * Returns the the list of locales associated with this view.
+         * Returns the list of locales associated with this view.
          */
         @Nullable public LocaleList getLocaleList() {
             return mLocaleList;
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index df27d58..c983d4f 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -29,6 +29,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.system.ErrnoException;
 import android.system.Os;
 import android.system.OsConstants;
@@ -222,6 +223,18 @@
     }
 
     /**
+     * Provided as a convenience for agent implementations that need an opportunity
+     * to do one-time initialization before the actual backup or restore operation
+     * is begun with information about the calling user.
+     * <p>
+     *
+     * @hide
+     */
+    public void onCreate(UserHandle user) {
+        onCreate();
+    }
+
+    /**
      * Provided as a convenience for agent implementations that need to do some
      * sort of shutdown process after backup or restore is completed.
      * <p>
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index fda2f89..cb996f3 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -24,6 +24,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -183,7 +184,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth A2DP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 654bfaf..8e6a385 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -2973,7 +2973,7 @@
      * socket will be encrypted.
      * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
      * {@link BluetoothServerSocket}.
-     * <p>The system will assign a dynamic PSM value. This PSM value can be read from the {#link
+     * <p>The system will assign a dynamic PSM value. This PSM value can be read from the {@link
      * BluetoothServerSocket#getPsm()} and this value will be released when this server socket is
      * closed, Bluetooth is turned off, or the application exits unexpectedly.
      * <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
@@ -3031,7 +3031,7 @@
      * <p>Use {@link BluetoothServerSocket#accept} to retrieve incoming connections from a listening
      * {@link BluetoothServerSocket}.
      * <p>The system will assign a dynamic protocol/service multiplexer (PSM) value. This PSM value
-     * can be read from the {#link BluetoothServerSocket#getPsm()} and this value will be released
+     * can be read from the {@link BluetoothServerSocket#getPsm()} and this value will be released
      * when this server socket is closed, Bluetooth is turned off, or the application exits
      * unexpectedly.
      * <p>The mechanism of disclosing the assigned dynamic PSM value to the initiating peer is
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index e7c8944..c447868 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -23,6 +23,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -138,7 +139,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth AVRCP Controller Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 73e98cd..0aa0535 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -107,20 +107,6 @@
             "android.bluetooth.device.action.FOUND";
 
     /**
-     * Broadcast Action: Remote device disappeared.
-     * <p>Sent when a remote device that was found in the last discovery is not
-     * found in the current discovery.
-     * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
-     * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
-     *
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @UnsupportedAppUsage
-    public static final String ACTION_DISAPPEARED =
-            "android.bluetooth.device.action.DISAPPEARED";
-
-    /**
      * Broadcast Action: Bluetooth class of a remote device has changed.
      * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
      * #EXTRA_CLASS}.
@@ -654,7 +640,7 @@
     public static final int ACCESS_REJECTED = 2;
 
     /**
-     * No preferrence of physical transport for GATT connections to remote dual-mode devices
+     * No preference of physical transport for GATT connections to remote dual-mode devices
      */
     public static final int TRANSPORT_AUTO = 0;
 
@@ -1596,7 +1582,7 @@
      * For example, for Bluetooth 2.1 devices, if any of the devices does not
      * have an input and output capability or just has the ability to
      * display a numeric key, a secure socket connection is not possible.
-     * In such a case, use {#link createInsecureRfcommSocket}.
+     * In such a case, use {@link createInsecureRfcommSocket}.
      * For more details, refer to the Security Model section 5.2 (vol 3) of
      * Bluetooth Core Specification version 2.1 + EDR.
      * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
@@ -1631,7 +1617,7 @@
      * For example, for Bluetooth 2.1 devices, if any of the devices does not
      * have an input and output capability or just has the ability to
      * display a numeric key, a secure socket connection is not possible.
-     * In such a case, use {#link createInsecureRfcommSocket}.
+     * In such a case, use {@link createInsecureRfcommSocket}.
      * For more details, refer to the Security Model section 5.2 (vol 3) of
      * Bluetooth Core Specification version 2.1 + EDR.
      * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
@@ -1688,7 +1674,7 @@
      * For example, for Bluetooth 2.1 devices, if any of the devices does not
      * have an input and output capability or just has the ability to
      * display a numeric key, a secure socket connection is not possible.
-     * In such a case, use {#link createInsecureRfcommSocketToServiceRecord}.
+     * In such a case, use {@link #createInsecureRfcommSocketToServiceRecord}.
      * For more details, refer to the Security Model section 5.2 (vol 3) of
      * Bluetooth Core Specification version 2.1 + EDR.
      * <p>Hint: If you are connecting to a Bluetooth serial board then try
@@ -1971,9 +1957,7 @@
      * <p>The remote device will be authenticated and communication on this socket will be
      * encrypted.
      * <p> Use this socket if an authenticated socket link is possible. Authentication refers
-     * to the authentication of the link key to prevent man-in-the-middle type of attacks. When a
-     * secure socket connection is not possible, use {#link createInsecureLeL2capCocSocket(int,
-     * int)}.
+     * to the authentication of the link key to prevent man-in-the-middle type of attacks.
      *
      * @param psm dynamic PSM value from remote device
      * @return a CoC #BluetoothSocket ready for an outgoing connection
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 29d5a1c..d616b8f 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -57,6 +57,7 @@
     private int mAuthRetryState;
     private int mConnState;
     private final Object mStateLock = new Object();
+    private final Object mDeviceBusyLock = new Object();
     @UnsupportedAppUsage
     private Boolean mDeviceBusy = false;
     @UnsupportedAppUsage
@@ -282,7 +283,7 @@
                         }
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
                 }
@@ -357,7 +358,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -413,7 +414,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -496,7 +497,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -547,7 +548,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -596,7 +597,7 @@
                         return;
                     }
 
-                    synchronized (mDeviceBusy) {
+                    synchronized (mDeviceBusyLock) {
                         mDeviceBusy = false;
                     }
 
@@ -1098,7 +1099,7 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1132,7 +1133,7 @@
         if (VDBG) Log.d(TAG, "readUsingCharacteristicUuid() - uuid: " + uuid);
         if (mService == null || mClientIf == 0) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1178,7 +1179,7 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1221,7 +1222,7 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1262,7 +1263,7 @@
         BluetoothDevice device = service.getDevice();
         if (device == null) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
@@ -1292,7 +1293,7 @@
      * <p>After all characteristics have been queued up and verified,
      * {@link #executeReliableWrite} will execute all writes. If a characteristic
      * was not written correctly, calling {@link #abortReliableWrite} will
-     * cancel the current transaction without commiting any values on the
+     * cancel the current transaction without committing any values on the
      * remote device.
      *
      * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -1330,7 +1331,7 @@
         if (VDBG) Log.d(TAG, "executeReliableWrite() - device: " + mDevice.getAddress());
         if (mService == null || mClientIf == 0) return false;
 
-        synchronized (mDeviceBusy) {
+        synchronized (mDeviceBusyLock) {
             if (mDeviceBusy) return false;
             mDeviceBusy = true;
         }
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index ef1b0bd..13b1b4f 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -522,7 +522,7 @@
      * {@link BluetoothGattServerCallback#onConnectionStateChange} callback will be
      * invoked when the connection state changes as a result of this function.
      *
-     * <p>The autoConnect paramter determines whether to actively connect to
+     * <p>The autoConnect parameter determines whether to actively connect to
      * the remote device, or rather passively scan and finalize the connection
      * when the remote device is in range/available. Generally, the first ever
      * connection to a device should be direct (autoConnect set to false) and
@@ -695,7 +695,7 @@
     /**
      * Add a service to the list of services to be hosted.
      *
-     * <p>Once a service has been addded to the the list, the service and its
+     * <p>Once a service has been addded to the list, the service and its
      * included characteristics will be provided by the local device.
      *
      * <p>If the local device has already exposed services when this function
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index ec18d42..549c1fa 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -25,6 +25,7 @@
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -428,7 +429,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Headset Client Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java
index b967fb2..22d41d9 100644
--- a/core/java/android/bluetooth/BluetoothHealth.java
+++ b/core/java/android/bluetooth/BluetoothHealth.java
@@ -24,6 +24,7 @@
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -491,7 +492,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Health Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 606f00a..47c4ee6 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -29,6 +29,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
@@ -205,7 +206,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                android.os.Process.myUserHandle())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Hearing Aid Service with " + intent);
             return;
         }
diff --git a/core/java/android/bluetooth/BluetoothHidDevice.java b/core/java/android/bluetooth/BluetoothHidDevice.java
index 3bc8544..e44f36e 100644
--- a/core/java/android/bluetooth/BluetoothHidDevice.java
+++ b/core/java/android/bluetooth/BluetoothHidDevice.java
@@ -24,6 +24,7 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -454,7 +455,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth HID Device Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothHidHost.java b/core/java/android/bluetooth/BluetoothHidHost.java
index 0ca39f1..58a2522 100644
--- a/core/java/android/bluetooth/BluetoothHidHost.java
+++ b/core/java/android/bluetooth/BluetoothHidHost.java
@@ -25,6 +25,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -279,7 +280,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth HID Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothMap.java b/core/java/android/bluetooth/BluetoothMap.java
index 98c23c6..fc5f830 100644
--- a/core/java/android/bluetooth/BluetoothMap.java
+++ b/core/java/android/bluetooth/BluetoothMap.java
@@ -24,6 +24,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -110,7 +111,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth MAP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothMapClient.java b/core/java/android/bluetooth/BluetoothMapClient.java
index 559a59b..1c82e19 100644
--- a/core/java/android/bluetooth/BluetoothMapClient.java
+++ b/core/java/android/bluetooth/BluetoothMapClient.java
@@ -25,6 +25,7 @@
 import android.net.Uri;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -128,7 +129,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth MAP MCE Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 58be732..8923d73 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -26,6 +26,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -150,7 +151,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Pan Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPbap.java b/core/java/android/bluetooth/BluetoothPbap.java
index ae264e1..a601df0 100644
--- a/core/java/android/bluetooth/BluetoothPbap.java
+++ b/core/java/android/bluetooth/BluetoothPbap.java
@@ -24,6 +24,7 @@
 import android.content.ServiceConnection;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -164,7 +165,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth Pbap Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothPbapClient.java b/core/java/android/bluetooth/BluetoothPbapClient.java
index 1446adc..cbc96c0 100644
--- a/core/java/android/bluetooth/BluetoothPbapClient.java
+++ b/core/java/android/bluetooth/BluetoothPbapClient.java
@@ -23,6 +23,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -116,7 +117,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth PBAP Client Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothSap.java b/core/java/android/bluetooth/BluetoothSap.java
index 1b73206..ebf6bed 100644
--- a/core/java/android/bluetooth/BluetoothSap.java
+++ b/core/java/android/bluetooth/BluetoothSap.java
@@ -24,6 +24,7 @@
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.os.UserHandle;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -148,7 +149,7 @@
         ComponentName comp = intent.resolveSystemService(mContext.getPackageManager(), 0);
         intent.setComponent(comp);
         if (comp == null || !mContext.bindServiceAsUser(intent, mConnection, 0,
-                mContext.getUser())) {
+                UserHandle.CURRENT_OR_SELF)) {
             Log.e(TAG, "Could not bind to Bluetooth SAP Service with " + intent);
             return false;
         }
diff --git a/core/java/android/bluetooth/BluetoothServerSocket.java b/core/java/android/bluetooth/BluetoothServerSocket.java
index 5fc344a..4e88625 100644
--- a/core/java/android/bluetooth/BluetoothServerSocket.java
+++ b/core/java/android/bluetooth/BluetoothServerSocket.java
@@ -203,8 +203,8 @@
     /**
      * Returns the assigned dynamic protocol/service multiplexer (PSM) value for the listening L2CAP
      * Connection-oriented Channel (CoC) server socket. This server socket must be returned by the
-     * {#link BluetoothAdapter.listenUsingL2capChannel()} or {#link
-     * BluetoothAdapter.listenUsingInsecureL2capChannel()}. The returned value is undefined if this
+     * {@link BluetoothAdapter#listenUsingL2capChannel()} or {@link
+     * BluetoothAdapter#listenUsingInsecureL2capChannel()}. The returned value is undefined if this
      * method is called on non-L2CAP server sockets.
      *
      * @return the assigned PSM or LE_PSM value depending on transport
diff --git a/core/java/android/bluetooth/le/AdvertisingSetCallback.java b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
index 58a3696..51324fd 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetCallback.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
@@ -56,7 +56,7 @@
     /**
      * Callback triggered in response to {@link BluetoothLeAdvertiser#startAdvertisingSet}
      * indicating result of the operation. If status is ADVERTISE_SUCCESS, then advertisingSet
-     * contains the started set and it is advertising. If error occured, advertisingSet is
+     * contains the started set and it is advertising. If error occurred, advertisingSet is
      * null, and status will be set to proper error code.
      *
      * @param advertisingSet The advertising set that was started or null if error.
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index b528e39..a086a30 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -95,7 +95,7 @@
  * the SyncManager will wait until the sync adapter is not in use before requesting that
  * it sync an account's data.
  * <li><code>android:isAlwaysSyncable</code> defaults to false and if true tells the SyncManager
- * to intialize the isSyncable state to 1 for that sync adapter for each account that is added.
+ * to initialize the isSyncable state to 1 for that sync adapter for each account that is added.
  * <li><code>android:syncAdapterSettingsAction</code> defaults to null and if supplied it
  * specifies an Intent action of an activity that can be used to adjust the sync adapter's
  * sync settings. The activity must live in the same package as the sync adapter.
diff --git a/core/java/android/content/ClipData.java b/core/java/android/content/ClipData.java
index 089cf10..ed3d455 100644
--- a/core/java/android/content/ClipData.java
+++ b/core/java/android/content/ClipData.java
@@ -224,7 +224,7 @@
          * Create an Item consisting of a single block of (possibly styled) text,
          * with an alternative HTML formatted representation.  You <em>must</em>
          * supply a plain text representation in addition to HTML text; coercion
-         * will not be done from HTML formated text into plain text.
+         * will not be done from HTML formatted text into plain text.
          */
         public Item(CharSequence text, String htmlText) {
             mText = text;
@@ -268,7 +268,7 @@
          * Create a complex Item, containing multiple representations of
          * text, HTML text, Intent, and/or URI.  If providing HTML text, you
          * <em>must</em> supply a plain text representation as well; coercion
-         * will not be done from HTML formated text into plain text.
+         * will not be done from HTML formatted text into plain text.
          */
         public Item(CharSequence text, String htmlText, Intent intent, Uri uri) {
             if (htmlText != null && text == null) {
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index a64eead..145c9273 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 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_IGNORED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -569,11 +570,7 @@
                 return mode;
             }
 
-            if (mReadOp != AppOpsManager.OP_NONE) {
-                return mAppOpsManager.noteProxyOp(mReadOp, callingPkg);
-            }
-
-            return AppOpsManager.MODE_ALLOWED;
+            return noteProxyOp(callingPkg, mReadOp);
         }
 
         private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
@@ -583,8 +580,13 @@
                 return mode;
             }
 
-            if (mWriteOp != AppOpsManager.OP_NONE) {
-                return mAppOpsManager.noteProxyOp(mWriteOp, callingPkg);
+            return noteProxyOp(callingPkg, mWriteOp);
+        }
+
+        private int noteProxyOp(String callingPkg, int op) {
+            if (op != AppOpsManager.OP_NONE) {
+                int mode = mAppOpsManager.noteProxyOp(op, callingPkg);
+                return mode == MODE_DEFAULT ? interpretDefaultAppOpMode(op) : mode;
             }
 
             return AppOpsManager.MODE_ALLOWED;
@@ -609,12 +611,17 @@
             return MODE_ERRORED;
         }
 
-        final int permOp = AppOpsManager.permissionToOpCode(permission);
-        if (permOp != AppOpsManager.OP_NONE) {
-            return mTransport.mAppOpsManager.noteProxyOp(permOp, callingPkg);
-        }
+        return mTransport.noteProxyOp(callingPkg, AppOpsManager.permissionToOpCode(permission));
+    }
 
-        return MODE_ALLOWED;
+    /**
+     * Allows for custom interpretations of {@link AppOpsManager#MODE_DEFAULT} by individual
+     * content providers
+     *
+     * @hide
+     */
+    protected int interpretDefaultAppOpMode(int op) {
+        return MODE_IGNORED;
     }
 
     /** {@hide} */
@@ -815,6 +822,48 @@
     }
 
     /**
+     * Opaque token representing the identity of an incoming IPC.
+     */
+    public final class CallingIdentity {
+        /** {@hide} */
+        public final long binderToken;
+        /** {@hide} */
+        public final String callingPackage;
+
+        /** {@hide} */
+        public CallingIdentity(long binderToken, String callingPackage) {
+            this.binderToken = binderToken;
+            this.callingPackage = callingPackage;
+        }
+    }
+
+    /**
+     * Reset the identity of the incoming IPC on the current thread.
+     * <p>
+     * Internally this calls {@link Binder#clearCallingIdentity()} and also
+     * clears any value stored in {@link #getCallingPackage()}.
+     *
+     * @return Returns an opaque token that can be used to restore the original
+     *         calling identity by passing it to
+     *         {@link #restoreCallingIdentity}.
+     */
+    public final @NonNull CallingIdentity clearCallingIdentity() {
+        return new CallingIdentity(Binder.clearCallingIdentity(), setCallingPackage(null));
+    }
+
+    /**
+     * Restore the identity of the incoming IPC on the current thread back to a
+     * previously identity that was returned by {@link #clearCallingIdentity}.
+     * <p>
+     * Internally this calls {@link Binder#restoreCallingIdentity(long)} and
+     * also restores any value stored in {@link #getCallingPackage()}.
+     */
+    public final void restoreCallingIdentity(@NonNull CallingIdentity identity) {
+        Binder.restoreCallingIdentity(identity.binderToken);
+        mCallingPackage.set(identity.callingPackage);
+    }
+
+    /**
      * Change the authorities of the ContentProvider.
      * This is normally set for you from its manifest information when the provider is first
      * created.
@@ -2104,7 +2153,11 @@
         // a source of security issues.
         final String encodedPath = uri.getEncodedPath();
         if (encodedPath != null && encodedPath.indexOf("//") != -1) {
-            return uri.buildUpon().encodedPath(encodedPath.replaceAll("//+", "/")).build();
+            final Uri normalized = uri.buildUpon()
+                    .encodedPath(encodedPath.replaceAll("//+", "/")).build();
+            Log.w(TAG, "Normalized " + uri + " to " + normalized
+                    + " to avoid possible security issues");
+            return normalized;
         } else {
             return uri;
         }
diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java
index 7dc4577..6a3fa6b2 100644
--- a/core/java/android/content/ContentProviderOperation.java
+++ b/core/java/android/content/ContentProviderOperation.java
@@ -637,7 +637,7 @@
 
         /**
          * The selection and arguments to use. An occurrence of '?' in the selection will be
-         * replaced with the corresponding occurence of the selection argument. Any of the
+         * replaced with the corresponding occurrence of the selection argument. Any of the
          * selection arguments may be overwritten by a selection argument back reference as
          * specified by {@link #withSelectionBackReference}.
          * This can only be used with builders of type update, delete, or assert.
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index a882434..a2a6b9b 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -35,6 +35,10 @@
 import android.database.CrossProcessCursorWrapper;
 import android.database.Cursor;
 import android.database.IContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.ImageDecoder;
+import android.graphics.ImageDecoder.ImageInfo;
+import android.graphics.ImageDecoder.Source;
 import android.graphics.Point;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
@@ -52,6 +56,7 @@
 import android.text.TextUtils;
 import android.util.EventLog;
 import android.util.Log;
+import android.util.Size;
 
 import com.android.internal.util.MimeIconUtils;
 import com.android.internal.util.Preconditions;
@@ -68,6 +73,7 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Objects;
 import java.util.Random;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -1877,7 +1883,7 @@
      * that services the content at uri, starting the provider if necessary. Returns
      * null if there is no provider associated wih the uri. The caller must indicate that they are
      * done with the provider by calling {@link ContentProviderClient#release} which will allow
-     * the system to release the provider it it determines that there is no other reason for
+     * the system to release the provider if it determines that there is no other reason for
      * keeping it active.
      * @param uri specifies which provider should be acquired
      * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider}
@@ -1897,7 +1903,7 @@
      * with the authority of name, starting the provider if necessary. Returns
      * null if there is no provider associated wih the uri. The caller must indicate that they are
      * done with the provider by calling {@link ContentProviderClient#release} which will allow
-     * the system to release the provider it it determines that there is no other reason for
+     * the system to release the provider if it determines that there is no other reason for
      * keeping it active.
      * @param name specifies which provider should be acquired
      * @return a {@link ContentProviderClient} that is associated with the {@link ContentProvider}
@@ -3188,4 +3194,71 @@
         }
         return query;
     }
+
+    /**
+     * Convenience method that efficiently loads a visual thumbnail for the
+     * given {@link Uri}. Internally calls
+     * {@link ContentProvider#openTypedAssetFile} on the remote provider, but
+     * also defensively resizes any returned content to match the requested
+     * target size.
+     *
+     * @param uri The item that should be visualized as a thumbnail.
+     * @param size The target area on the screen where this thumbnail will be
+     *            shown. This is passed to the provider as {@link #EXTRA_SIZE}
+     *            to help it avoid downloading or generating heavy resources.
+     * @param signal A signal to cancel the operation in progress.
+     * @return Valid {@link Bitmap} which is a visual thumbnail.
+     * @throws IOException If any trouble was encountered while generating or
+     *             loading the thumbnail, or if
+     *             {@link CancellationSignal#cancel()} was invoked.
+     */
+    public @NonNull Bitmap loadThumbnail(@NonNull Uri uri, @NonNull Size size,
+            @Nullable CancellationSignal signal) throws IOException {
+        Objects.requireNonNull(uri);
+        Objects.requireNonNull(size);
+
+        try (ContentProviderClient client = acquireContentProviderClient(uri)) {
+            return loadThumbnail(client, uri, size, signal, ImageDecoder.ALLOCATOR_DEFAULT);
+        }
+    }
+
+    /** {@hide} */
+    public static Bitmap loadThumbnail(@NonNull ContentProviderClient client, @NonNull Uri uri,
+            @NonNull Size size, @Nullable CancellationSignal signal, int allocator)
+            throws IOException {
+        Objects.requireNonNull(client);
+        Objects.requireNonNull(uri);
+        Objects.requireNonNull(size);
+
+        // Convert to Point, since that's what the API is defined as
+        final Bundle opts = new Bundle();
+        opts.putParcelable(EXTRA_SIZE, Point.convert(size));
+
+        return ImageDecoder.decodeBitmap(ImageDecoder.createSource(() -> {
+            return client.openTypedAssetFileDescriptor(uri, "image/*", opts, signal);
+        }), (ImageDecoder decoder, ImageInfo info, Source source) -> {
+            decoder.setAllocator(allocator);
+
+            // One last-ditch check to see if we've been canceled.
+            if (signal != null) signal.throwIfCanceled();
+
+            // We requested a rough thumbnail size, but the remote size may have
+            // returned something giant, so defensively scale down as needed.
+            final int widthSample = info.getSize().getWidth() / size.getWidth();
+            final int heightSample = info.getSize().getHeight() / size.getHeight();
+            final int sample = Math.min(widthSample, heightSample);
+            if (sample > 1) {
+                decoder.setTargetSampleSize(sample);
+            }
+        });
+    }
+
+    /** {@hide} */
+    public static void onDbCorruption(String tag, String message, Throwable stacktrace) {
+        try {
+            getContentService().onDbCorruption(tag, message, Log.getStackTraceString(stacktrace));
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index d711574..3197352 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -187,7 +187,7 @@
      *
      * <p>This was the legacy (but undocumented) behavior in and
      * before Gingerbread (Android 2.3) and this flag is implied when
-     * targetting such releases.  For applications targetting SDK
+     * targeting such releases.  For applications targeting SDK
      * versions <em>greater than</em> Android 2.3, this flag must be
      * explicitly set if desired.
      *
@@ -2840,7 +2840,7 @@
      *
      * @param service Description of the service to be stopped.  The Intent must be either
      *      fully explicit (supplying a component name) or specify a specific package
-     *      name it is targetted to.
+     *      name it is targeted to.
      *
      * @return If there is a service matching the given Intent that is already
      * running, then it is stopped and {@code true} is returned; else {@code false} is returned.
@@ -4982,6 +4982,14 @@
     public abstract Display getDisplay();
 
     /**
+     * Gets the display ID.
+     *
+     * @return display ID associated with this {@link Context}.
+     * @hide
+     */
+    public abstract int getDisplayId();
+
+    /**
      * @hide
      */
     public abstract void updateDisplay(int displayId);
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index c5dce017..bfad2b4 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -921,6 +921,14 @@
      * @hide
      */
     @Override
+    public int getDisplayId() {
+        return mBase.getDisplayId();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
     public void updateDisplay(int displayId) {
         mBase.updateDisplay(displayId);
     }
diff --git a/core/java/android/content/CursorLoader.java b/core/java/android/content/CursorLoader.java
index 4e46d571..4ccafab 100644
--- a/core/java/android/content/CursorLoader.java
+++ b/core/java/android/content/CursorLoader.java
@@ -36,7 +36,7 @@
  * perform, either through the
  * {@link #CursorLoader(Context, Uri, String[], String, String[], String)} or
  * creating an empty instance with {@link #CursorLoader(Context)} and filling
- * in the desired paramters with {@link #setUri(Uri)}, {@link #setSelection(String)},
+ * in the desired parameters with {@link #setUri(Uri)}, {@link #setSelection(String)},
  * {@link #setSelectionArgs(String[])}, {@link #setSortOrder(String)},
  * and {@link #setProjection(String[])}.
  *
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index a55dd31..1d02375 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -185,4 +185,6 @@
     Bundle getCache(in String packageName, in Uri key, int userId);
 
     void resetTodayStats();
+
+    void onDbCorruption(String tag, String message, String stacktrace);
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 3c8d9d03..ea1a2fe 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1538,7 +1538,10 @@
      * @see #EXTRA_INSTALLER_PACKAGE_NAME
      * @see #EXTRA_NOT_UNKNOWN_SOURCE
      * @see #EXTRA_RETURN_RESULT
+     *
+     * @deprecated use {@link android.content.pm.PackageInstaller} instead
      */
+    @Deprecated
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
 
@@ -1707,7 +1710,11 @@
      * <p>
      * Requires {@link android.Manifest.permission#REQUEST_DELETE_PACKAGES}
      * since {@link Build.VERSION_CODES#P}.
+     *
+     * @deprecated Use {@link android.content.pm.PackageInstaller#uninstall(String, IntentSender)}
+     *             instead
      */
+    @Deprecated
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_UNINSTALL_PACKAGE = "android.intent.action.UNINSTALL_PACKAGE";
 
@@ -1901,6 +1908,22 @@
     @SystemApi
     public static final String EXTRA_PERMISSION_NAME = "android.intent.extra.PERMISSION_NAME";
 
+    /**
+     * Activity action: Launch UI to review app uses of permissions.
+     * <p>
+     * Input: Nothing
+     * </p>
+     * <p>
+     * Output: Nothing.
+     * </p>
+     *
+     * @hide
+     */
+    @SystemApi
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_REVIEW_PERMISSION_USAGE =
+            "android.intent.action.REVIEW_PERMISSION_USAGE";
+
     // ---------------------------------------------------------------------
     // ---------------------------------------------------------------------
     // Standard intent broadcast actions (see action variable).
@@ -3948,6 +3971,12 @@
     public static final String EXTRA_LTE_EARFCN_RSRP_BOOST = "LteEarfcnRsrpBoost";
 
     /**
+     * An parcelable extra used with {@link #ACTION_SERVICE_STATE} representing the service state.
+     * @hide
+     */
+    public static final String EXTRA_SERVICE_STATE = "android.intent.extra.SERVICE_STATE";
+
+    /**
      * The name of the extra used to define the text to be processed, as a
      * CharSequence. Note that this may be a styled CharSequence, so you must use
      * {@link Bundle#getCharSequence(String) Bundle.getCharSequence()} to retrieve it.
@@ -4440,7 +4469,6 @@
      *
      * @hide
      */
-    @SystemApi
     public static final String EXTRA_USER_ID = "android.intent.extra.USER_ID";
 
     /**
@@ -4996,8 +5024,7 @@
             "android.intent.extra.user_handle";
 
     /**
-     * The UserHandle carried with broadcasts intents related to addition and removal of managed
-     * profiles - {@link #ACTION_MANAGED_PROFILE_ADDED} and {@link #ACTION_MANAGED_PROFILE_REMOVED}.
+     * The UserHandle carried with intents.
      */
     public static final String EXTRA_USER =
             "android.intent.extra.USER";
@@ -5516,7 +5543,7 @@
     /**
      * If set and this intent is being used to launch a new activity from an
      * existing one, then the reply target of the existing activity will be
-     * transfered to the new activity.  This way the new activity can call
+     * transferred to the new activity.  This way, the new activity can call
      * {@link android.app.Activity#setResult} and have that result sent back to
      * the reply target of the original activity.
      */
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 0469a90..36d8a37 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -479,7 +479,7 @@
     /**
      * Modify priority of this filter.  This only affects receiver filters.
      * The priority of activity filters are set in XML and cannot be changed
-     * programatically. The default priority is 0. Positive values will be
+     * programmatically. The default priority is 0. Positive values will be
      * before the default, lower values will be after it. Applications should
      * use a value that is larger than {@link #SYSTEM_LOW_PRIORITY} and
      * smaller than {@link #SYSTEM_HIGH_PRIORITY} .
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 5926af6..0a4f4eb 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1408,5 +1408,13 @@
          * @attr ref android.R.styleable#AndroidManifestLayout_minHeight
          */
         public final int minHeight;
+
+        /**
+         * Returns if this {@link WindowLayout} has specified bounds.
+         * @hide
+         */
+        public boolean hasSpecifiedSize() {
+            return width >= 0 || height >= 0 || widthFraction >= 0 || heightFraction >= 0;
+        }
     }
 }
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 225b6cf..c33f143 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -236,7 +236,7 @@
     
     /**
      * Value for {@link #flags}: true when the application knows how to
-     * accomodate different screen densities.  Corresponds to
+     * accommodate different screen densities.  Corresponds to
      * {@link android.R.styleable#AndroidManifestSupportsScreens_anyDensity
      * android:anyDensity}.
      */
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 6a20c93..4a4de51 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -43,6 +43,7 @@
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VersionedPackage;
@@ -273,7 +274,7 @@
 
     String[] setPackagesSuspendedAsUser(in String[] packageNames, boolean suspended,
             in PersistableBundle appExtras, in PersistableBundle launcherExtras,
-            String dialogMessage, String callingPackage, int userId);
+            in SuspendDialogInfo dialogInfo, String callingPackage, int userId);
 
     boolean isPackageSuspendedForUser(String packageName, int userId);
 
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 8fab7bb..e9cfa78 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -86,6 +86,19 @@
  * <p>
  * The ApiDemos project contains examples of using this API:
  * <code>ApiDemos/src/com/example/android/apis/content/InstallApk*.java</code>.
+ * <p>
+ * On Android Q or above, an app installed notification will be posted
+ * by system after a new app is installed.
+ * To customize installer's notification icon, you should declare the following in the manifest
+ * &lt;application> as follows: </p>
+ * <pre>
+ * &lt;meta-data android:name="com.android.packageinstaller.notification.smallIcon"
+ * android:resource="@drawable/installer_notification_icon"/>
+ * </pre>
+ * <pre>
+ * &lt;meta-data android:name="com.android.packageinstaller.notification.color"
+ * android:resource="@color/installer_notification_color"/>
+ * </pre>
  */
 public class PackageInstaller {
     private static final String TAG = "PackageInstaller";
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 19af609..cdb7814 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -16,10 +16,12 @@
 
 package android.content.pm;
 
-import static java.lang.annotation.RetentionPolicy.SOURCE;
+import static android.text.TextUtils.SAFE_STRING_FLAG_FIRST_LINE;
+import static android.text.TextUtils.SAFE_STRING_FLAG_SINGLE_LINE;
+import static android.text.TextUtils.SAFE_STRING_FLAG_TRIM;
+import static android.text.TextUtils.makeSafeForPresentation;
 
 import android.annotation.FloatRange;
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.content.res.XmlResourceParser;
@@ -27,17 +29,13 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.UserHandle;
-import android.text.Html;
-import android.text.TextPaint;
 import android.text.TextUtils;
 import android.util.Printer;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.util.Preconditions;
 
-import java.lang.annotation.Retention;
 import java.text.Collator;
-import java.util.BitSet;
 import java.util.Comparator;
 
 /**
@@ -50,9 +48,6 @@
  * in the implementation of Parcelable in subclasses.
  */
 public class PackageItemInfo {
-    private static final int LINE_FEED_CODE_POINT = 10;
-    private static final int NBSP_CODE_POINT = 160;
-
     /** The maximum length of a safe label, in characters */
     private static final int MAX_SAFE_LABEL_LENGTH = 50000;
 
@@ -60,58 +55,54 @@
     public static final float DEFAULT_MAX_LABEL_SIZE_PX = 500f;
 
     /**
-     * Flags for {@link #loadSafeLabel(PackageManager, float, int)}
-     *
-     * @hide
-     */
-    @Retention(SOURCE)
-    @IntDef(flag = true, prefix = "SAFE_LABEL_FLAG_",
-            value = {SAFE_LABEL_FLAG_TRIM, SAFE_LABEL_FLAG_SINGLE_LINE,
-                    SAFE_LABEL_FLAG_FIRST_LINE})
-    public @interface SafeLabelFlags {}
-
-    /**
      * Remove {@link Character#isWhitespace(int) whitespace} and non-breaking spaces from the edges
      * of the label.
      *
      * @see #loadSafeLabel(PackageManager, float, int)
+     *
+     * @deprecated Use {@link TextUtils#SAFE_STRING_FLAG_TRIM} instead
      * @hide
      */
+    @Deprecated
     @SystemApi
-    public static final int SAFE_LABEL_FLAG_TRIM = 0x1;
+    public static final int SAFE_LABEL_FLAG_TRIM = SAFE_STRING_FLAG_TRIM;
 
     /**
      * Force entire string into single line of text (no newlines). Cannot be set at the same time as
      * {@link #SAFE_LABEL_FLAG_FIRST_LINE}.
      *
      * @see #loadSafeLabel(PackageManager, float, int)
+     *
+     * @deprecated Use {@link TextUtils#SAFE_STRING_FLAG_SINGLE_LINE} instead
      * @hide
      */
+    @Deprecated
     @SystemApi
-    public static final int SAFE_LABEL_FLAG_SINGLE_LINE = 0x2;
+    public static final int SAFE_LABEL_FLAG_SINGLE_LINE = SAFE_STRING_FLAG_SINGLE_LINE;
 
     /**
      * Return only first line of text (truncate at first newline). Cannot be set at the same time as
      * {@link #SAFE_LABEL_FLAG_SINGLE_LINE}.
      *
      * @see #loadSafeLabel(PackageManager, float, int)
+     *
+     * @deprecated Use {@link TextUtils#SAFE_STRING_FLAG_FIRST_LINE} instead
      * @hide
      */
+    @Deprecated
     @SystemApi
-    public static final int SAFE_LABEL_FLAG_FIRST_LINE = 0x4;
+    public static final int SAFE_LABEL_FLAG_FIRST_LINE = SAFE_STRING_FLAG_FIRST_LINE;
 
     private static volatile boolean sForceSafeLabels = false;
 
     /**
      * Always use {@link #loadSafeLabel safe labels} when calling {@link #loadLabel}.
      *
-     * @param forceSafeLabels {@code true} to enforce safe labels
-     *
      * @hide
      */
     @SystemApi
-    public static void setForceSafeLabels(boolean forceSafeLabels) {
-        sForceSafeLabels = forceSafeLabels;
+    public static void forceSafeLabels() {
+        sForceSafeLabels = true;
     }
 
     /**
@@ -201,8 +192,8 @@
      */
     public @NonNull CharSequence loadLabel(@NonNull PackageManager pm) {
         if (sForceSafeLabels) {
-            return loadSafeLabel(pm, DEFAULT_MAX_LABEL_SIZE_PX, SAFE_LABEL_FLAG_TRIM
-                    | SAFE_LABEL_FLAG_FIRST_LINE);
+            return loadSafeLabel(pm, DEFAULT_MAX_LABEL_SIZE_PX, SAFE_STRING_FLAG_TRIM
+                    | SAFE_STRING_FLAG_FIRST_LINE);
         } else {
             return loadUnsafeLabel(pm);
         }
@@ -225,16 +216,6 @@
         return packageName;
     }
 
-    private static boolean isNewline(int codePoint) {
-        int type = Character.getType(codePoint);
-        return type == Character.PARAGRAPH_SEPARATOR || type == Character.LINE_SEPARATOR
-                || codePoint == LINE_FEED_CODE_POINT;
-    }
-
-    private static boolean isWhiteSpace(int codePoint) {
-        return Character.isWhitespace(codePoint) || codePoint == NBSP_CODE_POINT;
-    }
-
     /**
      * @hide
      * @deprecated use loadSafeLabel(PackageManager, float, int) instead
@@ -242,209 +223,24 @@
     @SystemApi
     @Deprecated
     public @NonNull CharSequence loadSafeLabel(@NonNull PackageManager pm) {
-        return loadSafeLabel(pm, DEFAULT_MAX_LABEL_SIZE_PX, SAFE_LABEL_FLAG_TRIM
-                | SAFE_LABEL_FLAG_FIRST_LINE);
+        return loadSafeLabel(pm, DEFAULT_MAX_LABEL_SIZE_PX, SAFE_STRING_FLAG_TRIM
+                | SAFE_STRING_FLAG_FIRST_LINE);
     }
 
     /**
-     * A special string manipulation class. Just records removals and executes the when onString()
-     * is called.
-     */
-    private static class StringWithRemovedChars {
-        /** The original string */
-        private final String mOriginal;
-
-        /**
-         * One bit per char in string. If bit is set, character needs to be removed. If whole
-         * bit field is not initialized nothing needs to be removed.
-         */
-        private BitSet mRemovedChars;
-
-        StringWithRemovedChars(@NonNull String original) {
-            mOriginal = original;
-        }
-
-        /**
-         * Mark all chars in a range {@code [firstRemoved - firstNonRemoved[} (not including
-         * firstNonRemoved) as removed.
-         */
-        void removeRange(int firstRemoved, int firstNonRemoved) {
-            if (mRemovedChars == null) {
-                mRemovedChars = new BitSet(mOriginal.length());
-            }
-
-            mRemovedChars.set(firstRemoved, firstNonRemoved);
-        }
-
-        /**
-         * Remove all characters before {@code firstNonRemoved}.
-         */
-        void removeAllCharBefore(int firstNonRemoved) {
-            if (mRemovedChars == null) {
-                mRemovedChars = new BitSet(mOriginal.length());
-            }
-
-            mRemovedChars.set(0, firstNonRemoved);
-        }
-
-        /**
-         * Remove all characters after and including {@code firstRemoved}.
-         */
-        void removeAllCharAfter(int firstRemoved) {
-            if (mRemovedChars == null) {
-                mRemovedChars = new BitSet(mOriginal.length());
-            }
-
-            mRemovedChars.set(firstRemoved, mOriginal.length());
-        }
-
-        @Override
-        public String toString() {
-            // Common case, no chars removed
-            if (mRemovedChars == null) {
-                return mOriginal;
-            }
-
-            StringBuilder sb = new StringBuilder(mOriginal.length());
-            for (int i = 0; i < mOriginal.length(); i++) {
-                if (!mRemovedChars.get(i)) {
-                    sb.append(mOriginal.charAt(i));
-                }
-            }
-
-            return sb.toString();
-        }
-
-        /**
-         * Return length or the original string
-         */
-        int length() {
-            return mOriginal.length();
-        }
-
-        /**
-         * Return if a certain {@code offset} of the original string is removed
-         */
-        boolean isRemoved(int offset) {
-            return mRemovedChars != null && mRemovedChars.get(offset);
-        }
-
-        /**
-         * Return codePoint of original string at a certain {@code offset}
-         */
-        int codePointAt(int offset) {
-            return mOriginal.codePointAt(offset);
-        }
-    }
-
-    /**
-     * Load, clean up and truncate label before use.
+     * Calls {@link TextUtils#makeSafeForPresentation} for the label of this item.
      *
-     * <p>This method is meant to remove common mistakes and nefarious formatting from strings that
-     * are used in sensitive parts of the UI.
+     * <p>For parameters see {@link TextUtils#makeSafeForPresentation}.
      *
-     * <p>This method first treats the string like HTML and then ...
-     * <ul>
-     * <li>Removes new lines or truncates at first new line
-     * <li>Trims the white-space off the end
-     * <li>Truncates the string to a given length
-     * </ul>
-     * ... if specified.
-     *
-     * @param ellipsizeDip Assuming maximum length of the string (in dip), assuming font size 42.
-     *                     This is roughly 50 characters for {@code ellipsizeDip == 1000}.<br />
-     *                     Usually ellipsizing should be left to the view showing the string. If a
-     *                     string is used as an input to another string, it might be useful to
-     *                     control the length of the input string though. {@code 0} disables this
-     *                     feature.
-     * @return The safe label
      * @hide
-     */
+    */
     @SystemApi
     public @NonNull CharSequence loadSafeLabel(@NonNull PackageManager pm,
-            @FloatRange(from = 0) float ellipsizeDip, @SafeLabelFlags int flags) {
-        boolean onlyKeepFirstLine = ((flags & SAFE_LABEL_FLAG_FIRST_LINE) != 0);
-        boolean forceSingleLine = ((flags & SAFE_LABEL_FLAG_SINGLE_LINE) != 0);
-        boolean trim = ((flags & SAFE_LABEL_FLAG_TRIM) != 0);
-
+            @FloatRange(from = 0) float ellipsizeDip, @TextUtils.SafeStringFlags int flags) {
         Preconditions.checkNotNull(pm);
-        Preconditions.checkArgument(ellipsizeDip >= 0);
-        Preconditions.checkFlagsArgument(flags, SAFE_LABEL_FLAG_TRIM | SAFE_LABEL_FLAG_SINGLE_LINE
-                | SAFE_LABEL_FLAG_FIRST_LINE);
-        Preconditions.checkArgument(!(onlyKeepFirstLine && forceSingleLine),
-                "Cannot set SAFE_LABEL_FLAG_SINGLE_LINE and SAFE_LABEL_FLAG_FIRST_LINE at the same "
-                + "time");
 
-        // loadLabel() always returns non-null
-        String label = loadUnsafeLabel(pm).toString();
-
-        // Treat string as HTML. This
-        // - converts HTML symbols: e.g. &szlig; -> ß
-        // - applies some HTML tags: e.g. <br> -> \n
-        // - removes invalid characters such as \b
-        // - removes html styling, such as <b>
-        // - applies html formatting: e.g. a<p>b</p>c -> a\n\nb\n\nc
-        // - replaces some html tags by "object replacement" markers: <img> -> \ufffc
-        // - Removes leading white space
-        // - Removes all trailing white space beside a single space
-        // - Collapses double white space
-        StringWithRemovedChars labelStr = new StringWithRemovedChars(
-                Html.fromHtml(label).toString());
-
-        int firstNonWhiteSpace = -1;
-        int firstTrailingWhiteSpace = -1;
-
-        // Remove new lines (if requested) and control characters.
-        int labelLength = labelStr.length();
-        for (int offset = 0; offset < labelLength; ) {
-            int codePoint = labelStr.codePointAt(offset);
-            int type = Character.getType(codePoint);
-            int codePointLen = Character.charCount(codePoint);
-            boolean isNewline = isNewline(codePoint);
-
-            if (offset > MAX_SAFE_LABEL_LENGTH || onlyKeepFirstLine && isNewline) {
-                labelStr.removeAllCharAfter(offset);
-                break;
-            } else if (forceSingleLine && isNewline) {
-                labelStr.removeRange(offset, offset + codePointLen);
-            } else if (type == Character.CONTROL && !isNewline) {
-                labelStr.removeRange(offset, offset + codePointLen);
-            } else if (trim && !isWhiteSpace(codePoint)) {
-                // This is only executed if the code point is not removed
-                if (firstNonWhiteSpace == -1) {
-                    firstNonWhiteSpace = offset;
-                }
-                firstTrailingWhiteSpace = offset + codePointLen;
-            }
-
-            offset += codePointLen;
-        }
-
-        if (trim) {
-            // Remove leading and trailing white space
-            if (firstNonWhiteSpace == -1) {
-                // No non whitespace found, remove all
-                labelStr.removeAllCharAfter(0);
-            } else {
-                if (firstNonWhiteSpace > 0) {
-                    labelStr.removeAllCharBefore(firstNonWhiteSpace);
-                }
-                if (firstTrailingWhiteSpace < labelLength) {
-                    labelStr.removeAllCharAfter(firstTrailingWhiteSpace);
-                }
-            }
-        }
-
-        if (ellipsizeDip == 0) {
-            return labelStr.toString();
-        } else {
-            // Truncate
-            final TextPaint paint = new TextPaint();
-            paint.setTextSize(42);
-
-            return TextUtils.ellipsize(labelStr.toString(), paint, ellipsizeDip,
-                    TextUtils.TruncateAt.END);
-        }
+        return makeSafeForPresentation(loadUnsafeLabel(pm).toString(), MAX_SAFE_LABEL_LENGTH,
+                ellipsizeDip, flags);
     }
 
     /**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 3032d16..dfb8128 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -5187,6 +5187,7 @@
      * @param packageName The name of the package to query
      * @throws IllegalArgumentException if the given package name is not installed
      */
+    @Nullable
     public abstract String getInstallerPackageName(String packageName);
 
     /**
@@ -5663,7 +5664,7 @@
      * {@link Manifest.permission#MANAGE_USERS} to use this api.</p>
      *
      * @param packageNames The names of the packages to set the suspended status.
-     * @param suspended If set to {@code true} than the packages will be suspended, if set to
+     * @param suspended If set to {@code true}, the packages will be suspended, if set to
      * {@code false}, the packages will be unsuspended.
      * @param appExtras An optional {@link PersistableBundle} that the suspending app can provide
      *                  which will be shared with the apps being suspended. Ignored if
@@ -5675,15 +5676,76 @@
      *                      suspended app.
      *
      * @return an array of package names for which the suspended status could not be set as
-     * requested in this method.
+     * requested in this method. Returns {@code null} if {@code packageNames} was {@code null}.
+     *
+     * @deprecated use {@link #setPackagesSuspended(String[], boolean, PersistableBundle,
+     * PersistableBundle, android.content.pm.SuspendDialogInfo)} instead.
+     *
+     * @hide
+     */
+    @SystemApi
+    @Deprecated
+    @RequiresPermission(Manifest.permission.SUSPEND_APPS)
+    @Nullable
+    public String[] setPackagesSuspended(@Nullable String[] packageNames, boolean suspended,
+            @Nullable PersistableBundle appExtras, @Nullable PersistableBundle launcherExtras,
+            @Nullable String dialogMessage) {
+        throw new UnsupportedOperationException("setPackagesSuspended not implemented");
+    }
+
+    /**
+     * Puts the given packages in a suspended state, where attempts at starting activities are
+     * denied.
+     *
+     * <p>The suspended application's notifications and all of its windows will be hidden, any
+     * of its started activities will be stopped and it won't be able to ring the device.
+     * It doesn't remove the data or the actual package file.
+     *
+     * <p>When the user tries to launch a suspended app, a system dialog alerting them that the app
+     * is suspended will be shown instead.
+     * The caller can optionally customize the dialog by passing a {@link SuspendDialogInfo} object
+     * to this api. This dialog will have a button that starts the
+     * {@link Intent#ACTION_SHOW_SUSPENDED_APP_DETAILS} intent if the suspending app declares an
+     * activity which handles this action.
+     *
+     * <p>The packages being suspended must already be installed. If a package is uninstalled, it
+     * will no longer be suspended.
+     *
+     * <p>Optionally, the suspending app can provide extra information in the form of
+     * {@link PersistableBundle} objects to be shared with the apps being suspended and the
+     * launcher to support customization that they might need to handle the suspended state.
+     *
+     * <p>The caller must hold {@link Manifest.permission#SUSPEND_APPS} to use this api.
+     *
+     * @param packageNames The names of the packages to set the suspended status.
+     * @param suspended If set to {@code true}, the packages will be suspended, if set to
+     * {@code false}, the packages will be unsuspended.
+     * @param appExtras An optional {@link PersistableBundle} that the suspending app can provide
+     *                  which will be shared with the apps being suspended. Ignored if
+     *                  {@code suspended} is false.
+     * @param launcherExtras An optional {@link PersistableBundle} that the suspending app can
+     *                       provide which will be shared with the launcher. Ignored if
+     *                       {@code suspended} is false.
+     * @param dialogInfo An optional {@link SuspendDialogInfo} object describing the dialog that
+     *                   should be shown to the user when they try to launch a suspended app.
+     *                   Ignored if {@code suspended} is false.
+     *
+     * @return an array of package names for which the suspended status could not be set as
+     * requested in this method. Returns {@code null} if {@code packageNames} was {@code null}.
+     *
+     * @see #isPackageSuspended
+     * @see SuspendDialogInfo
+     * @see SuspendDialogInfo.Builder
+     * @see Intent#ACTION_SHOW_SUSPENDED_APP_DETAILS
      *
      * @hide
      */
     @SystemApi
     @RequiresPermission(Manifest.permission.SUSPEND_APPS)
-    public String[] setPackagesSuspended(String[] packageNames, boolean suspended,
+    @Nullable
+    public String[] setPackagesSuspended(@Nullable String[] packageNames, boolean suspended,
             @Nullable PersistableBundle appExtras, @Nullable PersistableBundle launcherExtras,
-            String dialogMessage) {
+            @Nullable SuspendDialogInfo dialogInfo) {
         throw new UnsupportedOperationException("setPackagesSuspended not implemented");
     }
 
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index b5b4432..4f58321 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.PackageManager.ApplicationInfoFlags;
@@ -205,6 +206,29 @@
             @PackageInfoFlags int flags, int filterCallingUid, int userId);
 
     /**
+     * Return a List of all application packages that are installed on the
+     * device, for a specific user. If flag GET_UNINSTALLED_PACKAGES has been
+     * set, a list of all applications including those deleted with
+     * {@code DONT_DELETE_DATA} (partially installed apps with data directory)
+     * will be returned.
+     *
+     * @param flags Additional option flags to modify the data returned.
+     * @param userId The user for whom the installed applications are to be
+     *            listed
+     * @param callingUid The uid of the original caller app
+     * @return A List of ApplicationInfo objects, one for each installed
+     *         application. In the unlikely case there are no installed
+     *         packages, an empty list is returned. If flag
+     *         {@code MATCH_UNINSTALLED_PACKAGES} is set, the application
+     *         information is retrieved from the list of uninstalled
+     *         applications (which includes installed applications as well as
+     *         applications with data directory i.e. applications which had been
+     *         deleted with {@code DONT_DELETE_DATA} flag set).
+     */
+    public abstract List<ApplicationInfo> getInstalledApplications(
+            @ApplicationInfoFlags int flags, @UserIdInt int userId, int callingUid);
+
+    /**
      * Retrieve launcher extras for a suspended package provided to the system in
      * {@link PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle,
      * PersistableBundle, String)}.
@@ -243,14 +267,15 @@
     public abstract String getSuspendingPackage(String suspendedPackage, int userId);
 
     /**
-     * Get the dialog message to be shown to the user when they try to launch a suspended
-     * application.
+     * Get the information describing the dialog to be shown to the user when they try to launch a
+     * suspended application.
      *
      * @param suspendedPackage The package that has been suspended.
      * @param userId The user for which to check.
-     * @return The dialog message to be shown to the user.
+     * @return A {@link SuspendDialogInfo} object describing the dialog to be shown.
      */
-    public abstract String getSuspendedDialogMessage(String suspendedPackage, int userId);
+    @Nullable
+    public abstract SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, int userId);
 
     /**
      * Do a straight uid lookup for the given package/application in the given user.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index f5431ca..046e9e7 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -47,6 +47,7 @@
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityTaskManager;
+import android.app.AppDetailsActivity;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -2440,17 +2441,17 @@
         }
 
 
-        final int NS = PermissionManager.SPLIT_PERMISSIONS.length;
+        final int NS = PermissionManager.SPLIT_PERMISSIONS.size();
         for (int is=0; is<NS; is++) {
             final PermissionManager.SplitPermissionInfo spi =
-                    PermissionManager.SPLIT_PERMISSIONS[is];
+                    PermissionManager.SPLIT_PERMISSIONS.get(is);
             if (pkg.applicationInfo.targetSdkVersion >= spi.getTargetSdk()
-                    || !pkg.requestedPermissions.contains(spi.getRootPermission())) {
+                    || !pkg.requestedPermissions.contains(spi.getSplitPermission())) {
                 continue;
             }
-            final String[] newPerms = spi.getNewPermissions();
-            for (int in = 0; in < newPerms.length; in++) {
-                final String perm = newPerms[in];
+            final List<String> newPerms = spi.getNewPermissions();
+            for (int in = 0; in < newPerms.size(); in++) {
+                final String perm = newPerms.get(in);
                 if (!pkg.requestedPermissions.contains(perm)) {
                     pkg.requestedPermissions.add(perm);
                 }
@@ -3882,6 +3883,11 @@
             }
         }
 
+        // Add a hidden app detail activity which forwards user to App Details page.
+        Activity a = generateAppDetailsHiddenActivity(owner, flags, outError,
+                owner.baseHardwareAccelerated);
+        owner.activities.add(a);
+
         if (hasActivityOrder) {
             Collections.sort(owner.activities, (a1, a2) -> Integer.compare(a2.order, a1.order));
         }
@@ -4121,9 +4127,14 @@
                 return false;
             }
         } else {
-            outInfo.name
+            String outInfoName
                 = buildClassName(owner.applicationInfo.packageName, name, outError);
-            if (outInfo.name == null) {
+            if (AppDetailsActivity.class.getName().equals(outInfoName)) {
+                outError[0] = tag + " invalid android:name";
+                return false;
+            }
+            outInfo.name = outInfoName;
+            if (outInfoName == null) {
                 return false;
             }
         }
@@ -4162,6 +4173,45 @@
         return true;
     }
 
+    /**
+     * Generate activity object that forwards user to App Details page automatically.
+     * This activity should be invisible to user and user should not know or see it.
+     */
+    private @NonNull PackageParser.Activity generateAppDetailsHiddenActivity(
+            PackageParser.Package owner, int flags, String[] outError,
+            boolean hardwareAccelerated) {
+
+        // Build custom App Details activity info instead of parsing it from xml
+        Activity a = new Activity(owner, AppDetailsActivity.class.getName(), new ActivityInfo());
+        a.owner = owner;
+        a.setPackageName(owner.packageName);
+
+        a.info.theme = 0;
+        a.info.exported = true;
+        a.info.name = AppDetailsActivity.class.getName();
+        a.info.processName = owner.applicationInfo.processName;
+        a.info.uiOptions = a.info.applicationInfo.uiOptions;
+        a.info.taskAffinity = buildTaskAffinityName(owner.packageName, owner.packageName,
+                ":app_details", outError);
+        a.info.enabled = true;
+        a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+        a.info.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NONE;
+        a.info.maxRecents = ActivityTaskManager.getDefaultAppRecentsLimitStatic();
+        a.info.configChanges = getActivityConfigChanges(0, 0);
+        a.info.softInputMode = 0;
+        a.info.persistableMode = ActivityInfo.PERSIST_NEVER;
+        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.rotationAnimation = ROTATION_ANIMATION_UNSPECIFIED;
+        a.info.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
+        if (hardwareAccelerated) {
+            a.info.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED;
+        }
+        return a;
+    }
+
     private Activity parseActivity(Package owner, Resources res,
             XmlResourceParser parser, int flags, String[] outError, CachedComponentArgs cachedArgs,
             boolean receiver, boolean hardwareAccelerated)
@@ -5785,52 +5835,32 @@
             int AUTH = 16;
         }
 
-        /**
-         * APK Signature Scheme v3 includes support for adding a proof-of-rotation record that
-         * contains two pieces of information:
-         *   1) the past signing certificates
-         *   2) the flags that APK wants to assign to each of the past signing certificates.
-         *
-         * These flags, which have a one-to-one relationship for the {@code pastSigningCertificates}
-         * collection, represent the second piece of information and are viewed as capabilities.
-         * They are an APK's way of telling the platform: "this is how I want to trust my old certs,
-         * please enforce that." This is useful for situation where this app itself is using its
-         * signing certificate as an authorization mechanism, like whether or not to allow another
-         * app to have its SIGNATURE permission.  An app could specify whether to allow other apps
-         * signed by its old cert 'X' to still get a signature permission it defines, for example.
-         */
-        @Nullable
-        public final int[] pastSigningCertificatesFlags;
-
         /** A representation of unknown signing details. Use instead of null. */
         public static final SigningDetails UNKNOWN =
-                new SigningDetails(null, SignatureSchemeVersion.UNKNOWN, null, null, null);
+                new SigningDetails(null, SignatureSchemeVersion.UNKNOWN, null, null);
 
         @VisibleForTesting
         public SigningDetails(Signature[] signatures,
                 @SignatureSchemeVersion int signatureSchemeVersion,
-                ArraySet<PublicKey> keys, Signature[] pastSigningCertificates,
-                int[] pastSigningCertificatesFlags) {
+                ArraySet<PublicKey> keys, Signature[] pastSigningCertificates) {
             this.signatures = signatures;
             this.signatureSchemeVersion = signatureSchemeVersion;
             this.publicKeys = keys;
             this.pastSigningCertificates = pastSigningCertificates;
-            this.pastSigningCertificatesFlags = pastSigningCertificatesFlags;
         }
 
         public SigningDetails(Signature[] signatures,
                 @SignatureSchemeVersion int signatureSchemeVersion,
-                Signature[] pastSigningCertificates, int[] pastSigningCertificatesFlags)
+                Signature[] pastSigningCertificates)
                 throws CertificateException {
             this(signatures, signatureSchemeVersion, toSigningKeys(signatures),
-                    pastSigningCertificates, pastSigningCertificatesFlags);
+                    pastSigningCertificates);
         }
 
         public SigningDetails(Signature[] signatures,
                 @SignatureSchemeVersion int signatureSchemeVersion)
                 throws CertificateException {
-            this(signatures, signatureSchemeVersion,
-                    null, null);
+            this(signatures, signatureSchemeVersion, null);
         }
 
         public SigningDetails(SigningDetails orig) {
@@ -5844,17 +5874,14 @@
                 this.publicKeys = new ArraySet<>(orig.publicKeys);
                 if (orig.pastSigningCertificates != null) {
                     this.pastSigningCertificates = orig.pastSigningCertificates.clone();
-                    this.pastSigningCertificatesFlags = orig.pastSigningCertificatesFlags.clone();
                 } else {
                     this.pastSigningCertificates = null;
-                    this.pastSigningCertificatesFlags = null;
                 }
             } else {
                 this.signatures = null;
                 this.signatureSchemeVersion = SignatureSchemeVersion.UNKNOWN;
                 this.publicKeys = null;
                 this.pastSigningCertificates = null;
-                this.pastSigningCertificatesFlags = null;
             }
         }
 
@@ -5956,7 +5983,7 @@
                     if (Signature.areEffectiveMatch(
                             oldDetails.signatures[0],
                             pastSigningCertificates[i])
-                            && pastSigningCertificatesFlags[i] == flags) {
+                            && pastSigningCertificates[i].getFlags() == flags) {
                         return true;
                     }
                 }
@@ -6006,7 +6033,7 @@
                 for (int i = 0; i < pastSigningCertificates.length - 1; i++) {
                     if (pastSigningCertificates[i].equals(signature)) {
                         if (flags == PAST_CERT_EXISTS
-                                || (flags & pastSigningCertificatesFlags[i]) == flags) {
+                                || (flags & pastSigningCertificates[i].getFlags()) == flags) {
                             return true;
                         }
                     }
@@ -6090,7 +6117,7 @@
                             pastSigningCertificates[i].toByteArray());
                     if (Arrays.equals(sha256Certificate, digest)) {
                         if (flags == PAST_CERT_EXISTS
-                                || (flags & pastSigningCertificatesFlags[i]) == flags) {
+                                || (flags & pastSigningCertificates[i].getFlags()) == flags) {
                             return true;
                         }
                     }
@@ -6127,7 +6154,6 @@
             dest.writeInt(this.signatureSchemeVersion);
             dest.writeArraySet(this.publicKeys);
             dest.writeTypedArray(this.pastSigningCertificates, flags);
-            dest.writeIntArray(this.pastSigningCertificatesFlags);
         }
 
         protected SigningDetails(Parcel in) {
@@ -6136,7 +6162,6 @@
             this.signatureSchemeVersion = in.readInt();
             this.publicKeys = (ArraySet<PublicKey>) in.readArraySet(boot);
             this.pastSigningCertificates = in.createTypedArray(Signature.CREATOR);
-            this.pastSigningCertificatesFlags = in.createIntArray();
         }
 
         public static final Creator<SigningDetails> CREATOR = new Creator<SigningDetails>() {
@@ -6175,9 +6200,6 @@
             if (!Arrays.equals(pastSigningCertificates, that.pastSigningCertificates)) {
                 return false;
             }
-            if (!Arrays.equals(pastSigningCertificatesFlags, that.pastSigningCertificatesFlags)) {
-                return false;
-            }
 
             return true;
         }
@@ -6188,7 +6210,6 @@
             result = 31 * result + signatureSchemeVersion;
             result = 31 * result + (publicKeys != null ? publicKeys.hashCode() : 0);
             result = 31 * result + Arrays.hashCode(pastSigningCertificates);
-            result = 31 * result + Arrays.hashCode(pastSigningCertificatesFlags);
             return result;
         }
 
@@ -6199,7 +6220,6 @@
             private Signature[] mSignatures;
             private int mSignatureSchemeVersion = SignatureSchemeVersion.UNKNOWN;
             private Signature[] mPastSigningCertificates;
-            private int[] mPastSigningCertificatesFlags;
 
             @UnsupportedAppUsage
             public Builder() {
@@ -6226,34 +6246,12 @@
                 return this;
             }
 
-            /** set the flags for the {@code pastSigningCertificates} */
-            @UnsupportedAppUsage
-            public Builder setPastSigningCertificatesFlags(int[] pastSigningCertificatesFlags) {
-                mPastSigningCertificatesFlags = pastSigningCertificatesFlags;
-                return this;
-            }
-
             private void checkInvariants() {
                 // must have signatures and scheme version set
                 if (mSignatures == null) {
                     throw new IllegalStateException("SigningDetails requires the current signing"
                             + " certificates.");
                 }
-
-                // pastSigningCerts and flags must match up
-                boolean pastMismatch = false;
-                if (mPastSigningCertificates != null && mPastSigningCertificatesFlags != null) {
-                    if (mPastSigningCertificates.length != mPastSigningCertificatesFlags.length) {
-                        pastMismatch = true;
-                    }
-                } else if (!(mPastSigningCertificates == null
-                        && mPastSigningCertificatesFlags == null)) {
-                    pastMismatch = true;
-                }
-                if (pastMismatch) {
-                    throw new IllegalStateException("SigningDetails must have a one to one mapping "
-                            + "between pastSigningCertificates and pastSigningCertificatesFlags");
-                }
             }
             /** build a {@code SigningDetails} object */
             @UnsupportedAppUsage
@@ -6261,7 +6259,7 @@
                     throws CertificateException {
                 checkInvariants();
                 return new SigningDetails(mSignatures, mSignatureSchemeVersion,
-                        mPastSigningCertificates, mPastSigningCertificatesFlags);
+                        mPastSigningCertificates);
             }
         }
     }
@@ -7184,10 +7182,16 @@
         ComponentName componentName;
         String componentShortName;
 
-        public Component(Package _owner) {
-            owner = _owner;
-            intents = null;
-            className = null;
+        public Component(Package owner, ArrayList<II> intents, String className) {
+            this.owner = owner;
+            this.intents = intents;
+            this.className = className;
+        }
+
+        public Component(Package owner) {
+            this.owner = owner;
+            this.intents = null;
+            this.className = null;
         }
 
         public Component(final ParsePackageItemArgs args, final PackageItemInfo outInfo) {
@@ -7652,6 +7656,13 @@
             return mHasMaxAspectRatio;
         }
 
+        // To construct custom activity which does not exist in manifest
+        Activity(final Package owner, final String className, final ActivityInfo info) {
+            super(owner, new ArrayList<>(0), className);
+            this.info = info;
+            this.info.applicationInfo = owner.applicationInfo;
+        }
+
         public Activity(final ParseComponentArgs args, final ActivityInfo _info) {
             super(args, _info);
             info = _info;
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 248d523..e21c33a 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -33,6 +33,7 @@
 import android.os.PersistableBundle;
 import android.util.ArraySet;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ArrayUtils;
 
 import java.util.Arrays;
@@ -50,7 +51,7 @@
     public boolean hidden; // Is the app restricted by owner / admin
     public boolean suspended;
     public String suspendingPackage;
-    public String dialogMessage; // Message to show when a suspended package launch attempt is made
+    public SuspendDialogInfo dialogInfo;
     public PersistableBundle suspendedAppExtras;
     public PersistableBundle suspendedLauncherExtras;
     public boolean instantApp;
@@ -79,6 +80,7 @@
         installReason = PackageManager.INSTALL_REASON_UNKNOWN;
     }
 
+    @VisibleForTesting
     public PackageUserState(PackageUserState o) {
         ceDataInode = o.ceDataInode;
         installed = o.installed;
@@ -87,7 +89,7 @@
         hidden = o.hidden;
         suspended = o.suspended;
         suspendingPackage = o.suspendingPackage;
-        dialogMessage = o.dialogMessage;
+        dialogInfo = o.dialogInfo;
         suspendedAppExtras = o.suspendedAppExtras;
         suspendedLauncherExtras = o.suspendedLauncherExtras;
         instantApp = o.instantApp;
@@ -217,7 +219,7 @@
                     || !suspendingPackage.equals(oldState.suspendingPackage)) {
                 return false;
             }
-            if (!Objects.equals(dialogMessage, oldState.dialogMessage)) {
+            if (!Objects.equals(dialogInfo, oldState.dialogInfo)) {
                 return false;
             }
             if (!BaseBundle.kindofEquals(suspendedAppExtras,
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
index e58ca60..349bb69 100644
--- a/core/java/android/content/pm/Signature.java
+++ b/core/java/android/content/pm/Signature.java
@@ -45,6 +45,20 @@
     private boolean mHaveHashCode;
     private SoftReference<String> mStringRef;
     private Certificate[] mCertificateChain;
+    /**
+     * APK Signature Scheme v3 includes support for adding a proof-of-rotation record that
+     * contains two pieces of information:
+     *   1) the past signing certificates
+     *   2) the flags that APK wants to assign to each of the past signing certificates.
+     *
+     * These flags represent the second piece of information and are viewed as capabilities.
+     * They are an APK's way of telling the platform: "this is how I want to trust my old certs,
+     * please enforce that." This is useful for situation where this app itself is using its
+     * signing certificate as an authorization mechanism, like whether or not to allow another
+     * app to have its SIGNATURE permission.  An app could specify whether to allow other apps
+     * signed by its old cert 'X' to still get a signature permission it defines, for example.
+     */
+    private int mFlags;
 
     /**
      * Create Signature from an existing raw byte array.
@@ -109,6 +123,22 @@
     }
 
     /**
+     * Sets the flags representing the capabilities of the past signing certificate.
+     * @hide
+     */
+    public void setFlags(int flags) {
+        this.mFlags = flags;
+    }
+
+    /**
+     * Returns the flags representing the capabilities of the past signing certificate.
+     * @hide
+     */
+    public int getFlags() {
+        return mFlags;
+    }
+
+    /**
      * Encode the Signature as ASCII text.
      */
     public char[] toChars() {
@@ -328,4 +358,4 @@
 
         return sPrime;
     }
-}
+}
\ No newline at end of file
diff --git a/proto/src/stats_enums.proto b/core/java/android/content/pm/SuspendDialogInfo.aidl
similarity index 76%
copy from proto/src/stats_enums.proto
copy to core/java/android/content/pm/SuspendDialogInfo.aidl
index 6c892cf..5e711cf 100644
--- a/proto/src/stats_enums.proto
+++ b/core/java/android/content/pm/SuspendDialogInfo.aidl
@@ -13,14 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package android.content.pm;
 
-syntax = "proto2";
-
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "StatsEnums";
-
-enum EventType {
-  // Unknown.
-  TYPE_UNKNOWN = 0;
-}
+parcelable SuspendDialogInfo;
diff --git a/core/java/android/content/pm/SuspendDialogInfo.java b/core/java/android/content/pm/SuspendDialogInfo.java
new file mode 100644
index 0000000..c798c99
--- /dev/null
+++ b/core/java/android/content/pm/SuspendDialogInfo.java
@@ -0,0 +1,379 @@
+/*
+ * 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.content.pm;
+
+import static android.content.res.ResourceId.ID_NULL;
+
+import android.annotation.DrawableRes;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StringRes;
+import android.annotation.SystemApi;
+import android.content.res.ResourceId;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+import android.util.Slog;
+
+import com.android.internal.util.Preconditions;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlSerializer;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * A container to describe the dialog to be shown when the user tries to launch a suspended
+ * application.
+ * The suspending app can customize the dialog's following attributes:
+ * <ul>
+ * <li>The dialog icon, by providing a resource id.
+ * <li>The title text, by providing a resource id.
+ * <li>The text of the dialog's body, by providing a resource id or a string.
+ * <li>The text on the neutral button which starts the
+ * {@link android.content.Intent#ACTION_SHOW_SUSPENDED_APP_DETAILS SHOW_SUSPENDED_APP_DETAILS}
+ * activity, by providing a resource id.
+ * </ul>
+ * System defaults are used whenever any of these are not provided, or any of the provided resource
+ * ids cannot be resolved at the time of displaying the dialog.
+ *
+ * @hide
+ * @see PackageManager#setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle,
+ * SuspendDialogInfo)
+ * @see Builder
+ */
+@SystemApi
+public final class SuspendDialogInfo implements Parcelable {
+    private static final String TAG = SuspendDialogInfo.class.getSimpleName();
+    private static final String XML_ATTR_ICON_RES_ID = "iconResId";
+    private static final String XML_ATTR_TITLE_RES_ID = "titleResId";
+    private static final String XML_ATTR_DIALOG_MESSAGE_RES_ID = "dialogMessageResId";
+    private static final String XML_ATTR_DIALOG_MESSAGE = "dialogMessage";
+    private static final String XML_ATTR_BUTTON_TEXT_RES_ID = "buttonTextResId";
+
+    private final int mIconResId;
+    private final int mTitleResId;
+    private final int mDialogMessageResId;
+    private final String mDialogMessage;
+    private final int mNeutralButtonTextResId;
+
+    /**
+     * @return the resource id of the icon to be used with the dialog
+     * @hide
+     */
+    @DrawableRes
+    public int getIconResId() {
+        return mIconResId;
+    }
+
+    /**
+     * @return the resource id of the title to be used with the dialog
+     * @hide
+     */
+    @StringRes
+    public int getTitleResId() {
+        return mTitleResId;
+    }
+
+    /**
+     * @return the resource id of the text to be shown in the dialog's body
+     * @hide
+     */
+    @StringRes
+    public int getDialogMessageResId() {
+        return mDialogMessageResId;
+    }
+
+    /**
+     * @return the text to be shown in the dialog's body. Returns {@code null} if
+     * {@link #getDialogMessageResId()} returns a valid resource id.
+     * @hide
+     */
+    @Nullable
+    public String getDialogMessage() {
+        return mDialogMessage;
+    }
+
+    /**
+     * @return the text to be shown
+     * @hide
+     */
+    @StringRes
+    public int getNeutralButtonTextResId() {
+        return mNeutralButtonTextResId;
+    }
+
+    /**
+     * @hide
+     */
+    public void saveToXml(XmlSerializer out) throws IOException {
+        if (mIconResId != ID_NULL) {
+            XmlUtils.writeIntAttribute(out, XML_ATTR_ICON_RES_ID, mIconResId);
+        }
+        if (mTitleResId != ID_NULL) {
+            XmlUtils.writeIntAttribute(out, XML_ATTR_TITLE_RES_ID, mTitleResId);
+        }
+        if (mDialogMessageResId != ID_NULL) {
+            XmlUtils.writeIntAttribute(out, XML_ATTR_DIALOG_MESSAGE_RES_ID, mDialogMessageResId);
+        } else {
+            XmlUtils.writeStringAttribute(out, XML_ATTR_DIALOG_MESSAGE, mDialogMessage);
+        }
+        if (mNeutralButtonTextResId != ID_NULL) {
+            XmlUtils.writeIntAttribute(out, XML_ATTR_BUTTON_TEXT_RES_ID, mNeutralButtonTextResId);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static SuspendDialogInfo restoreFromXml(XmlPullParser in) {
+        final SuspendDialogInfo.Builder dialogInfoBuilder = new SuspendDialogInfo.Builder();
+        try {
+            final int iconId = XmlUtils.readIntAttribute(in, XML_ATTR_ICON_RES_ID, ID_NULL);
+            final int titleId = XmlUtils.readIntAttribute(in, XML_ATTR_TITLE_RES_ID, ID_NULL);
+            final int buttonTextId = XmlUtils.readIntAttribute(in, XML_ATTR_BUTTON_TEXT_RES_ID,
+                    ID_NULL);
+            final int dialogMessageResId = XmlUtils.readIntAttribute(
+                    in, XML_ATTR_DIALOG_MESSAGE_RES_ID, ID_NULL);
+            final String dialogMessage = XmlUtils.readStringAttribute(in, XML_ATTR_DIALOG_MESSAGE);
+
+            if (iconId != ID_NULL) {
+                dialogInfoBuilder.setIcon(iconId);
+            }
+            if (titleId != ID_NULL) {
+                dialogInfoBuilder.setTitle(titleId);
+            }
+            if (buttonTextId != ID_NULL) {
+                dialogInfoBuilder.setNeutralButtonText(buttonTextId);
+            }
+            if (dialogMessageResId != ID_NULL) {
+                dialogInfoBuilder.setMessage(dialogMessageResId);
+            } else if (dialogMessage != null) {
+                dialogInfoBuilder.setMessage(dialogMessage);
+            }
+        } catch (Exception e) {
+            Slog.e(TAG, "Exception while parsing from xml. Some fields may default", e);
+        }
+        return dialogInfoBuilder.build();
+    }
+
+    @Override
+    public int hashCode() {
+        int hashCode = mIconResId;
+        hashCode = 31 * hashCode + mTitleResId;
+        hashCode = 31 * hashCode + mNeutralButtonTextResId;
+        hashCode = 31 * hashCode + mDialogMessageResId;
+        hashCode = 31 * hashCode + Objects.hashCode(mDialogMessage);
+        return hashCode;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof SuspendDialogInfo)) {
+            return false;
+        }
+        final SuspendDialogInfo otherDialogInfo = (SuspendDialogInfo) obj;
+        return mIconResId == otherDialogInfo.mIconResId
+                && mTitleResId == otherDialogInfo.mTitleResId
+                && mDialogMessageResId == otherDialogInfo.mDialogMessageResId
+                && mNeutralButtonTextResId == otherDialogInfo.mNeutralButtonTextResId
+                && Objects.equals(mDialogMessage, otherDialogInfo.mDialogMessage);
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder builder = new StringBuilder("SuspendDialogInfo: {");
+        if (mIconResId != ID_NULL) {
+            builder.append("mIconId = 0x");
+            builder.append(Integer.toHexString(mIconResId));
+            builder.append(" ");
+        }
+        if (mTitleResId != ID_NULL) {
+            builder.append("mTitleResId = 0x");
+            builder.append(Integer.toHexString(mTitleResId));
+            builder.append(" ");
+        }
+        if (mNeutralButtonTextResId != ID_NULL) {
+            builder.append("mNeutralButtonTextResId = 0x");
+            builder.append(Integer.toHexString(mNeutralButtonTextResId));
+            builder.append(" ");
+        }
+        if (mDialogMessageResId != ID_NULL) {
+            builder.append("mDialogMessageResId = 0x");
+            builder.append(Integer.toHexString(mDialogMessageResId));
+            builder.append(" ");
+        } else if (mDialogMessage != null) {
+            builder.append("mDialogMessage = \"");
+            builder.append(mDialogMessage);
+            builder.append("\" ");
+        }
+        builder.append("}");
+        return builder.toString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int parcelableFlags) {
+        dest.writeInt(mIconResId);
+        dest.writeInt(mTitleResId);
+        dest.writeInt(mDialogMessageResId);
+        dest.writeString(mDialogMessage);
+        dest.writeInt(mNeutralButtonTextResId);
+    }
+
+    private SuspendDialogInfo(Parcel source) {
+        mIconResId = source.readInt();
+        mTitleResId = source.readInt();
+        mDialogMessageResId = source.readInt();
+        mDialogMessage = source.readString();
+        mNeutralButtonTextResId = source.readInt();
+    }
+
+    SuspendDialogInfo(Builder b) {
+        mIconResId = b.mIconResId;
+        mTitleResId = b.mTitleResId;
+        mDialogMessageResId = b.mDialogMessageResId;
+        mDialogMessage = (mDialogMessageResId == ID_NULL) ? b.mDialogMessage : null;
+        mNeutralButtonTextResId = b.mNeutralButtonTextResId;
+    }
+
+    public static final Creator<SuspendDialogInfo> CREATOR = new Creator<SuspendDialogInfo>() {
+        @Override
+        public SuspendDialogInfo createFromParcel(Parcel source) {
+            return new SuspendDialogInfo(source);
+        }
+
+        @Override
+        public SuspendDialogInfo[] newArray(int size) {
+            return new SuspendDialogInfo[size];
+        }
+    };
+
+    /**
+     * Builder to build a {@link SuspendDialogInfo} object.
+     */
+    public static final class Builder {
+        private int mDialogMessageResId = ID_NULL;
+        private String mDialogMessage;
+        private int mTitleResId = ID_NULL;
+        private int mIconResId = ID_NULL;
+        private int mNeutralButtonTextResId = ID_NULL;
+
+        /**
+         * Set the resource id of the icon to be used. If not provided, no icon will be shown.
+         *
+         * @param resId The resource id of the icon.
+         * @return this builder object.
+         */
+        @NonNull
+        public Builder setIcon(@DrawableRes int resId) {
+            Preconditions.checkArgument(ResourceId.isValid(resId), "Invalid resource id provided");
+            mIconResId = resId;
+            return this;
+        }
+
+        /**
+         * Set the resource id of the title text to be displayed. If this is not provided, the
+         * system will use a default title.
+         *
+         * @param resId The resource id of the title.
+         * @return this builder object.
+         */
+        @NonNull
+        public Builder setTitle(@StringRes int resId) {
+            Preconditions.checkArgument(ResourceId.isValid(resId), "Invalid resource id provided");
+            mTitleResId = resId;
+            return this;
+        }
+
+        /**
+         * Set the text to show in the body of the dialog. Ignored if a resource id is set via
+         * {@link #setMessage(int)}.
+         * <p>
+         * The system will use {@link String#format(Locale, String, Object...) String.format} to
+         * insert the suspended app name into the message, so an example format string could be
+         * {@code "The app %1$s is currently suspended"}. This is optional - if the string passed in
+         * {@code message} does not accept an argument, it will be used as is.
+         *
+         * @param message The dialog message.
+         * @return this builder object.
+         * @see #setMessage(int)
+         */
+        @NonNull
+        public Builder setMessage(@NonNull String message) {
+            Preconditions.checkStringNotEmpty(message, "Message cannot be null or empty");
+            mDialogMessage = message;
+            return this;
+        }
+
+        /**
+         * Set the resource id of the dialog message to be shown. If no dialog message is provided
+         * via either this method or {@link #setMessage(String)}, the system will use a
+         * default message.
+         * <p>
+         * The system will use {@link android.content.res.Resources#getString(int, Object...)
+         * getString} to insert the suspended app name into the message, so an example format string
+         * could be {@code "The app %1$s is currently suspended"}. This is optional - if the string
+         * referred to by {@code resId} does not accept an argument, it will be used as is.
+         *
+         * @param resId The resource id of the dialog message.
+         * @return this builder object.
+         * @see #setMessage(String)
+         */
+        @NonNull
+        public Builder setMessage(@StringRes int resId) {
+            Preconditions.checkArgument(ResourceId.isValid(resId), "Invalid resource id provided");
+            mDialogMessageResId = resId;
+            return this;
+        }
+
+        /**
+         * Set the resource id of text to be shown on the neutral button. Tapping this button starts
+         * the {@link android.content.Intent#ACTION_SHOW_SUSPENDED_APP_DETAILS} activity. If this is
+         * not provided, the system will use a default text.
+         *
+         * @param resId The resource id of the button text
+         * @return this builder object.
+         */
+        @NonNull
+        public Builder setNeutralButtonText(@StringRes int resId) {
+            Preconditions.checkArgument(ResourceId.isValid(resId), "Invalid resource id provided");
+            mNeutralButtonTextResId = resId;
+            return this;
+        }
+
+        /**
+         * Build the final object based on given inputs.
+         *
+         * @return The {@link SuspendDialogInfo} object built using this builder.
+         */
+        @NonNull
+        public SuspendDialogInfo build() {
+            return new SuspendDialogInfo(this);
+        }
+    }
+}
diff --git a/core/java/android/database/DefaultDatabaseErrorHandler.java b/core/java/android/database/DefaultDatabaseErrorHandler.java
index 7fa2b40..cf019e1 100755
--- a/core/java/android/database/DefaultDatabaseErrorHandler.java
+++ b/core/java/android/database/DefaultDatabaseErrorHandler.java
@@ -15,14 +15,14 @@
  */
 package android.database;
 
-import java.io.File;
-import java.util.List;
-
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
 import android.util.Log;
 import android.util.Pair;
 
+import java.io.File;
+import java.util.List;
+
 /**
  * Default class used to define the action to take when database corruption is reported
  * by sqlite.
@@ -52,6 +52,7 @@
      */
     public void onCorruption(SQLiteDatabase dbObj) {
         Log.e(TAG, "Corruption reported by sqlite on database: " + dbObj.getPath());
+        SQLiteDatabase.wipeDetected(dbObj.getPath(), "corruption");
 
         // is the corruption detected even before database could be 'opened'?
         if (!dbObj.isOpen()) {
@@ -99,7 +100,7 @@
         }
         Log.e(TAG, "deleting the database file: " + fileName);
         try {
-            SQLiteDatabase.deleteDatabase(new File(fileName));
+            SQLiteDatabase.deleteDatabase(new File(fileName), /*removeCheckFile=*/ false);
         } catch (Exception e) {
             /* print warning and ignore exception */
             Log.w(TAG, "delete failed: " + e.getMessage());
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
index 5c4f16a..20505ca 100644
--- a/core/java/android/database/sqlite/SQLiteConnection.java
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -34,6 +34,7 @@
 import dalvik.system.CloseGuard;
 
 import java.io.File;
+import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
@@ -414,6 +415,10 @@
         final String newLocale = mConfiguration.locale.toString();
         nativeRegisterLocalizedCollators(mConnectionPtr, newLocale);
 
+        if (!mConfiguration.isInMemoryDb()) {
+            checkDatabaseWiped();
+        }
+
         // If the database is read-only, we cannot modify the android metadata table
         // or existing indexes.
         if (mIsReadOnlyConnection) {
@@ -449,6 +454,36 @@
         }
     }
 
+    private void checkDatabaseWiped() {
+        if (!SQLiteGlobal.checkDbWipe()) {
+            return;
+        }
+        try {
+            final File checkFile = new File(mConfiguration.path
+                    + SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX);
+
+            final boolean hasMetadataTable = executeForLong(
+                    "SELECT count(*) FROM sqlite_master"
+                            + " WHERE type='table' AND name='android_metadata'", null, null) > 0;
+            final boolean hasCheckFile = checkFile.exists();
+
+            if (!mIsReadOnlyConnection && !hasCheckFile) {
+                // Create the check file, unless it's a readonly connection,
+                // in which case we can't create the metadata table anyway.
+                checkFile.createNewFile();
+            }
+
+            if (!hasMetadataTable && hasCheckFile) {
+                // Bad. The DB is gone unexpectedly.
+                SQLiteDatabase.wipeDetected(mConfiguration.path, "unknown");
+            }
+
+        } catch (RuntimeException | IOException ex) {
+            SQLiteDatabase.wtfAsSystemServer(TAG,
+                    "Unexpected exception while checking for wipe", ex);
+        }
+    }
+
     // Called by SQLiteConnectionPool only.
     void reconfigure(SQLiteDatabaseConfiguration configuration) {
         mOnlyAllowReadOnlyOperations = false;
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
index 3ee348b..dbc1766 100644
--- a/core/java/android/database/sqlite/SQLiteConnectionPool.java
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -24,6 +24,7 @@
 import android.os.OperationCanceledException;
 import android.os.SystemClock;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.PrefixPrinter;
 import android.util.Printer;
@@ -34,6 +35,7 @@
 import dalvik.system.CloseGuard;
 
 import java.io.Closeable;
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Map;
 import java.util.WeakHashMap;
@@ -1105,9 +1107,12 @@
      * @param printer The printer to receive the dump, not null.
      * @param verbose True to dump more verbose information.
      */
-    public void dump(Printer printer, boolean verbose) {
+    public void dump(Printer printer, boolean verbose, ArraySet<String> directories) {
         Printer indentedPrinter = PrefixPrinter.create(printer, "    ");
         synchronized (mLock) {
+            if (directories != null) {
+                directories.add(new File(mConfiguration.path).getParent());
+            }
             printer.println("Connection pool for " + mConfiguration.path + ":");
             printer.println("  Open: " + mIsOpen);
             printer.println("  Max connections: " + mMaxConnectionPoolSize);
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index eb5c720..f9c2c3e 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -22,6 +22,8 @@
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
+import android.app.ActivityThread;
+import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.database.Cursor;
 import android.database.DatabaseErrorHandler;
@@ -34,6 +36,7 @@
 import android.os.OperationCanceledException;
 import android.os.SystemProperties;
 import android.text.TextUtils;
+import android.util.ArraySet;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Pair;
@@ -45,9 +48,14 @@
 
 import java.io.File;
 import java.io.FileFilter;
+import java.io.IOException;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
@@ -808,6 +816,12 @@
      * @return True if the database was successfully deleted.
      */
     public static boolean deleteDatabase(@NonNull File file) {
+        return deleteDatabase(file, /*removeCheckFile=*/ true);
+    }
+
+
+    /** @hide */
+    public static boolean deleteDatabase(@NonNull File file, boolean removeCheckFile) {
         if (file == null) {
             throw new IllegalArgumentException("file must not be null");
         }
@@ -818,6 +832,9 @@
         deleted |= new File(file.getPath() + "-shm").delete();
         deleted |= new File(file.getPath() + "-wal").delete();
 
+        // This file is not a standard SQLite file, so don't update the deleted flag.
+        new File(file.getPath() + SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX).delete();
+
         File dir = file.getParentFile();
         if (dir != null) {
             final String prefix = file.getName() + "-mj";
@@ -2170,21 +2187,61 @@
      * Dump detailed information about all open databases in the current process.
      * Used by bug report.
      */
-    static void dumpAll(Printer printer, boolean verbose) {
+    static void dumpAll(Printer printer, boolean verbose, boolean isSystem) {
+        // Use this ArraySet to collect file paths.
+        final ArraySet<String> directories = new ArraySet<>();
+
         for (SQLiteDatabase db : getActiveDatabases()) {
-            db.dump(printer, verbose);
+            db.dump(printer, verbose, isSystem, directories);
+        }
+
+        // Dump DB files in the directories.
+        if (directories.size() > 0) {
+            final String[] dirs = directories.toArray(new String[directories.size()]);
+            Arrays.sort(dirs);
+            for (String dir : dirs) {
+                dumpDatabaseDirectory(printer, new File(dir), isSystem);
+            }
         }
     }
 
-    private void dump(Printer printer, boolean verbose) {
+    private void dump(Printer printer, boolean verbose, boolean isSystem, ArraySet directories) {
         synchronized (mLock) {
             if (mConnectionPoolLocked != null) {
                 printer.println("");
-                mConnectionPoolLocked.dump(printer, verbose);
+                mConnectionPoolLocked.dump(printer, verbose, directories);
             }
         }
     }
 
+    private static void dumpDatabaseDirectory(Printer pw, File dir, boolean isSystem) {
+        pw.println("");
+        pw.println("Database files in " + dir.getAbsolutePath() + ":");
+        final File[] files = dir.listFiles();
+        if (files == null || files.length == 0) {
+            pw.println("  [none]");
+            return;
+        }
+        Arrays.sort(files, (a, b) -> a.getName().compareTo(b.getName()));
+
+        for (File f : files) {
+            if (isSystem) {
+                // If called within the system server, the directory contains other files too, so
+                // filter by file extensions.
+                // (If it's an app, just print all files because they may not use *.db
+                // extension.)
+                final String name = f.getName();
+                if (!(name.endsWith(".db") || name.endsWith(".db-wal")
+                        || name.endsWith(".db-journal")
+                        || name.endsWith(SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX))) {
+                    continue;
+                }
+            }
+            pw.println(String.format("  %-40s %7db %s", f.getName(), f.length(),
+                    SQLiteDatabase.getFileTimestamps(f.getAbsolutePath())));
+        }
+    }
+
     /**
      * Returns list of full pathnames of all attached databases including the main database
      * by executing 'pragma database_list' on the database.
@@ -2611,7 +2668,7 @@
                 return this;
             }
 
-            /**
+            /**w
              * Sets <a href="https://sqlite.org/pragma.html#pragma_synchronous">synchronous mode</a>
              * .
              * @return
@@ -2646,5 +2703,34 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface DatabaseOpenFlags {}
 
+    /** @hide */
+    public static void wipeDetected(String filename, String reason) {
+        wtfAsSystemServer(TAG, "DB wipe detected:"
+                + " package=" + ActivityThread.currentPackageName()
+                + " reason=" + reason
+                + " file=" + filename
+                + " " + getFileTimestamps(filename)
+                + " checkfile " + getFileTimestamps(filename + SQLiteGlobal.WIPE_CHECK_FILE_SUFFIX),
+                new Throwable("STACKTRACE"));
+    }
+
+    /** @hide */
+    public static String getFileTimestamps(String path) {
+        try {
+            BasicFileAttributes attr = Files.readAttributes(
+                    FileSystems.getDefault().getPath(path), BasicFileAttributes.class);
+            return "ctime=" + attr.creationTime()
+                    + " mtime=" + attr.lastModifiedTime()
+                    + " atime=" + attr.lastAccessTime();
+        } catch (IOException e) {
+            return "[unable to obtain timestamp]";
+        }
+    }
+
+    /** @hide */
+    static void wtfAsSystemServer(String tag, String message, Throwable stacktrace) {
+        Log.e(tag, message, stacktrace);
+        ContentResolver.onDbCorruption(tag, message, stacktrace);
+    }
 }
 
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index 1c66204..f220205 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -189,6 +189,11 @@
      * @param args Command-line arguments supplied to dumpsys dbinfo
      */
     public static void dump(Printer printer, String[] args) {
+        dump(printer, args, false);
+    }
+
+    /** @hide */
+    public static void dump(Printer printer, String[] args, boolean isSystem) {
         boolean verbose = false;
         for (String arg : args) {
             if (arg.equals("-v")) {
@@ -196,6 +201,6 @@
             }
         }
 
-        SQLiteDatabase.dumpAll(printer, verbose);
+        SQLiteDatabase.dumpAll(printer, verbose, isSystem);
     }
 }
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
index 67e5f65..ff286fd 100644
--- a/core/java/android/database/sqlite/SQLiteGlobal.java
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -42,6 +42,9 @@
     /** @hide */
     public static final String SYNC_MODE_FULL = "FULL";
 
+    /** @hide */
+    static final String WIPE_CHECK_FILE_SUFFIX = "-wipecheck";
+
     private static final Object sLock = new Object();
 
     private static int sDefaultPageSize;
@@ -181,4 +184,8 @@
                         com.android.internal.R.integer.db_wal_truncate_size));
     }
 
+    /** @hide */
+    public static boolean checkDbWipe() {
+        return true;
+    }
 }
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index 8f8f676..42e7ac7 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -53,7 +53,7 @@
     }
 
     /**
-     * Execute this SQL statement, if the the number of rows affected by execution of this SQL
+     * Execute this SQL statement, if the number of rows affected by execution of this SQL
      * statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements.
      *
      * @return the number of rows affected by this SQL statement execution.
diff --git a/core/java/android/hardware/biometrics/BiometricAuthenticator.java b/core/java/android/hardware/biometrics/BiometricAuthenticator.java
index c604ff1..79e15a7a 100644
--- a/core/java/android/hardware/biometrics/BiometricAuthenticator.java
+++ b/core/java/android/hardware/biometrics/BiometricAuthenticator.java
@@ -202,6 +202,21 @@
     }
 
     /**
+     * @return true if the user has enrolled templates for this biometric.
+     */
+    default boolean hasEnrolledTemplates(int userId) {
+        throw new UnsupportedOperationException("Stub!");
+    }
+
+    /**
+     * Sets the active user. This is meant to be used to select the current profile
+     * to allow separate templates for work profile.
+     */
+    default void setActiveUser(int userId) {
+        throw new UnsupportedOperationException("Stub!");
+    }
+
+    /**
      * This call warms up the hardware and starts scanning for valid biometrics. It terminates
      * when {@link AuthenticationCallback#onAuthenticationError(int,
      * CharSequence)} is called or when {@link AuthenticationCallback#onAuthenticationSucceeded(
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 6150be3..2a64c2e 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -34,6 +34,13 @@
     //
 
     /**
+     * This was not added here since it would update BiometricPrompt API. But, is used in
+     * BiometricManager.
+     * @hide
+     */
+    int BIOMETRIC_ERROR_NONE = 0;
+
+    /**
      * The hardware is unavailable. Try again later.
      */
     int BIOMETRIC_ERROR_HW_UNAVAILABLE = 1;
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index eea5f9b..1d40001 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -17,16 +17,44 @@
 package android.hardware.biometrics;
 
 import static android.Manifest.permission.USE_BIOMETRIC;
+import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 
+import android.annotation.IntDef;
 import android.annotation.RequiresPermission;
 import android.content.Context;
 import android.os.RemoteException;
+import android.util.Slog;
 
 /**
  * A class that contains biometric utilities. For authentication, see {@link BiometricPrompt}.
  */
 public class BiometricManager {
 
+    private static final String TAG = "BiometricManager";
+
+    /**
+     * No error detected.
+     */
+    public static final int ERROR_NONE = BiometricConstants.BIOMETRIC_ERROR_NONE;
+
+    /**
+     * The hardware is unavailable. Try again later.
+     */
+    public static final int ERROR_UNAVAILABLE = BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
+
+    /**
+     * The user does not have any biometrics enrolled.
+     */
+    public static final int ERROR_NO_BIOMETRICS = BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS;
+
+    /**
+     * There is no biometric hardware.
+     */
+    public static final int ERROR_NO_HARDWARE = BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT;
+
+    @IntDef({ERROR_NONE, ERROR_UNAVAILABLE, ERROR_NO_BIOMETRICS, ERROR_NO_HARDWARE})
+    @interface BiometricError {}
+
     private final Context mContext;
     private final IBiometricService mService;
 
@@ -41,16 +69,60 @@
     }
 
     /**
-     * Determine if there is at least one biometric enrolled.
+     * Determine if biometrics can be used. In other words, determine if {@link BiometricPrompt}
+     * can be expected to be shown (hardware available, templates enrolled, user-enabled).
      *
-     * @return true if at least one biometric is enrolled, false otherwise
+     * @return Returns {@link #ERROR_NO_BIOMETRICS} if the user does not have any enrolled, or
+     *     {@link #ERROR_UNAVAILABLE} if none are currently supported/enabled. Returns
+     *     {@link #ERROR_NONE} if a biometric can currently be used (enrolled and available).
      */
     @RequiresPermission(USE_BIOMETRIC)
-    public boolean hasEnrolledBiometrics() {
-        try {
-            return mService.hasEnrolledBiometrics(mContext.getOpPackageName());
-        } catch (RemoteException e) {
-            return false;
+    public @BiometricError int canAuthenticate() {
+        if (mService != null) {
+            try {
+                return mService.canAuthenticate(mContext.getOpPackageName());
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        } else {
+            Slog.w(TAG, "hasEnrolledBiometrics(): Service not connected");
+            return ERROR_UNAVAILABLE;
+        }
+    }
+
+    /**
+     * Listens for changes to biometric eligibility on keyguard from user settings.
+     * @param callback
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback) {
+        if (mService != null) {
+            try {
+                mService.registerEnabledOnKeyguardCallback(callback);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        } else {
+            Slog.w(TAG, "registerEnabledOnKeyguardCallback(): Service not connected");
+        }
+    }
+
+    /**
+     * Sets the active user.
+     * @hide
+     */
+    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+    public void setActiveUser(int userId) {
+        if (mService != null) {
+            try {
+                mService.setActiveUser(userId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        } else {
+            Slog.w(TAG, "setActiveUser(): Service not connected");
         }
     }
 }
+
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index 83998cc..7952c41 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -17,6 +17,7 @@
 package android.hardware.biometrics;
 
 import static android.Manifest.permission.USE_BIOMETRIC;
+import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
@@ -55,6 +56,10 @@
     /**
      * @hide
      */
+    public static final String KEY_USE_DEFAULT_TITLE = "use_default_title";
+    /**
+     * @hide
+     */
     public static final String KEY_SUBTITLE = "subtitle";
     /**
      * @hide
@@ -131,6 +136,17 @@
         }
 
         /**
+         * For internal use currently. Only takes effect if title is null/empty. Shows a default
+         * modality-specific title.
+         * @hide
+         */
+        @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+        public Builder setUseDefaultTitle() {
+            mBundle.putBoolean(KEY_USE_DEFAULT_TITLE, true);
+            return this;
+        }
+
+        /**
          * Optional: Set the subtitle to display.
          * @param subtitle
          * @return
@@ -206,8 +222,9 @@
         public BiometricPrompt build() {
             final CharSequence title = mBundle.getCharSequence(KEY_TITLE);
             final CharSequence negative = mBundle.getCharSequence(KEY_NEGATIVE_TEXT);
+            final boolean useDefaultTitle = mBundle.getBoolean(KEY_USE_DEFAULT_TITLE);
 
-            if (TextUtils.isEmpty(title)) {
+            if (TextUtils.isEmpty(title) && !useDefaultTitle) {
                 throw new IllegalArgumentException("Title must be set and non-empty");
             } else if (TextUtils.isEmpty(negative)) {
                 throw new IllegalArgumentException("Negative text must be set and non-empty");
diff --git a/proto/src/stats_enums.proto b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
similarity index 72%
copy from proto/src/stats_enums.proto
copy to core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
index 6c892cf..d22e7e2 100644
--- a/proto/src/stats_enums.proto
+++ b/core/java/android/hardware/biometrics/IBiometricEnabledOnKeyguardCallback.aidl
@@ -14,13 +14,13 @@
  * limitations under the License.
  */
 
-syntax = "proto2";
+package android.hardware.biometrics;
 
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "StatsEnums";
+import android.hardware.biometrics.BiometricSourceType;
 
-enum EventType {
-  // Unknown.
-  TYPE_UNKNOWN = 0;
-}
+/**
+ * @hide
+ */
+oneway interface IBiometricEnabledOnKeyguardCallback {
+    void onChanged(in BiometricSourceType type, boolean enabled);
+}
\ No newline at end of file
diff --git a/core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl b/core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl
index 67c9346..27d25b8 100644
--- a/core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricPromptReceiver.aidl
@@ -15,9 +15,6 @@
  */
 package android.hardware.biometrics;
 
-import android.os.Bundle;
-import android.os.UserHandle;
-
 /**
  * Communication channel from the BiometricPrompt (SysUI) back to AuthenticationClient.
  * @hide
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index fd9d572..e17feff 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -17,6 +17,7 @@
 package android.hardware.biometrics;
 
 import android.os.Bundle;
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
 import android.hardware.biometrics.IBiometricPromptReceiver;
 import android.hardware.biometrics.IBiometricServiceReceiver;
 
@@ -37,6 +38,12 @@
     // Cancel authentication for the given sessionId
     void cancelAuthentication(IBinder token, String opPackageName);
 
-    // Returns true if the user has at least one enrolled biometric.
-    boolean hasEnrolledBiometrics(String opPackageName);
-}
\ No newline at end of file
+    // Checks if biometrics can be used.
+    int canAuthenticate(String opPackageName);
+
+    // Register callback for when keyguard biometric eligibility changes.
+    void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback);
+
+    // Explicitly set the active user.
+    void setActiveUser(int userId);
+}
diff --git a/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl b/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
index 71abdd2..a6e3696 100644
--- a/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricServiceReceiver.aidl
@@ -15,10 +15,6 @@
  */
 package android.hardware.biometrics;
 
-import android.hardware.biometrics.BiometricSourceType;
-import android.os.Bundle;
-import android.os.UserHandle;
-
 /**
  * Communication channel from the BiometricService back to BiometricPrompt.
  * @hide
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 486b054..d4dc181 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -2090,7 +2090,7 @@
 
     /**
      * <p>Optimized for dim settings where the main light source
-     * is a flame.</p>
+     * is a candle.</p>
      * @see CaptureRequest#CONTROL_SCENE_MODE
      */
     public static final int CONTROL_SCENE_MODE_CANDLELIGHT = 15;
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index e8fb287..01ef58e 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -297,6 +297,15 @@
      */
     public static final int VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 8;
 
+    /**
+     * Virtual display flag: Indicates that the display should support system decorations. Virtual
+     * displays without this flag shouldn't show home, IME or any other system decorations.
+     *
+     * @see #createVirtualDisplay
+     * @hide
+     */
+    public static final int VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 9;
+
     /** @hide */
     public DisplayManager(Context context) {
         mContext = context;
@@ -388,7 +397,7 @@
         if (display == null) {
             // TODO: We cannot currently provide any override configurations for metrics on displays
             // other than the display the context is associated with.
-            final Context context = mContext.getDisplay().getDisplayId() == displayId
+            final Context context = mContext.getDisplayId() == displayId
                     ? mContext : mContext.getApplicationContext();
 
             display = mGlobal.getCompatibleDisplay(displayId, context.getResources());
diff --git a/core/java/android/hardware/display/DisplayViewport.java b/core/java/android/hardware/display/DisplayViewport.java
index 496f34c..df0d46b 100644
--- a/core/java/android/hardware/display/DisplayViewport.java
+++ b/core/java/android/hardware/display/DisplayViewport.java
@@ -16,9 +16,14 @@
 
 package android.hardware.display;
 
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
 import android.graphics.Rect;
 import android.text.TextUtils;
 
+import java.lang.annotation.Retention;
+
 /**
  * Describes how the pixels of physical display device reflects the content of
  * a logical display.
@@ -35,6 +40,10 @@
     public static final int VIEWPORT_INTERNAL = 1;
     public static final int VIEWPORT_EXTERNAL = 2;
     public static final int VIEWPORT_VIRTUAL = 3;
+    @IntDef(prefix = { "VIEWPORT_" }, value = {
+            VIEWPORT_INTERNAL, VIEWPORT_EXTERNAL, VIEWPORT_VIRTUAL})
+    @Retention(SOURCE)
+    public @interface ViewportType {};
 
     // True if this viewport is valid.
     public boolean valid;
@@ -62,6 +71,8 @@
     // The ID used to uniquely identify this display.
     public String uniqueId;
 
+    public @ViewportType int type;
+
     public void copyFrom(DisplayViewport viewport) {
         valid = viewport.valid;
         displayId = viewport.displayId;
@@ -71,6 +82,7 @@
         deviceWidth = viewport.deviceWidth;
         deviceHeight = viewport.deviceHeight;
         uniqueId = viewport.uniqueId;
+        type = viewport.type;
     }
 
     /**
@@ -100,7 +112,8 @@
               && physicalFrame.equals(other.physicalFrame)
               && deviceWidth == other.deviceWidth
               && deviceHeight == other.deviceHeight
-              && TextUtils.equals(uniqueId, other.uniqueId);
+              && TextUtils.equals(uniqueId, other.uniqueId)
+              && type == other.type;
     }
 
     @Override
@@ -115,13 +128,15 @@
         result += prime * result + deviceWidth;
         result += prime * result + deviceHeight;
         result += prime * result + uniqueId.hashCode();
+        result += prime * result + type;
         return result;
     }
 
     // For debugging purposes.
     @Override
     public String toString() {
-        return "DisplayViewport{valid=" + valid
+        return "DisplayViewport{type=" + typeToString(type)
+                + ", valid=" + valid
                 + ", displayId=" + displayId
                 + ", uniqueId='" + uniqueId + "'"
                 + ", orientation=" + orientation
@@ -131,4 +146,20 @@
                 + ", deviceHeight=" + deviceHeight
                 + "}";
     }
+
+    /**
+     * Human-readable viewport type.
+     */
+    public static String typeToString(@ViewportType int viewportType) {
+        switch (viewportType) {
+            case VIEWPORT_INTERNAL:
+                return "INTERNAL";
+            case VIEWPORT_EXTERNAL:
+                return "EXTERNAL";
+            case VIEWPORT_VIRTUAL:
+                return "VIRTUAL";
+            default:
+                return "UNKNOWN (" + viewportType + ")";
+        }
+    }
 }
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 873a24a..536c4a5 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -317,6 +317,7 @@
      * @hide
      */
     @RequiresPermission(MANAGE_BIOMETRIC)
+    @Override
     public void setActiveUser(int userId) {
         if (mService != null) {
             try {
@@ -408,6 +409,7 @@
     @RequiresPermission(allOf = {
             USE_BIOMETRIC_INTERNAL,
             INTERACT_ACROSS_USERS})
+    @Override
     public boolean hasEnrolledTemplates(int userId) {
         if (mService != null) {
             try {
diff --git a/core/java/android/hardware/face/IFaceServiceReceiver.aidl b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
index 16fb690..b88574b 100644
--- a/core/java/android/hardware/face/IFaceServiceReceiver.aidl
+++ b/core/java/android/hardware/face/IFaceServiceReceiver.aidl
@@ -16,8 +16,6 @@
 package android.hardware.face;
 
 import android.hardware.face.Face;
-import android.os.Bundle;
-import android.os.UserHandle;
 
 /**
  * Communication channel from the FaceService back to FaceAuthenticationManager.
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index a4f3ce1..bb98211 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -521,6 +521,7 @@
      * @hide
      */
     @RequiresPermission(MANAGE_FINGERPRINT)
+    @Override
     public void setActiveUser(int userId) {
         if (mService != null) try {
             mService.setActiveUser(userId);
@@ -637,6 +638,14 @@
     }
 
     /**
+     * @hide
+     */
+    @Override
+    public boolean hasEnrolledTemplates(int userId) {
+        return hasEnrolledFingerprints(userId);
+    }
+
+    /**
      * Determine if there is at least one fingerprint enrolled.
      *
      * @return true if at least one fingerprint is enrolled, false otherwise
diff --git a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
index 370383f..cf1c94e 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
@@ -16,8 +16,6 @@
 package android.hardware.fingerprint;
 
 import android.hardware.fingerprint.Fingerprint;
-import android.os.Bundle;
-import android.os.UserHandle;
 
 /**
  * Communication channel from the FingerprintService back to FingerprintManager.
diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java
index c4d7e40..d8da548 100644
--- a/core/java/android/hardware/input/InputManagerInternal.java
+++ b/core/java/android/hardware/input/InputManagerInternal.java
@@ -40,8 +40,7 @@
      * Called by the display manager to set information about the displays as needed
      * by the input system.  The input system must copy this information to retain it.
      */
-    public abstract void setDisplayViewports(DisplayViewport defaultViewport,
-            DisplayViewport externalTouchViewport, List<DisplayViewport> virtualTouchViewports);
+    public abstract void setDisplayViewports(List<DisplayViewport> viewports);
 
     /**
      * Called by the power manager to tell the input manager whether it should start
diff --git a/core/java/android/hardware/location/ContextHubClient.java b/core/java/android/hardware/location/ContextHubClient.java
index 917644d..56da719 100644
--- a/core/java/android/hardware/location/ContextHubClient.java
+++ b/core/java/android/hardware/location/ContextHubClient.java
@@ -105,12 +105,15 @@
      *
      * This method should be used if the caller wants to receive notifications even after the
      * process exits. The client must have an open connection with the Context Hub Service (i.e. it
-     * cannot have been closed through the {@link #close()} method). If registered successfully,
-     * intents will be delivered regarding events for the specified nanoapp from the attached
-     * Context Hub. Any unicast messages for this client will also be delivered. The intent will
-     * have an extra {@link #EXTRA_EVENT_TYPE} of type {@link ContextHubManager.Event}, which will
-     * contain the type of the event. See {@link ContextHubManager.Event} for description of each
-     * event type.
+     * cannot have been closed through the {@link #close()} method). Only one PendingIntent can be
+     * registered at a time for a single ContextHubClient. If registered successfully, intents will
+     * be delivered regarding events for the specified nanoapp from the attached Context Hub. Any
+     * unicast messages for this client will also be delivered. The intent will have an extra
+     * {@link ContextHubManager.EXTRA_CONTEXT_HUB_INFO} of type {@link ContextHubInfo}, which
+     * describes the Context Hub the intent event was for. The intent will also have an extra
+     * {@link ContextHubManager.EXTRA_EVENT_TYPE} of type {@link ContextHubManager.Event}, which
+     * will contain the type of the event. See {@link ContextHubManager.Event} for description of
+     * each event type, along with event-specific extra fields.
      *
      * When the intent is received, this client can be recreated through
      * {@link ContextHubManager.createClient(PendingIntent, ContextHubInfo,
@@ -127,28 +130,42 @@
      * {@link PendingIntent} through a {@link BroadcastReceiver}, and maps an {@link Intent} to a
      * {@link ContextHubClientCallback}.
      *
-     * @param intent    The PendingIntent to register for this client
-     * @param nanoAppId the unique ID of the nanoapp to receive events for
+     * @param pendingIntent the PendingIntent to register for this client
+     * @param nanoAppId     the unique ID of the nanoapp to receive events for
      * @return true on success, false otherwise
      *
      * @hide
      */
-    public boolean registerIntent(@NonNull PendingIntent intent, long nanoAppId) {
-        // TODO: Implement this
-        return false;
+    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+    public boolean registerIntent(@NonNull PendingIntent pendingIntent, long nanoAppId) {
+        Preconditions.checkNotNull(pendingIntent, "PendingIntent cannot be null");
+
+        try {
+            return mClientProxy.registerIntent(pendingIntent, nanoAppId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
      * Unregisters an intent previously registered via {@link #registerIntent(PendingIntent, long)}.
      * If this intent has not been registered for this client, this method returns false.
      *
+     * @param pendingIntent the PendingIntent to unregister
+     *
      * @return true on success, false otherwise
      *
      * @hide
      */
-    public boolean unregisterIntent(@NonNull PendingIntent intent) {
-        // TODO: Implement this
-        return false;
+    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
+    public boolean unregisterIntent(@NonNull PendingIntent pendingIntent) {
+        Preconditions.checkNotNull(pendingIntent, "PendingIntent cannot be null");
+
+        try {
+            return mClientProxy.unregisterIntent(pendingIntent);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 36f3586..b0b77f3 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -73,7 +73,7 @@
      *
      * @hide
      */
-    public static final String EXTRA_NANOAPP_ID = "android.location.hardware.extra.NANOAPP_ID";
+    public static final String EXTRA_NANOAPP_ID = "android.hardware.location.extra.NANOAPP_ID";
 
     /**
      * An extra of type int describing the nanoapp-specific abort code.
@@ -81,14 +81,14 @@
      * @hide
      */
     public static final String EXTRA_NANOAPP_ABORT_CODE =
-            "android.location.hardware.extra.NANOAPP_ABORT_CODE";
+            "android.hardware.location.extra.NANOAPP_ABORT_CODE";
 
     /**
      * An extra of type {@link NanoAppMessage} describing contents of a message from a nanoapp.
      *
      * @hide
      */
-    public static final String EXTRA_MESSAGE = "android.location.hardware.extra.MESSAGE";
+    public static final String EXTRA_MESSAGE = "android.hardware.location.extra.MESSAGE";
 
     /**
      * Constants describing the type of events from a Context Hub.
@@ -749,6 +749,7 @@
      *
      * @see ContextHubClientCallback
      */
+    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     @NonNull public ContextHubClient createClient(
             @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback,
             @NonNull @CallbackExecutor Executor executor) {
@@ -785,6 +786,7 @@
      *
      * @see ContextHubClientCallback
      */
+    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     @NonNull public ContextHubClient createClient(
             @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback) {
         return createClient(hubInfo, callback, new HandlerExecutor(Handler.getMain()));
@@ -798,21 +800,22 @@
      * through {@link #createClient(ContextHubInfo, ContextHubClientCallback, Executor)} or
      * equivalent at an earlier time.
      *
-     * @param intent   the intent that is associated with a client
-     * @param hubInfo  the hub to attach this client to
-     * @param callback the notification callback to register
-     * @param executor the executor to invoke the callback
+     * @param pendingIntent the PendingIntent that has been registered with a client
+     * @param hubInfo       the hub to attach this client to
+     * @param callback      the notification callback to register
+     * @param executor      the executor to invoke the callback
      * @return the registered client object
      *
-     * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or the intent
+     * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or pendingIntent
      *                                  was not associated with a client
      * @throws IllegalStateException    if there were too many registered clients at the service
-     * @throws NullPointerException     if intent, hubInfo, callback, or executor is null
+     * @throws NullPointerException     if pendingIntent, hubInfo, callback, or executor is null
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     @NonNull public ContextHubClient createClient(
-            @NonNull PendingIntent intent, @NonNull ContextHubInfo hubInfo,
+            @NonNull PendingIntent pendingIntent, @NonNull ContextHubInfo hubInfo,
             @NonNull ContextHubClientCallback callback,
             @NonNull @CallbackExecutor Executor executor) {
         // TODO: Implement this
@@ -820,25 +823,27 @@
     }
 
     /**
-     * Equivalent to {@link #createClient(Intent, ContextHubInfo, ContextHubClientCallback,
+     * Equivalent to {@link #createClient(PendingIntent, ContextHubInfo, ContextHubClientCallback,
      * Executor)} with the executor using the main thread's Looper.
      *
-     * @param intent   the intent that is associated with a client
-     * @param hubInfo  the hub to attach this client to
-     * @param callback the notification callback to register
+     * @param pendingIntent the PendingIntent that has been registered with a client
+     * @param hubInfo       the hub to attach this client to
+     * @param callback      the notification callback to register
      * @return the registered client object
      *
-     * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or the intent
+     * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or pendingIntent
      *                                  was not associated with a client
      * @throws IllegalStateException    if there were too many registered clients at the service
-     * @throws NullPointerException     if intent, hubInfo, or callback is null
+     * @throws NullPointerException     if pendingIntent, hubInfo, or callback is null
      *
      * @hide
      */
+    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
     @NonNull public ContextHubClient createClient(
-            @NonNull PendingIntent intent, @NonNull ContextHubInfo hubInfo,
+            @NonNull PendingIntent pendingIntent, @NonNull ContextHubInfo hubInfo,
             @NonNull ContextHubClientCallback callback) {
-        return createClient(intent, hubInfo, callback, new HandlerExecutor(Handler.getMain()));
+        return createClient(
+                pendingIntent, hubInfo, callback, new HandlerExecutor(Handler.getMain()));
     }
 
     /**
diff --git a/core/java/android/hardware/location/IContextHubClient.aidl b/core/java/android/hardware/location/IContextHubClient.aidl
index d81126a..7559cd5 100644
--- a/core/java/android/hardware/location/IContextHubClient.aidl
+++ b/core/java/android/hardware/location/IContextHubClient.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.location;
 
+import android.app.PendingIntent;
 import android.hardware.location.NanoAppMessage;
 
 /**
@@ -28,4 +29,10 @@
 
     // Closes the connection with the Context Hub
     void close();
+
+    // Registers a PendingIntent with the client
+    boolean registerIntent(in PendingIntent intent, long nanoAppId);
+
+    // Unregisters a PendingIntent from the client
+    boolean unregisterIntent(in PendingIntent intent);
 }
diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.java b/core/java/android/hardware/location/NanoAppInstanceInfo.java
index 75fb915..2db6a79 100644
--- a/core/java/android/hardware/location/NanoAppInstanceInfo.java
+++ b/core/java/android/hardware/location/NanoAppInstanceInfo.java
@@ -24,7 +24,7 @@
 import libcore.util.EmptyArray;
 
 /**
- * Describes an instance of a nanoapp, used by the internal state manged by ContextHubService.
+ * Describes an instance of a nanoapp, used by the internal state managed by ContextHubService.
  *
  * TODO(b/69270990) Remove this class once the old API is deprecated.
  *
diff --git a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
index 838765b..e970747 100644
--- a/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
+++ b/core/java/android/hardware/soundtrigger/SoundTriggerModule.java
@@ -20,6 +20,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+
 import java.lang.ref.WeakReference;
 
 /**
@@ -131,6 +132,14 @@
     @UnsupportedAppUsage
     public native int stopRecognition(int soundModelHandle);
 
+    /**
+     * Get the current state of a {@link SoundTrigger.SoundModel}
+     * @param soundModelHandle The sound model handle indicating which model's state to return
+     * @return - {@link SoundTrigger#RecognitionEvent} in case of success
+     *         - null in case of an error or if not supported
+     */
+    public native SoundTrigger.RecognitionEvent getModelState(int soundModelHandle);
+
     private class NativeEventHandlerDelegate {
         private final Handler mHandler;
 
@@ -207,4 +216,3 @@
         }
     }
 }
-
diff --git a/proto/src/stats_enums.proto b/core/java/android/hardware/usb/IUsbSerialReader.aidl
similarity index 76%
copy from proto/src/stats_enums.proto
copy to core/java/android/hardware/usb/IUsbSerialReader.aidl
index 6c892cf..787d5cd 100644
--- a/proto/src/stats_enums.proto
+++ b/core/java/android/hardware/usb/IUsbSerialReader.aidl
@@ -14,13 +14,11 @@
  * limitations under the License.
  */
 
-syntax = "proto2";
+package android.hardware.usb;
 
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "StatsEnums";
-
-enum EventType {
-  // Unknown.
-  TYPE_UNKNOWN = 0;
+/** @hide */
+interface IUsbSerialReader
+{
+    /* Returns a serial for the accessory/device */
+    String getSerial(String packageName);
 }
diff --git a/core/java/android/hardware/usb/UsbAccessory.java b/core/java/android/hardware/usb/UsbAccessory.java
index 4aeb40c..b418d43 100644
--- a/core/java/android/hardware/usb/UsbAccessory.java
+++ b/core/java/android/hardware/usb/UsbAccessory.java
@@ -18,8 +18,11 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.ActivityThread;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
+
 import com.android.internal.util.Preconditions;
 
 /**
@@ -54,7 +57,7 @@
     private final @Nullable String mDescription;
     private final @Nullable String mVersion;
     private final @Nullable String mUri;
-    private final @Nullable String mSerial;
+    private final @NonNull IUsbSerialReader mSerialNumberReader;
 
     /** @hide */
     public static final int MANUFACTURER_STRING = 0;
@@ -75,22 +78,38 @@
      */
     public UsbAccessory(@NonNull String manufacturer, @NonNull String model,
             @Nullable String description, @Nullable String version, @Nullable String uri,
-            @Nullable String serial) {
+            @NonNull IUsbSerialReader serialNumberReader) {
         mManufacturer = Preconditions.checkNotNull(manufacturer);
         mModel = Preconditions.checkNotNull(model);
         mDescription = description;
         mVersion = version;
         mUri = uri;
-        mSerial = serial;
+        mSerialNumberReader = serialNumberReader;
+
+        // Make sure the binder belongs to the system
+        if (ActivityThread.isSystem()) {
+            Preconditions.checkArgument(mSerialNumberReader instanceof IUsbSerialReader.Stub);
+        }
     }
 
     /**
-     * UsbAccessory should only be instantiated by UsbService implementation
+     * DO NOT USE. Only for backwards compatibility with
+     * {@link com.android.future.usb.UsbAccessory}.
+     *
      * @hide
+     * @deprecated use {@link UsbAccessory#UsbAccessory(String, String, String, String, String,
+     *             IUsbSerialReader) instead}
      */
-    public UsbAccessory(String[] strings) {
-        this(strings[MANUFACTURER_STRING], strings[MODEL_STRING], strings[DESCRIPTION_STRING],
-                strings[VERSION_STRING], strings[URI_STRING], strings[SERIAL_STRING]);
+    @Deprecated
+    public UsbAccessory(@NonNull String manufacturer, @NonNull String model,
+            @Nullable String description, @Nullable String version, @Nullable String uri,
+            @Nullable String serialNumber) {
+        this(manufacturer, model, description, version, uri, new IUsbSerialReader.Stub() {
+            @Override
+            public String getSerial(String packageName) {
+                return serialNumber;
+            }
+        });
     }
 
     /**
@@ -146,9 +165,17 @@
      * between individual accessories of the same model and manufacturer
      *
      * @return the unique serial number, or {@code null} if not set
+     *
+     * @throws SecurityException if the app targets SDK >= {@value android.os.Build.VERSION_CODES#Q}
+     *                           and the app does not have permission to read from the accessory.
      */
     public @Nullable String getSerial() {
-        return mSerial;
+        try {
+            return mSerialNumberReader.getSerial(ActivityThread.currentPackageName());
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+            return null;
+        }
     }
 
     private static boolean compare(String s1, String s2) {
@@ -165,7 +192,7 @@
                     compare(mDescription, accessory.getDescription()) &&
                     compare(mVersion, accessory.getVersion()) &&
                     compare(mUri, accessory.getUri()) &&
-                    compare(mSerial, accessory.getSerial()));
+                    compare(getSerial(), accessory.getSerial()));
         }
         return false;
     }
@@ -175,7 +202,7 @@
         return mManufacturer.hashCode() ^ mModel.hashCode() ^
                 (mDescription == null ? 0 : mDescription.hashCode()) ^
                 (mVersion == null ? 0 : mVersion.hashCode()) ^
-                (mUri == null ? 0 : mUri.hashCode()) ^ (mSerial == null ? 0 : mSerial.hashCode());
+                (mUri == null ? 0 : mUri.hashCode());
     }
 
     @Override
@@ -185,7 +212,7 @@
                             ", mDescription=" + mDescription +
                             ", mVersion=" + mVersion +
                             ", mUri=" + mUri +
-                            ", mSerial=" + mSerial + "]";
+                            ", mSerialNumberReader=" + mSerialNumberReader + "]";
     }
 
     public static final Parcelable.Creator<UsbAccessory> CREATOR =
@@ -196,8 +223,11 @@
             String description = in.readString();
             String version = in.readString();
             String uri = in.readString();
-            String serial = in.readString();
-            return new UsbAccessory(manufacturer, model, description, version, uri, serial);
+            IUsbSerialReader serialNumberReader = IUsbSerialReader.Stub.asInterface(
+                    in.readStrongBinder());
+
+            return new UsbAccessory(manufacturer, model, description, version, uri,
+                    serialNumberReader);
         }
 
         public UsbAccessory[] newArray(int size) {
@@ -215,6 +245,6 @@
         parcel.writeString(mDescription);
         parcel.writeString(mVersion);
         parcel.writeString(mUri);
-        parcel.writeString(mSerial);
+        parcel.writeStrongBinder(mSerialNumberReader.asBinder());
    }
 }
diff --git a/core/java/android/hardware/usb/UsbDevice.java b/core/java/android/hardware/usb/UsbDevice.java
index 26c5a95..b08212c 100644
--- a/core/java/android/hardware/usb/UsbDevice.java
+++ b/core/java/android/hardware/usb/UsbDevice.java
@@ -19,8 +19,11 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
+import android.app.ActivityThread;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.RemoteException;
+
 import com.android.internal.util.Preconditions;
 
 /**
@@ -50,27 +53,27 @@
     private final @Nullable String mManufacturerName;
     private final @Nullable String mProductName;
     private final @NonNull String mVersion;
-    private final @Nullable String mSerialNumber;
+    private final @NonNull UsbConfiguration[] mConfigurations;
+    private final @NonNull IUsbSerialReader mSerialNumberReader;
     private final int mVendorId;
     private final int mProductId;
     private final int mClass;
     private final int mSubclass;
     private final int mProtocol;
 
-    /** All configurations for this device, only null during creation */
-    private @Nullable Parcelable[] mConfigurations;
-
     /** All interfaces on the device. Initialized on first call to getInterfaceList */
     @UnsupportedAppUsage
     private @Nullable UsbInterface[] mInterfaces;
 
     /**
-     * UsbDevice should only be instantiated by UsbService implementation
+     * Create a new UsbDevice object. Only called by {@link Builder#build(IUsbSerialReader)}
+     *
      * @hide
      */
-    public UsbDevice(@NonNull String name, int vendorId, int productId, int Class, int subClass,
+    private UsbDevice(@NonNull String name, int vendorId, int productId, int Class, int subClass,
             int protocol, @Nullable String manufacturerName, @Nullable String productName,
-            @NonNull String version, @Nullable String serialNumber) {
+            @NonNull String version, @NonNull UsbConfiguration[] configurations,
+            @NonNull IUsbSerialReader serialNumberReader) {
         mName = Preconditions.checkNotNull(name);
         mVendorId = vendorId;
         mProductId = productId;
@@ -80,7 +83,13 @@
         mManufacturerName = manufacturerName;
         mProductName = productName;
         mVersion = Preconditions.checkStringNotEmpty(version);
-        mSerialNumber = serialNumber;
+        mConfigurations = Preconditions.checkArrayElementsNotNull(configurations, "configurations");
+        mSerialNumberReader = Preconditions.checkNotNull(serialNumberReader);
+
+        // Make sure the binder belongs to the system
+        if (ActivityThread.isSystem()) {
+            Preconditions.checkArgument(mSerialNumberReader instanceof IUsbSerialReader.Stub);
+        }
     }
 
     /**
@@ -125,9 +134,17 @@
      * Returns the serial number of the device.
      *
      * @return the serial number name, or {@code null} if the property could not be read
+     *
+     * @throws SecurityException if the app targets SDK >= {@value android.os.Build.VERSION_CODES#Q}
+     *                           and the app does not have permission to read from the device.
      */
     public @Nullable String getSerialNumber() {
-        return mSerialNumber;
+        try {
+            return mSerialNumberReader.getSerial(ActivityThread.currentPackageName());
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+            return null;
+        }
     }
 
     /**
@@ -203,7 +220,7 @@
      * @return the configuration
      */
     public @NonNull UsbConfiguration getConfiguration(int index) {
-        return (UsbConfiguration)mConfigurations[index];
+        return mConfigurations[index];
     }
 
     private @Nullable UsbInterface[] getInterfaceList() {
@@ -211,14 +228,14 @@
             int configurationCount = mConfigurations.length;
             int interfaceCount = 0;
             for (int i = 0; i < configurationCount; i++) {
-                UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i];
+                UsbConfiguration configuration = mConfigurations[i];
                 interfaceCount += configuration.getInterfaceCount();
             }
 
             mInterfaces = new UsbInterface[interfaceCount];
             int offset = 0;
             for (int i = 0; i < configurationCount; i++) {
-                UsbConfiguration configuration = (UsbConfiguration)mConfigurations[i];
+                UsbConfiguration configuration = mConfigurations[i];
                 interfaceCount = configuration.getInterfaceCount();
                 for (int j = 0; j < interfaceCount; j++) {
                     mInterfaces[offset++] = configuration.getInterface(j);
@@ -251,14 +268,6 @@
         return getInterfaceList()[index];
     }
 
-    /**
-     * Only used by UsbService implementation
-     * @hide
-     */
-    public void setConfigurations(@NonNull Parcelable[] configuration) {
-        mConfigurations = Preconditions.checkArrayElementsNotNull(configuration, "configuration");
-    }
-
     @Override
     public boolean equals(Object o) {
         if (o instanceof UsbDevice) {
@@ -281,7 +290,8 @@
                 ",mVendorId=" + mVendorId + ",mProductId=" + mProductId +
                 ",mClass=" + mClass + ",mSubclass=" + mSubclass + ",mProtocol=" + mProtocol +
                 ",mManufacturerName=" + mManufacturerName + ",mProductName=" + mProductName +
-                ",mVersion=" + mVersion + ",mSerialNumber=" + mSerialNumber + ",mConfigurations=[");
+                ",mVersion=" + mVersion + ",mSerialNumberReader=" + mSerialNumberReader
+                + ",mConfigurations=[");
         for (int i = 0; i < mConfigurations.length; i++) {
             builder.append("\n");
             builder.append(mConfigurations[i].toString());
@@ -302,11 +312,13 @@
             String manufacturerName = in.readString();
             String productName = in.readString();
             String version = in.readString();
-            String serialNumber = in.readString();
-            Parcelable[] configurations = in.readParcelableArray(UsbInterface.class.getClassLoader());
+            IUsbSerialReader serialNumberReader =
+                    IUsbSerialReader.Stub.asInterface(in.readStrongBinder());
+            UsbConfiguration[] configurations = in.readParcelableArray(
+                    UsbConfiguration.class.getClassLoader(), UsbConfiguration.class);
             UsbDevice device = new UsbDevice(name, vendorId, productId, clasz, subClass, protocol,
-                                 manufacturerName, productName, version, serialNumber);
-            device.setConfigurations(configurations);
+                                 manufacturerName, productName, version, configurations,
+                    serialNumberReader);
             return device;
         }
 
@@ -329,7 +341,7 @@
         parcel.writeString(mManufacturerName);
         parcel.writeString(mProductName);
         parcel.writeString(mVersion);
-        parcel.writeString(mSerialNumber);
+        parcel.writeStrongBinder(mSerialNumberReader.asBinder());
         parcel.writeParcelableArray(mConfigurations, 0);
    }
 
@@ -343,4 +355,53 @@
 
     private static native int native_get_device_id(String name);
     private static native String native_get_device_name(int id);
+
+    /**
+     * @hide
+     */
+    public static class Builder {
+        private final @NonNull String mName;
+        private final int mVendorId;
+        private final int mProductId;
+        private final int mClass;
+        private final int mSubclass;
+        private final int mProtocol;
+        private final @Nullable String mManufacturerName;
+        private final @Nullable String mProductName;
+        private final @NonNull String mVersion;
+        private final @NonNull UsbConfiguration[] mConfigurations;
+
+        // Temporary storage for serial number. Serial number reader need to be wrapped in a
+        // IUsbSerialReader as they might be used as PII.
+        public final @Nullable String serialNumber;
+
+        public Builder(@NonNull String name, int vendorId, int productId, int Class, int subClass,
+                int protocol, @Nullable String manufacturerName, @Nullable String productName,
+                @NonNull String version, @NonNull UsbConfiguration[] configurations,
+                @Nullable String serialNumber) {
+            mName = Preconditions.checkNotNull(name);
+            mVendorId = vendorId;
+            mProductId = productId;
+            mClass = Class;
+            mSubclass = subClass;
+            mProtocol = protocol;
+            mManufacturerName = manufacturerName;
+            mProductName = productName;
+            mVersion = Preconditions.checkStringNotEmpty(version);
+            mConfigurations = configurations;
+            this.serialNumber = serialNumber;
+        }
+
+        /**
+         * Create a new {@link UsbDevice}
+         *
+         * @param serialReader The method to read the serial number.
+         *
+         * @return The usb device
+         */
+        public UsbDevice build(@NonNull IUsbSerialReader serialReader) {
+            return new UsbDevice(mName, mVendorId, mProductId, mClass, mSubclass, mProtocol,
+                    mManufacturerName, mProductName, mVersion, mConfigurations, serialReader);
+        }
+    }
 }
diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
index 0982d65..843db6d 100644
--- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
+++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java
@@ -41,8 +41,7 @@
 class IInputMethodSessionWrapper extends IInputMethodSession.Stub
         implements HandlerCaller.Callback {
     private static final String TAG = "InputMethodWrapper";
-    
-    private static final int DO_FINISH_INPUT = 60;
+
     private static final int DO_DISPLAY_COMPLETIONS = 65;
     private static final int DO_UPDATE_EXTRACTED_TEXT = 67;
     private static final int DO_UPDATE_SELECTION = 90;
@@ -89,9 +88,6 @@
         }
 
         switch (msg.what) {
-            case DO_FINISH_INPUT:
-                mInputMethodSession.finishInput();
-                return;
             case DO_DISPLAY_COMPLETIONS:
                 mInputMethodSession.displayCompletions((CompletionInfo[])msg.obj);
                 return;
@@ -150,11 +146,6 @@
     }
 
     @Override
-    public void finishInput() {
-        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_FINISH_INPUT));
-    }
-
-    @Override
     public void displayCompletions(CompletionInfo[] completions) {
         mCaller.executeOrSendMessage(mCaller.obtainMessageO(
                 DO_DISPLAY_COMPLETIONS, completions));
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index f7f627e..097a3e3 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -2095,7 +2095,7 @@
      * Called when the application has reported a new location of its text
      * cursor.  This is only called if explicitly requested by the input method.
      * The default implementation does nothing.
-     * @deprecated Use {#link onUpdateCursorAnchorInfo(CursorAnchorInfo)} instead.
+     * @deprecated Use {@link #onUpdateCursorAnchorInfo(CursorAnchorInfo)} instead.
      */
     @Deprecated
     public void onUpdateCursor(Rect newCursor) {
@@ -2162,7 +2162,7 @@
     }
 
     /**
-     * @return {#link ExtractEditText} if it is considered to be visible and active. Otherwise
+     * @return {@link ExtractEditText} if it is considered to be visible and active. Otherwise
      * {@code null} is returned.
      */
     private ExtractEditText getExtractEditTextIfVisible() {
diff --git a/core/java/android/inputmethodservice/SoftInputWindow.java b/core/java/android/inputmethodservice/SoftInputWindow.java
index b4b8887..0513fee 100644
--- a/core/java/android/inputmethodservice/SoftInputWindow.java
+++ b/core/java/android/inputmethodservice/SoftInputWindow.java
@@ -162,9 +162,9 @@
     /**
      * Set which boundary of the screen the DockWindow sticks to.
      * 
-     * @param gravity The boundary of the screen to stick. See {#link
-     *        android.view.Gravity.LEFT}, {#link android.view.Gravity.TOP},
-     *        {#link android.view.Gravity.BOTTOM}, {#link
+     * @param gravity The boundary of the screen to stick. See {@link
+     *        android.view.Gravity.LEFT}, {@link android.view.Gravity.TOP},
+     *        {@link android.view.Gravity.BOTTOM}, {@link
      *        android.view.Gravity.RIGHT}.
      */
     public void setGravity(int gravity) {
diff --git a/core/java/android/metrics/LogMaker.java b/core/java/android/metrics/LogMaker.java
index e84f913..19848ee 100644
--- a/core/java/android/metrics/LogMaker.java
+++ b/core/java/android/metrics/LogMaker.java
@@ -436,4 +436,12 @@
         }
         return true;
     }
+
+    /**
+     * @return entries containing key value pairs.
+     * @hide
+     */
+    public SparseArray<Object> getEntries() {
+        return entries;
+    }
 }
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 8333b81..4714587 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -83,6 +83,7 @@
 @SystemService(Context.CONNECTIVITY_SERVICE)
 public class ConnectivityManager {
     private static final String TAG = "ConnectivityManager";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     /**
      * A change in network connectivity has occurred. A default connection has either
@@ -2493,6 +2494,7 @@
      * {@hide}
      */
     public void reportInetCondition(int networkType, int percentage) {
+        printStackTrace();
         try {
             mService.reportInetCondition(networkType, percentage);
         } catch (RemoteException e) {
@@ -2513,6 +2515,7 @@
      */
     @Deprecated
     public void reportBadNetwork(Network network) {
+        printStackTrace();
         try {
             // One of these will be ignored because it matches system's current state.
             // The other will trigger the necessary reevaluation.
@@ -2535,6 +2538,7 @@
      *                        Internet using {@code network} or {@code false} if not.
      */
     public void reportNetworkConnectivity(Network network, boolean hasConnectivity) {
+        printStackTrace();
         try {
             mService.reportNetworkConnectivity(network, hasConnectivity);
         } catch (RemoteException e) {
@@ -2727,8 +2731,11 @@
      *
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL)
-    @UnsupportedAppUsage
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_SETUP_WIZARD,
+            android.Manifest.permission.NETWORK_STACK})
+    @SystemApi
     public void setAirplaneMode(boolean enable) {
         try {
             mService.setAirplaneMode(enable);
@@ -2809,10 +2816,11 @@
          * @param network The {@link Network} of the satisfying network.
          * @param networkCapabilities The {@link NetworkCapabilities} of the satisfying network.
          * @param linkProperties The {@link LinkProperties} of the satisfying network.
+         * @param blocked Whether access to the {@link Network} is blocked due to system policy.
          * @hide
          */
         public void onAvailable(Network network, NetworkCapabilities networkCapabilities,
-                LinkProperties linkProperties) {
+                LinkProperties linkProperties, boolean blocked) {
             // Internally only this method is called when a new network is available, and
             // it calls the callback in the same way and order that older versions used
             // to call so as not to change the behavior.
@@ -2823,6 +2831,7 @@
             }
             onCapabilitiesChanged(network, networkCapabilities);
             onLinkPropertiesChanged(network, linkProperties);
+            onBlockedStatusChanged(network, blocked);
         }
 
         /**
@@ -2830,7 +2839,8 @@
          * This callback may be called more than once if the {@link Network} that is
          * satisfying the request changes. This will always immediately be followed by a
          * call to {@link #onCapabilitiesChanged(Network, NetworkCapabilities)} then by a
-         * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}.
+         * call to {@link #onLinkPropertiesChanged(Network, LinkProperties)}, and a call to
+         * {@link #onBlockedStatusChanged(Network, boolean)}.
          *
          * @param network The {@link Network} of the satisfying network.
          */
@@ -2909,6 +2919,14 @@
          */
         public void onNetworkResumed(Network network) {}
 
+        /**
+         * Called when access to the specified network is blocked or unblocked.
+         *
+         * @param network The {@link Network} whose blocked status has changed.
+         * @param blocked The blocked status of this {@link Network}.
+         */
+        public void onBlockedStatusChanged(Network network, boolean blocked) {}
+
         private NetworkRequest networkRequest;
     }
 
@@ -2955,6 +2973,8 @@
     public static final int CALLBACK_SUSPENDED           = BASE + 9;
     /** @hide */
     public static final int CALLBACK_RESUMED             = BASE + 10;
+    /** @hide */
+    public static final int CALLBACK_BLK_CHANGED         = BASE + 11;
 
     /** @hide */
     public static String getCallbackName(int whichCallback) {
@@ -2969,6 +2989,7 @@
             case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
             case CALLBACK_SUSPENDED:    return "CALLBACK_SUSPENDED";
             case CALLBACK_RESUMED:      return "CALLBACK_RESUMED";
+            case CALLBACK_BLK_CHANGED:  return "CALLBACK_BLK_CHANGED";
             default:
                 return Integer.toString(whichCallback);
         }
@@ -3015,7 +3036,7 @@
                 case CALLBACK_AVAILABLE: {
                     NetworkCapabilities cap = getObject(message, NetworkCapabilities.class);
                     LinkProperties lp = getObject(message, LinkProperties.class);
-                    callback.onAvailable(network, cap, lp);
+                    callback.onAvailable(network, cap, lp, message.arg1 != 0);
                     break;
                 }
                 case CALLBACK_LOSING: {
@@ -3048,6 +3069,10 @@
                     callback.onNetworkResumed(network);
                     break;
                 }
+                case CALLBACK_BLK_CHANGED: {
+                    boolean blocked = message.arg1 != 0;
+                    callback.onBlockedStatusChanged(network, blocked);
+                }
             }
         }
 
@@ -3073,6 +3098,7 @@
 
     private NetworkRequest sendRequestForNetwork(NetworkCapabilities need, NetworkCallback callback,
             int timeoutMs, int action, int legacyType, CallbackHandler handler) {
+        printStackTrace();
         checkCallbackNotNull(callback);
         Preconditions.checkArgument(action == REQUEST || need != null, "null NetworkCapabilities");
         final NetworkRequest request;
@@ -3332,6 +3358,7 @@
      *         {@link NetworkCapabilities#NET_CAPABILITY_CAPTIVE_PORTAL}.
      */
     public void requestNetwork(NetworkRequest request, PendingIntent operation) {
+        printStackTrace();
         checkPendingIntentNotNull(operation);
         try {
             mService.pendingRequestForNetwork(request.networkCapabilities, operation);
@@ -3355,6 +3382,7 @@
      *                  corresponding NetworkRequest you'd like to remove. Cannot be null.
      */
     public void releaseNetworkRequest(PendingIntent operation) {
+        printStackTrace();
         checkPendingIntentNotNull(operation);
         try {
             mService.releasePendingNetworkRequest(operation);
@@ -3439,6 +3467,7 @@
      */
     @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
     public void registerNetworkCallback(NetworkRequest request, PendingIntent operation) {
+        printStackTrace();
         checkPendingIntentNotNull(operation);
         try {
             mService.pendingListenForNetwork(request.networkCapabilities, operation);
@@ -3520,6 +3549,7 @@
      * @param networkCallback The {@link NetworkCallback} used when making the request.
      */
     public void unregisterNetworkCallback(NetworkCallback networkCallback) {
+        printStackTrace();
         checkCallbackNotNull(networkCallback);
         final List<NetworkRequest> reqs = new ArrayList<>();
         // Find all requests associated to this callback and stop callback triggers immediately.
@@ -3948,4 +3978,19 @@
             throw e.rethrowFromSystemServer();
         }
     }
+
+    private void printStackTrace() {
+        if (DEBUG) {
+            final StackTraceElement[] callStack = Thread.currentThread().getStackTrace();
+            final StringBuffer sb = new StringBuffer();
+            for (int i = 3; i < callStack.length; i++) {
+                final String stackTrace = callStack[i].toString();
+                if (stackTrace == null || stackTrace.contains("android.os")) {
+                    break;
+                }
+                sb.append(" [").append(stackTrace).append("]");
+            }
+            Log.d(TAG, "StackLog:" + sb.toString());
+        }
+    }
 }
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 12b6f9e..0bdfca7 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -1590,4 +1590,14 @@
         Preconditions.checkArgument(isValidCapability(capability),
                 "NetworkCapability " + capability + "out of range");
     }
+
+    /**
+     * Check if this {@code NetworkCapability} instance is metered.
+     *
+     * @return {@code true} if {@code NET_CAPABILITY_NOT_METERED} is not set on this instance.
+     * @hide
+     */
+    public boolean isMetered() {
+        return !hasCapability(NET_CAPABILITY_NOT_METERED);
+    }
 }
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index d912dd10..1a1d2d334 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -202,7 +202,9 @@
      * Return a network-type-specific integer describing the subtype
      * of the network.
      * @return the network subtype
+     * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
      */
+    @Deprecated
     public int getSubtype() {
         synchronized (this) {
             return mSubtype;
@@ -243,7 +245,9 @@
     /**
      * Return a human-readable name describing the subtype of the network.
      * @return the name of the network subtype
+     * @deprecated Use {@link android.telephony.TelephonyManager#getDataNetworkType} instead.
      */
+    @Deprecated
     public String getSubtypeName() {
         synchronized (this) {
             return mSubtypeName;
@@ -278,7 +282,15 @@
      * connections and pass data.
      * <p>Always call this before attempting to perform data transactions.
      * @return {@code true} if network connectivity exists, {@code false} otherwise.
+     * @deprecated Apps should instead use the
+     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
+     *             learn about connectivity changes. See
+     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
+     *             {@link ConnectivityManager#registerNetworkCallback}. These will
+     *             give a more accurate picture of the connectivity state of
+     *             the device and let apps react more easily and quickly to changes.
      */
+    @Deprecated
     public boolean isConnected() {
         synchronized (this) {
             return mState == State.CONNECTED;
@@ -411,7 +423,15 @@
     /**
      * Reports the current fine-grained state of the network.
      * @return the fine-grained state
+     * @deprecated Apps should instead use the
+     *             {@link android.net.ConnectivityManager.NetworkCallback} API to
+     *             learn about connectivity changes. See
+     *             {@link ConnectivityManager#registerDefaultNetworkCallback} and
+     *             {@link ConnectivityManager#registerNetworkCallback}. These will
+     *             give a more accurate picture of the connectivity state of
+     *             the device and let apps react more easily and quickly to changes.
      */
+    @Deprecated
     public DetailedState getDetailedState() {
         synchronized (this) {
             return mDetailedState;
diff --git a/core/java/android/net/NetworkMisc.java b/core/java/android/net/NetworkMisc.java
index 69f50a2..a2da6ea 100644
--- a/core/java/android/net/NetworkMisc.java
+++ b/core/java/android/net/NetworkMisc.java
@@ -46,7 +46,7 @@
 
     /**
      * Set if the user desires to use this network even if it is unvalidated. This field has meaning
-     * only if {#link explicitlySelected} is true. If it is, this field must also be set to the
+     * only if {@link explicitlySelected} is true. If it is, this field must also be set to the
      * appropriate value based on previous user choice.
      */
     public boolean acceptUnvalidated;
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 34e9476..c431e40e 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -16,8 +16,13 @@
 
 package android.net;
 
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Parcel;
+import android.system.Os;
 import android.util.Log;
 import android.util.Pair;
 
@@ -570,4 +575,30 @@
         }
         return routedIPCount;
     }
+
+    private static final int[] ADDRESS_FAMILIES = new int[] {AF_INET, AF_INET6};
+
+    /**
+     * Returns true if the hostname is weakly validated.
+     * @param hostname Name of host to validate.
+     * @return True if it's a valid-ish hostname.
+     *
+     * @hide
+     */
+    public static boolean isWeaklyValidatedHostname(@NonNull String hostname) {
+        // TODO(b/34953048): Use a validation method that permits more accurate,
+        // but still inexpensive, checking of likely valid DNS hostnames.
+        final String weakHostnameRegex = "^[a-zA-Z0-9_.-]+$";
+        if (!hostname.matches(weakHostnameRegex)) {
+            return false;
+        }
+
+        for (int address_family : ADDRESS_FAMILIES) {
+            if (Os.inet_pton(address_family, hostname) != null) {
+                return false;
+            }
+        }
+
+        return true;
+    }
 }
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 40465ce..d09f33b 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1102,19 +1102,18 @@
         public String getHost() {
             @SuppressWarnings("StringEquality")
             boolean cached = (host != NOT_CACHED);
-            return cached ? host
-                    : (host = parseHost());
+            return cached ? host : (host = parseHost());
         }
 
         private String parseHost() {
-            String authority = getEncodedAuthority();
+            final String authority = getEncodedAuthority();
             if (authority == null) {
                 return null;
             }
 
             // Parse out user info and then port.
             int userInfoSeparator = authority.lastIndexOf('@');
-            int portSeparator = authority.indexOf(':', userInfoSeparator);
+            int portSeparator = findPortSeparator(authority);
 
             String encodedHost = portSeparator == NOT_FOUND
                     ? authority.substring(userInfoSeparator + 1)
@@ -1132,16 +1131,8 @@
         }
 
         private int parsePort() {
-            String authority = getEncodedAuthority();
-            if (authority == null) {
-                return -1;
-            }
-
-            // Make sure we look for the port separtor *after* the user info
-            // separator. We have URLs with a ':' in the user info.
-            int userInfoSeparator = authority.lastIndexOf('@');
-            int portSeparator = authority.indexOf(':', userInfoSeparator);
-
+            final String authority = getEncodedAuthority();
+            int portSeparator = findPortSeparator(authority);
             if (portSeparator == NOT_FOUND) {
                 return -1;
             }
@@ -1154,6 +1145,24 @@
                 return -1;
             }
         }
+
+        private int findPortSeparator(String authority) {
+            if (authority == null) {
+                return NOT_FOUND;
+            }
+
+            // Reverse search for the ':' character that breaks as soon as a char that is neither
+            // a colon nor an ascii digit is encountered. Thanks to the goodness of UTF-16 encoding,
+            // it's not possible that a surrogate matches one of these, so this loop can just
+            // look for characters rather than care about code points.
+            for (int i = authority.length() - 1; i >= 0; --i) {
+                final int character = authority.charAt(i);
+                if (':' == character) return i;
+                // Character.isDigit would include non-ascii digits
+                if (character < '0' || character > '9') return NOT_FOUND;
+            }
+            return NOT_FOUND;
+        }
     }
 
     /**
diff --git a/core/java/android/net/UrlQuerySanitizer.java b/core/java/android/net/UrlQuerySanitizer.java
index d2073b4..5b67406 100644
--- a/core/java/android/net/UrlQuerySanitizer.java
+++ b/core/java/android/net/UrlQuerySanitizer.java
@@ -287,7 +287,7 @@
         /**
          * Sanitize a value.
          * <ol>
-         * <li>If script URLs are not OK, the will be removed.
+         * <li>If script URLs are not OK, they will be removed.
          * <li>If neither spaces nor other white space is OK, then
          * white space will be trimmed from the beginning and end of
          * the URL. (Just the actual white space characters are trimmed, not
@@ -563,7 +563,7 @@
     }
 
     /**
-     * Constructs a UrlQuerySanitizer and parse a URL.
+     * Constructs a UrlQuerySanitizer and parses a URL.
      * This constructor is provided for convenience when the
      * default parsing behavior is acceptable.
      * <p>
@@ -644,7 +644,7 @@
     }
 
     /**
-     * An array list of all of the parameter value pairs in the sanitized
+     * An array list of all of the parameter-value pairs in the sanitized
      * query, in the order they appeared in the query. May contain duplicate
      * parameters.
      * <p class="note"><b>Note:</b> Do not modify this list. Treat it as a read-only list.</p>
@@ -656,7 +656,7 @@
     /**
      * Check if a parameter exists in the current sanitized query.
      * @param parameter the unencoded name of a parameter.
-     * @return true if the paramater exists in the current sanitized queary.
+     * @return true if the parameter exists in the current sanitized queary.
      */
     public boolean hasParameter(String parameter) {
         return mEntries.containsKey(parameter);
@@ -766,7 +766,7 @@
      * the value. If all goes well then addSanitizedValue is called with
      * the unescaped parameter and the sanitized unescaped value.
      * @param parameter an escaped parameter
-     * @param value an unsanitzied escaped value
+     * @param value an unsanitized escaped value
      */
     protected void parseEntry(String parameter, String value) {
         String unescapedParameter = unescape(parameter);
@@ -812,7 +812,7 @@
     /**
      * Get the effective value sanitizer for a parameter. Like getValueSanitizer,
      * except if there is no value sanitizer registered for a parameter, and
-     * unregistered paramaters are allowed, then the default value sanitizer is
+     * unregistered parameters are allowed, then the default value sanitizer is
      * returned.
      * @param parameter an unescaped parameter
      * @return the effective value sanitizer for a parameter.
diff --git a/core/java/android/nfc/cardemulation/OffHostApduService.java b/core/java/android/nfc/cardemulation/OffHostApduService.java
index 6a8aeee..2286e84 100644
--- a/core/java/android/nfc/cardemulation/OffHostApduService.java
+++ b/core/java/android/nfc/cardemulation/OffHostApduService.java
@@ -31,7 +31,7 @@
  * <div class="special reference">
  * <h3>Developer Guide</h3>
  * For a general introduction into the topic of card emulation,
- * please read the <a href="{@docRoot}guide/topics/nfc/ce.html">
+ * please read the <a href="{@docRoot}guide/topics/connectivity/nfc/hce.html">
  * NFC card emulation developer guide.</a></p>
  * </div>
  *
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index f947b5e..8b6194c 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -28,6 +28,8 @@
 import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
 import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
 
+import dalvik.annotation.optimization.CriticalNative;
+
 import libcore.io.IoUtils;
 import libcore.util.NativeAllocationRegistry;
 
@@ -373,6 +375,54 @@
     public static final native int getThreadStrictModePolicy();
 
     /**
+     * Sets the work source for this thread.
+     *
+     * <p>All the following binder calls on this thread will use the provided work source.
+     *
+     * <p>The concept of worksource is similar to {@link WorkSource}. However, for performance
+     * reasons, we only support one UID. This UID represents the original user responsible for the
+     * binder calls.
+     *
+     * <p>A typical use case would be
+     * <pre>
+     * Binder.setThreadWorkSource(uid);
+     * try {
+     *   // Call an API.
+     * } finally {
+     *   Binder.clearThreadWorkSource();
+     * }
+     * </pre>
+     *
+     * @param workSource The original UID responsible for the binder call.
+     * @return The previously set work source.
+     * @hide
+     **/
+    @CriticalNative
+    public static final native int setThreadWorkSource(int workSource);
+
+    /**
+     * Returns the work source set by the caller.
+     *
+     * Unlike {@link Binder#getCallingUid()}, this result of this method cannot be trusted. The
+     * caller can set the value to whatever he wants. Only use this value if you trust the calling
+     * uid.
+     *
+     * @return The original UID responsible for the binder transaction.
+     * @hide
+     */
+    @CriticalNative
+    public static final native int getThreadWorkSource();
+
+    /**
+     * Clears the work source on this thread.
+     *
+     * @return The previously set work source.
+     * @hide
+     **/
+    @CriticalNative
+    public static final native int clearThreadWorkSource();
+
+    /**
      * Flush any Binder commands pending in the current thread to the kernel
      * driver.  This can be
      * useful to call before performing an operation that may block for a long
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 8681893..292543c 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -17,9 +17,12 @@
 package android.os;
 
 import android.Manifest;
+import android.annotation.NonNull;
 import android.annotation.RequiresPermission;
+import android.annotation.SuppressAutoDoc;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
+import android.app.ActivityThread;
 import android.app.Application;
 import android.content.Context;
 import android.text.TextUtils;
@@ -127,14 +130,21 @@
      * <a href="/training/articles/security-key-attestation.html">key attestation</a> to obtain
      * proof of the device's original identifiers.
      *
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. Profile owner access is
+     * deprecated and will be removed in a future release.
+     *
      * @return The serial number if specified.
      */
-    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner.
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public static String getSerial() {
         IDeviceIdentifiersPolicyService service = IDeviceIdentifiersPolicyService.Stub
                 .asInterface(ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE));
         try {
-            return service.getSerial();
+            Application application = ActivityThread.currentApplication();
+            String callingPackage = application != null ? application.getPackageName() : null;
+            return service.getSerialForPackage(callingPackage);
         } catch (RemoteException e) {
             e.rethrowFromSystemServer();
         }
@@ -1103,19 +1113,37 @@
         }
 
         /** The name of this partition, e.g. "system", or "vendor" */
+        @NonNull
         public String getName() {
             return mName;
         }
 
         /** The build fingerprint of this partition, see {@link Build#FINGERPRINT}. */
+        @NonNull
         public String getFingerprint() {
             return mFingerprint;
         }
 
         /** The time (ms since epoch), at which this partition was built, see {@link Build#TIME}. */
-        public long getTimeMillis() {
+        public long getBuildTimeMillis() {
             return mTimeMs;
         }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof Partition)) {
+                return false;
+            }
+            Partition op = (Partition) o;
+            return mName.equals(op.mName)
+                    && mFingerprint.equals(op.mFingerprint)
+                    && mTimeMs == op.mTimeMs;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mName, mFingerprint, mTimeMs);
+        }
     }
 
     /**
@@ -1124,7 +1152,8 @@
      * The list includes partitions that are suitable candidates for over-the-air updates. This is
      * not an exhaustive list of partitions on the device.
      */
-    public static List<Partition> getPartitions() {
+    @NonNull
+    public static List<Partition> getFingerprintedPartitions() {
         ArrayList<Partition> partitions = new ArrayList();
 
         String[] names = new String[] {
diff --git a/core/java/android/os/DumpstateOptions.java b/core/java/android/os/DumpstateOptions.java
new file mode 100644
index 0000000..53037b24
--- /dev/null
+++ b/core/java/android/os/DumpstateOptions.java
@@ -0,0 +1,57 @@
+/*
+ * 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.os;
+
+/**
+ * Options passed to dumpstate service.
+ *
+ * @hide
+ */
+public final class DumpstateOptions implements Parcelable {
+    // If true the caller can get callbacks with per-section
+    // progress details.
+    private final boolean mGetSectionDetails;
+    // Name of the caller.
+    private final String mName;
+
+    public DumpstateOptions(Parcel in) {
+        mGetSectionDetails = in.readBoolean();
+        mName = in.readString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+     public void writeToParcel(Parcel out, int flags) {
+        out.writeBoolean(mGetSectionDetails);
+        out.writeString(mName);
+    }
+
+    public static final Parcelable.Creator<DumpstateOptions> CREATOR =
+            new Parcelable.Creator<DumpstateOptions>() {
+        public DumpstateOptions createFromParcel(Parcel in) {
+            return new DumpstateOptions(in);
+        }
+
+        public DumpstateOptions[] newArray(int size) {
+            return new DumpstateOptions[size];
+        }
+    };
+}
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 3c43fd18..483b764 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -219,12 +219,11 @@
      * services to store files relating to the user. This directory will be
      * automatically deleted when the user is removed.
      *
-     * @deprecated This directory is valid and still exists, but callers should
-     *             <em>strongly</em> consider switching to
-     *             {@link #getDataSystemCeDirectory(int)} which is protected
-     *             with user credentials or
-     *             {@link #getDataSystemDeDirectory(int)} which supports fast
-     *             user wipe.
+     * @deprecated This directory is valid and still exists, but but callers
+     *             should <em>strongly</em> consider switching to using either
+     *             {@link #getDataSystemCeDirectory(int)} or
+     *             {@link #getDataSystemDeDirectory(int)}, both of which support
+     *             fast user wipe.
      * @hide
      */
     @Deprecated
@@ -292,12 +291,42 @@
         return buildPath(getDataDirectory(), "system_ce");
     }
 
-    /** {@hide} */
+    /**
+     * Return the "credential encrypted" system directory for a user. This is
+     * for use by system services to store files relating to the user. This
+     * directory supports fast user wipe, and will be automatically deleted when
+     * the user is removed.
+     * <p>
+     * Data stored under this path is "credential encrypted", which uses an
+     * encryption key that is entangled with user credentials, such as a PIN or
+     * password. The contents will only be available once the user has been
+     * unlocked, as reported by {@code SystemService.onUnlockUser()}.
+     * <p>
+     * New code should <em>strongly</em> prefer storing sensitive data in these
+     * credential encrypted areas.
+     *
+     * @hide
+     */
     public static File getDataSystemCeDirectory(int userId) {
         return buildPath(getDataDirectory(), "system_ce", String.valueOf(userId));
     }
 
-    /** {@hide} */
+    /**
+     * Return the "device encrypted" system directory for a user. This is for
+     * use by system services to store files relating to the user. This
+     * directory supports fast user wipe, and will be automatically deleted when
+     * the user is removed.
+     * <p>
+     * Data stored under this path is "device encrypted", which uses an
+     * encryption key that is tied to the physical device. The contents will
+     * only be available once the device has finished a {@code dm-verity}
+     * protected boot.
+     * <p>
+     * New code should <em>strongly</em> avoid storing sensitive data in these
+     * device encrypted areas.
+     *
+     * @hide
+     */
     public static File getDataSystemDeDirectory(int userId) {
         return buildPath(getDataDirectory(), "system_de", String.valueOf(userId));
     }
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index a9cb0d9..f71fdd7 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1198,6 +1198,19 @@
 
     /** {@hide} */
     public static int translateModeStringToPosix(String mode) {
+        // Sanity check for invalid chars
+        for (int i = 0; i < mode.length(); i++) {
+            switch (mode.charAt(i)) {
+                case 'r':
+                case 'w':
+                case 't':
+                case 'a':
+                    break;
+                default:
+                    throw new IllegalArgumentException("Bad mode: " + mode);
+            }
+        }
+
         int res = 0;
         if (mode.startsWith("rw")) {
             res |= O_RDWR | O_CREAT;
diff --git a/core/java/android/os/GraphicsEnvironment.java b/core/java/android/os/GraphicsEnvironment.java
index 54be639..0c56d48 100644
--- a/core/java/android/os/GraphicsEnvironment.java
+++ b/core/java/android/os/GraphicsEnvironment.java
@@ -19,6 +19,8 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
 import android.opengl.EGL14;
 import android.os.Build;
 import android.os.SystemProperties;
@@ -27,7 +29,14 @@
 
 import dalvik.system.VMRuntime;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.HashSet;
+import java.util.Set;
 
 /** @hide */
 public class GraphicsEnvironment {
@@ -44,8 +53,10 @@
     private static final boolean DEBUG = false;
     private static final String TAG = "GraphicsEnvironment";
     private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
+    private static final String PROPERTY_GFX_DRIVER_WHITELIST = "ro.gfx.driver.whitelist.0";
     private static final String ANGLE_PACKAGE_NAME = "com.android.angle";
     private static final String GLES_MODE_METADATA_KEY = "com.android.angle.GLES_MODE";
+    private static final String ANGLE_RULES_FILE = "a4a_rules.json";
 
     private ClassLoader mClassLoader;
     private String mLayerPath;
@@ -54,9 +65,9 @@
     /**
      * Set up GraphicsEnvironment
      */
-    public void setup(Context context) {
-        setupGpuLayers(context);
-        setupAngle(context);
+    public void setup(Context context, Bundle coreSettings) {
+        setupGpuLayers(context, coreSettings);
+        setupAngle(context, coreSettings);
         chooseDriver(context);
     }
 
@@ -81,27 +92,54 @@
     }
 
     /**
+     * Return the debug layer app's on-disk and in-APK lib directories
+     */
+    private static String getDebugLayerAppPaths(Context context, String app) {
+        ApplicationInfo appInfo;
+        try {
+            appInfo = context.getPackageManager().getApplicationInfo(
+                    app, PackageManager.MATCH_ALL);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Debug layer app '" + app + "' not installed");
+
+            return null;
+        }
+
+        String abi = chooseAbi(appInfo);
+
+        StringBuilder sb = new StringBuilder();
+        sb.append(appInfo.nativeLibraryDir)
+            .append(File.pathSeparator);
+        sb.append(appInfo.sourceDir)
+            .append("!/lib/")
+            .append(abi);
+        String paths = sb.toString();
+
+        if (DEBUG) Log.v(TAG, "Debug layer app libs: " + paths);
+
+        return paths;
+    }
+
+    /**
      * Set up layer search paths for all apps
      * If debuggable, check for additional debug settings
      */
-    private void setupGpuLayers(Context context) {
+    private void setupGpuLayers(Context context, Bundle coreSettings) {
 
         String layerPaths = "";
 
         // Only enable additional debug functionality if the following conditions are met:
-        // 1. App is debuggable
+        // 1. App is debuggable or device is rooted
         // 2. ENABLE_GPU_DEBUG_LAYERS is true
         // 3. Package name is equal to GPU_DEBUG_APP
 
-        if (isDebuggable(context)) {
+        if (isDebuggable(context) || (getCanLoadSystemLibraries() == 1)) {
 
-            int enable = Settings.Global.getInt(context.getContentResolver(),
-                                                Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
+            int enable = coreSettings.getInt(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, 0);
 
             if (enable != 0) {
 
-                String gpuDebugApp = Settings.Global.getString(context.getContentResolver(),
-                                                               Settings.Global.GPU_DEBUG_APP);
+                String gpuDebugApp = coreSettings.getString(Settings.Global.GPU_DEBUG_APP);
 
                 String packageName = context.getPackageName();
 
@@ -115,8 +153,22 @@
                     // the layers specified by the app.
                     layerPaths = mDebugLayerPath + ":";
 
-                    String layers = Settings.Global.getString(context.getContentResolver(),
-                                                              Settings.Global.GPU_DEBUG_LAYERS);
+
+                    // If there is a debug layer app specified, add its path.
+                    String gpuDebugLayerApp =
+                            coreSettings.getString(Settings.Global.GPU_DEBUG_LAYER_APP);
+
+                    if (gpuDebugLayerApp != null && !gpuDebugLayerApp.isEmpty()) {
+                        Log.i(TAG, "GPU debug layer app: " + gpuDebugLayerApp);
+                        String paths = getDebugLayerAppPaths(context, gpuDebugLayerApp);
+                        if (paths != null) {
+                            // Append the path so files placed in the app's base directory will
+                            // override the external path
+                            layerPaths += paths + ":";
+                        }
+                    }
+
+                    String layers = coreSettings.getString(Settings.Global.GPU_DEBUG_LAYERS);
 
                     Log.i(TAG, "Debug layer list: " + layers);
                     if (layers != null && !layers.isEmpty()) {
@@ -135,11 +187,10 @@
     /**
      * Pass ANGLE details down to trigger enable logic
      */
-    private static void setupAngle(Context context) {
+    private static void setupAngle(Context context, Bundle coreSettings) {
 
         String angleEnabledApp =
-                Settings.Global.getString(context.getContentResolver(),
-                                          Settings.Global.ANGLE_ENABLED_APP);
+                coreSettings.getString(Settings.Global.ANGLE_ENABLED_APP);
 
         String packageName = context.getPackageName();
 
@@ -202,8 +253,40 @@
 
         if (DEBUG) Log.v(TAG, "ANGLE package libs: " + paths);
 
+        // Pass the rules file to loader for ANGLE decisions
+        AssetManager angleAssets = null;
+        try {
+            angleAssets =
+                context.getPackageManager().getResourcesForApplication(angleInfo).getAssets();
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, "Failed to get AssetManager for '" + ANGLE_PACKAGE_NAME + "'");
+            return;
+        }
+
+        AssetFileDescriptor assetsFd = null;
+        try {
+            assetsFd = angleAssets.openFd(ANGLE_RULES_FILE);
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to get AssetFileDescriptor for " + ANGLE_RULES_FILE + " from "
+                       + "'" + ANGLE_PACKAGE_NAME + "'");
+            return;
+        }
+
+        FileDescriptor rulesFd = null;
+        long rulesOffset = 0;
+        long rulesLength = 0;
+        if (assetsFd != null) {
+            rulesFd = assetsFd.getFileDescriptor();
+            rulesOffset = assetsFd.getStartOffset();
+            rulesLength = assetsFd.getLength();
+        } else {
+            Log.w(TAG, "Failed to get file descriptor for " + ANGLE_RULES_FILE);
+            return;
+        }
+
         // Further opt-in logic is handled in native, so pass relevant info down
-        setAngleInfo(paths, packageName, appPref, devOptIn);
+        setAngleInfo(paths, packageName, appPref, devOptIn,
+                     rulesFd, rulesOffset, rulesLength);
     }
 
     /**
@@ -222,6 +305,15 @@
             if (DEBUG) Log.v(TAG, "ignoring driver package for privileged/non-updated system app");
             return;
         }
+        Set<String> whitelist = loadWhitelist(context, driverPackageName);
+
+        // Empty whitelist implies no updatable graphics driver. Typically, the pre-installed
+        // updatable graphics driver is supposed to be a place holder and contains no graphics
+        // driver and whitelist.
+        if (whitelist == null || whitelist.isEmpty()) {
+            return;
+        }
+
         ApplicationInfo driverInfo;
         try {
             driverInfo = context.getPackageManager().getApplicationInfo(driverPackageName,
@@ -230,6 +322,22 @@
             Log.w(TAG, "driver package '" + driverPackageName + "' not installed");
             return;
         }
+        if (!whitelist.contains(context.getPackageName())) {
+            if (DEBUG) {
+                Log.w(TAG, context.getPackageName() + " is not on the whitelist.");
+            }
+            return;
+        }
+
+        // O drivers are restricted to the sphal linker namespace, so don't try to use
+        // packages unless they declare they're compatible with that restriction.
+        if (driverInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+            if (DEBUG) {
+                Log.w(TAG, "updated driver package is not known to be compatible with O");
+            }
+            return;
+        }
+
         String abi = chooseAbi(driverInfo);
         if (abi == null) {
             if (DEBUG) {
@@ -240,12 +348,6 @@
             }
             return;
         }
-        if (driverInfo.targetSdkVersion < Build.VERSION_CODES.O) {
-            // O drivers are restricted to the sphal linker namespace, so don't try to use
-            // packages unless they declare they're compatible with that restriction.
-            Log.w(TAG, "updated driver package is not known to be compatible with O");
-            return;
-        }
 
         StringBuilder sb = new StringBuilder();
         sb.append(driverInfo.nativeLibraryDir)
@@ -291,9 +393,39 @@
         return null;
     }
 
+    private static Set<String> loadWhitelist(Context context, String driverPackageName) {
+        String whitelistName = SystemProperties.get(PROPERTY_GFX_DRIVER_WHITELIST);
+        if (whitelistName == null || whitelistName.isEmpty()) {
+            return null;
+        }
+        try {
+            Context driverContext = context.createPackageContext(driverPackageName,
+                                                                 Context.CONTEXT_RESTRICTED);
+            AssetManager assets = driverContext.getAssets();
+            InputStream stream = assets.open(whitelistName);
+            BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
+            Set<String> whitelist = new HashSet<>();
+            for (String line; (line = reader.readLine()) != null; ) {
+                whitelist.add(line);
+            }
+            return whitelist;
+        } 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 whitelist driver package, abort.");
+            }
+        }
+        return null;
+    }
+
+    private static native int getCanLoadSystemLibraries();
     private static native void setLayerPaths(ClassLoader classLoader, String layerPaths);
     private static native void setDebugLayers(String layers);
     private static native void setDriverPath(String path);
     private static native void setAngleInfo(String path, String appPackage, String appPref,
-                                            boolean devOptIn);
+                                            boolean devOptIn, FileDescriptor rulesFd,
+                                            long rulesOffset, long rulesLength);
 }
diff --git a/core/java/android/os/IDeviceIdentifiersPolicyService.aidl b/core/java/android/os/IDeviceIdentifiersPolicyService.aidl
index ac19f2b..87d358f 100644
--- a/core/java/android/os/IDeviceIdentifiersPolicyService.aidl
+++ b/core/java/android/os/IDeviceIdentifiersPolicyService.aidl
@@ -21,4 +21,5 @@
  */
 interface IDeviceIdentifiersPolicyService {
     String getSerial();
+    String getSerialForPackage(in String callingPackage);
 }
\ No newline at end of file
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 20ca19b..c9c4205 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -388,10 +388,10 @@
 
     /**
      * Setup a new physical network.
-     * @param permission null if no permissions required to access this network.  PERMISSION_NETWORK
-     *                   or PERMISSION_SYSTEM to set respective permission.
+     * @param permission PERMISSION_NONE if no permissions required to access this network.
+     *                   PERMISSION_NETWORK or PERMISSION_SYSTEM to set respective permission.
      */
-    void createPhysicalNetwork(int netId, String permission);
+    void createPhysicalNetwork(int netId, int permission);
 
     /**
      * Setup a new VPN.
@@ -420,10 +420,10 @@
 
     /**
      * Set permission for a network.
-     * @param permission null to clear permissions. PERMISSION_NETWORK or PERMISSION_SYSTEM to set
-     *                   permission.
+     * @param permission PERMISSION_NONE to clear permissions.
+     *                   PERMISSION_NETWORK or PERMISSION_SYSTEM to set permission.
      */
-    void setNetworkPermission(int netId, String permission);
+    void setNetworkPermission(int netId, int permission);
 
     void setPermission(String permission, in int[] uids);
     void clearPermission(in int[] uids);
diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java
index cd3f301..5d5e5e2 100644
--- a/core/java/android/os/Message.java
+++ b/core/java/android/os/Message.java
@@ -19,6 +19,8 @@
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  *
  * Defines a message containing a description and arbitrary data object that can be
@@ -111,7 +113,13 @@
 
     /*package*/ int flags;
 
-    /*package*/ long when;
+    /**
+     * The targeted delivery time of this message. The time-base is
+     * {@link SystemClock#uptimeMillis}.
+     * @hide Only for use within the tests.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public long when;
 
     /*package*/ Bundle data;
 
@@ -382,7 +390,7 @@
      * the <em>target</em> {@link Handler} that is receiving this Message to
      * dispatch it.  If
      * not set, the message will be dispatched to the receiving Handler's
-     * {@link Handler#handleMessage(Message Handler.handleMessage())}.
+     * {@link Handler#handleMessage(Message)}.
      */
     public Runnable getCallback() {
         return callback;
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 8ea061e..e0b2c78 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -557,6 +557,7 @@
             ServiceType.FORCE_ALL_APPS_STANDBY,
             ServiceType.OPTIONAL_SENSORS,
             ServiceType.AOD,
+            ServiceType.QUICK_DOZE,
     })
     public @interface ServiceType {
         int NULL = 0;
@@ -586,6 +587,11 @@
          * Whether to disable non-essential sensors. (e.g. edge sensors.)
          */
         int OPTIONAL_SENSORS = 13;
+
+        /**
+         * Whether to go into Deep Doze as soon as the screen turns off or not.
+         */
+        int QUICK_DOZE = 15;
     }
 
     /**
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 0f64c45..379d28c 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -1003,11 +1003,38 @@
     public static final int PROC_OUT_LONG = 0x2000;
     /** @hide */
     public static final int PROC_OUT_FLOAT = 0x4000;
-    
-    /** @hide */
+
+    /**
+     * Read and parse a {@code proc} file in the given format.
+     *
+     * <p>The format is a list of integers, where every integer describes a variable in the file. It
+     * specifies how the variable is syntactically terminated (e.g. {@link Process#PROC_SPACE_TERM},
+     * {@link Process#PROC_TAB_TERM}, {@link Process#PROC_ZERO_TERM}).
+     *
+     * <p>If the variable should be parsed and returned to the caller, the termination type should
+     * be binary OR'd with the type of output (e.g. {@link Process#PROC_OUT_STRING}, {@link
+     * Process#PROC_OUT_LONG}, {@link Process#PROC_OUT_FLOAT}.
+     *
+     * <p>If the variable is wrapped in quotation marks it should be binary OR'd with {@link
+     * Process#PROC_QUOTES}. If the variable is wrapped in parentheses it should be binary OR'd with
+     * {@link Process#PROC_PARENS}.
+     *
+     * <p>If the variable is not formatted as a string and should be cast directly from characters
+     * to a long, the {@link Process#PROC_CHAR} integer should be binary OR'd.
+     *
+     * <p>If the terminating character can be repeated, the {@link Process#PROC_COMBINE} integer
+     * should be binary OR'd.
+     *
+     * @param file the path of the {@code proc} file to read
+     * @param format the format of the file
+     * @param outStrings the parsed {@code String}s from the file
+     * @param outLongs the parsed {@code long}s from the file
+     * @param outFloats the parsed {@code float}s from the file
+     * @hide
+     */
     public static final native boolean readProcFile(String file, int[] format,
             String[] outStrings, long[] outLongs, float[] outFloats);
-    
+
     /** @hide */
     public static final native boolean parseProcLine(byte[] buffer, int startIndex, 
             int endIndex, int[] format, String[] outStrings, long[] outLongs, float[] outFloats);
diff --git a/core/java/android/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java
index 051ab75..72e1ab9 100644
--- a/core/java/android/os/StatsLogEventWrapper.java
+++ b/core/java/android/os/StatsLogEventWrapper.java
@@ -70,11 +70,17 @@
                 }
             };
 
+    /**
+     * Write a int value.
+     */
     public void writeInt(int val) {
         mTypes.add(EVENT_TYPE_INT);
         mValues.add(val);
     }
 
+    /**
+     * Write a long value.
+     */
     public void writeLong(long val) {
         mTypes.add(EVENT_TYPE_LONG);
         mValues.add(val);
@@ -89,12 +95,23 @@
         mValues.add(val == null ? "" : val);
     }
 
+    /**
+     * Write a float value.
+     */
     public void writeFloat(float val) {
         mTypes.add(EVENT_TYPE_FLOAT);
         mValues.add(val);
     }
 
     /**
+     * Write a double value.
+     */
+    public void writeDouble(double val) {
+        mTypes.add(EVENT_TYPE_DOUBLE);
+        mValues.add(val);
+    }
+
+    /**
      * Write a storage value.
      */
     public void writeStorage(byte[] val) {
@@ -102,6 +119,9 @@
         mValues.add(val);
     }
 
+    /**
+     * Write a boolean value.
+     */
     public void writeBoolean(boolean val) {
         mTypes.add(EVENT_TYPE_INT);
         mValues.add(val ? 1 : 0);
@@ -134,6 +154,9 @@
                 case EVENT_TYPE_FLOAT:
                     out.writeFloat((float) mValues.get(i));
                     break;
+                case EVENT_TYPE_DOUBLE:
+                    out.writeDouble((double) mValues.get(i));
+                    break;
                 case EVENT_TYPE_STRING:
                     out.writeString((String) mValues.get(i));
                     break;
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index fb34a52..bdc776d 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -208,13 +208,18 @@
                 return;
             }
             ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks);
-            for (int i=0; i<callbacks.size(); i++) {
-                try {
-                    callbacks.get(i).run();
-                } catch (Throwable t) {
-                    Log.wtf(TAG, "Exception in SystemProperties change callback", t);
-                    // Ignore and try to go on.
+            final long token = Binder.clearCallingIdentity();
+            try {
+                for (int i = 0; i < callbacks.size(); i++) {
+                    try {
+                        callbacks.get(i).run();
+                    } catch (Throwable t) {
+                        Log.wtf(TAG, "Exception in SystemProperties change callback", t);
+                        // Ignore and try to go on.
+                    }
                 }
+            } finally {
+                Binder.restoreCallingIdentity(token);
             }
         }
     }
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 4fe2d58..f8feb7b 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -61,7 +61,6 @@
     public static final UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);
 
     /** @hide An undefined user id */
-    @SystemApi
     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 1282170..00b989e 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -268,10 +268,14 @@
     public static final String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
 
     /**
-     * This restriction is a device-wide version of {@link DISALLOW_INSTALL_UNKNOWN_SOURCES}.
+     * This restriction is a device-wide version of {@link #DISALLOW_INSTALL_UNKNOWN_SOURCES}.
      *
      * Specifies if all users on the device are disallowed from enabling the
      * "Unknown Sources" setting, that allows installation of apps from unknown sources.
+     *
+     * This restriction can be enabled by the profile owner, in which case all accounts and
+     * profiles will be affected.
+     *
      * The default value is <code>false</code>.
      *
      * <p>Key for user restrictions.
@@ -983,6 +987,21 @@
     public static final String DISALLOW_PRINTING = "no_printing";
 
     /**
+     * Specifies whether the user is allowed to modify private DNS settings.
+     *
+     * <p>The default value is <code>false</code>.
+     *
+     * <p>This user restriction can only be applied by the Device Owner.
+     * <p>Key for user restrictions.
+     * <p>Type: Boolean
+     * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+     * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+     * @see #getUserRestrictions()
+     */
+    public static final String DISALLOW_CONFIG_PRIVATE_DNS =
+            "disallow_config_private_dns";
+
+    /**
      * Application restriction key that is used to indicate the pending arrival
      * of real restrictions for the app.
      *
@@ -2363,7 +2382,6 @@
      */
     @RequiresPermission(anyOf = {Manifest.permission.MANAGE_USERS,
             Manifest.permission.CREATE_USERS}, conditional = true)
-    @SystemApi
     public @NonNull int[] getProfileIds(@UserIdInt int userId, boolean enabledOnly) {
         try {
             return mService.getProfileIds(userId, enabledOnly);
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 50ca4ab..df771df 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -1538,6 +1538,9 @@
      * @hide
      */
     public File translateAppToSystem(File file, String packageName) {
+        // We can only translate absolute paths
+        if (!file.isAbsolute()) return file;
+
         try {
             return new File(mStorageManager.translateAppToSystem(file.getAbsolutePath(),
                     packageName, mContext.getUserId()));
@@ -1553,6 +1556,9 @@
      * @hide
      */
     public File translateSystemToApp(File file, String packageName) {
+        // We can only translate absolute paths
+        if (!file.isAbsolute()) return file;
+
         try {
             return new File(mStorageManager.translateSystemToApp(file.getAbsolutePath(),
                     packageName, mContext.getUserId()));
diff --git a/core/java/android/os/storage/StorageManagerInternal.java b/core/java/android/os/storage/StorageManagerInternal.java
index 1f54ea5..63ff7b2 100644
--- a/core/java/android/os/storage/StorageManagerInternal.java
+++ b/core/java/android/os/storage/StorageManagerInternal.java
@@ -16,6 +16,9 @@
 
 package android.os.storage;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
 /**
  * Mount service local interface.
  *
@@ -81,18 +84,26 @@
     public abstract int getExternalStorageMountMode(int uid, String packageName);
 
     /**
-     * Mount external storage for the given package.
+     * Create storage sandbox for the given package.
      *
      * <p> This will involve calling into vold to setup appropriate bind mounts.
      *
-     * @param packageName The package for which external storage will be mounted.
+     * @param packageName The package for which the sandbox needs to be created.
      * @param appId The appId for the given package.
      * @param sharedUserId The sharedUserId for given package if it specified
      *      {@code android:sharedUserId} in the manifest, otherwise {@code null}
-     * @param userId The userId in which the storage needs to be mounted.
+     * @param userId The userId in which the sandbox needs to be created.
      */
-    public abstract void mountExternalStorageForApp(String packageName, int appId,
-            String sharedUserId, int userId);
+    public abstract void prepareSandboxForApp(@NonNull String packageName, int appId,
+            @Nullable String sharedUserId, int userId);
+
+    /**
+     * Delete storage sandbox for the given package.
+     *
+     * @param packageName The package for which the sandbox needs to be destroyed.
+     * @param userId The userId in which the sandbox needs to be destroyed.
+     */
+    public abstract void destroySandboxForApp(@NonNull String packageName, int userId);
 
     /**
      * @return Labels of storage volumes that are visible to the given userId.
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index aa44eb7..7ffb22f 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -25,7 +25,9 @@
 import com.android.internal.annotations.Immutable;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * System level service for accessing the permission capabilities of the platform.
@@ -40,26 +42,28 @@
      *
      * @hide
      */
-    public static final SplitPermissionInfo[] SPLIT_PERMISSIONS = new SplitPermissionInfo[]{
+    public static final List<SplitPermissionInfo> SPLIT_PERMISSIONS = Arrays.asList(
             // READ_EXTERNAL_STORAGE is always required when an app requests
             // WRITE_EXTERNAL_STORAGE, because we can't have an app that has
             // write access without read access.  The hack here with the target
             // target SDK version ensures that this grant is always done.
             new SplitPermissionInfo(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
-                    new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
+                    Collections.singletonList(android.Manifest.permission.READ_EXTERNAL_STORAGE),
                     android.os.Build.VERSION_CODES.CUR_DEVELOPMENT + 1),
             new SplitPermissionInfo(android.Manifest.permission.READ_CONTACTS,
-                    new String[]{android.Manifest.permission.READ_CALL_LOG},
+                    Collections.singletonList(android.Manifest.permission.READ_CALL_LOG),
                     android.os.Build.VERSION_CODES.JELLY_BEAN),
             new SplitPermissionInfo(android.Manifest.permission.WRITE_CONTACTS,
-                    new String[]{android.Manifest.permission.WRITE_CALL_LOG},
+                    Collections.singletonList(android.Manifest.permission.WRITE_CALL_LOG),
                     android.os.Build.VERSION_CODES.JELLY_BEAN),
             new SplitPermissionInfo(Manifest.permission.ACCESS_FINE_LOCATION,
-                    new String[]{android.Manifest.permission.ACCESS_BACKGROUND_LOCATION},
+                    Collections.singletonList(
+                            android.Manifest.permission.ACCESS_BACKGROUND_LOCATION),
                     android.os.Build.VERSION_CODES.P0),
             new SplitPermissionInfo(Manifest.permission.ACCESS_COARSE_LOCATION,
-                    new String[]{android.Manifest.permission.ACCESS_BACKGROUND_LOCATION},
-                    android.os.Build.VERSION_CODES.P0)};
+                    Collections.singletonList(
+                            android.Manifest.permission.ACCESS_BACKGROUND_LOCATION),
+                    android.os.Build.VERSION_CODES.P0));
 
     private final @NonNull Context mContext;
 
@@ -74,7 +78,7 @@
     }
 
     /**
-     * Get list of permissions that have been split into more granular or dependent permissions.
+     * Get set of permissions that have been split into more granular or dependent permissions.
      *
      * <p>E.g. before {@link android.os.Build.VERSION_CODES#P0} an app that was granted
      * {@link Manifest.permission#ACCESS_COARSE_LOCATION} could access he location while it was in
@@ -82,7 +86,7 @@
      * the location permission only grants location access while the app is in foreground. This
      * would break apps that target before {@link android.os.Build.VERSION_CODES#P0}. Hence whenever
      * such an old app asks for a location permission (i.e. the
-     * {@link SplitPermissionInfo#getRootPermission()}), then the
+     * {@link SplitPermissionInfo#getSplitPermission()}), then the
      * {@link Manifest.permission#ACCESS_BACKGROUND_LOCATION} permission (inside
      * {@{@link SplitPermissionInfo#getNewPermissions}) is added.
      *
@@ -91,8 +95,9 @@
      *
      * @return All permissions that are split.
      */
-    public @NonNull List<SplitPermissionInfo> getSplitPermissions() {
-        return Arrays.asList(SPLIT_PERMISSIONS);
+    public @NonNull
+    List<SplitPermissionInfo> getSplitPermissions() {
+        return SPLIT_PERMISSIONS;
     }
 
     /**
@@ -101,21 +106,35 @@
      */
     @Immutable
     public static final class SplitPermissionInfo {
-        private final @NonNull String mRootPerm;
-        private final @NonNull String[] mNewPerms;
+        private final @NonNull String mSplitPerm;
+        private final @NonNull List<String> mNewPerms;
         private final int mTargetSdk;
 
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            SplitPermissionInfo that = (SplitPermissionInfo) o;
+            return mTargetSdk == that.mTargetSdk
+                    && Objects.equals(mSplitPerm, that.mSplitPerm);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mSplitPerm, mTargetSdk);
+        }
+
         /**
          * Get the permission that is split.
          */
-        public @NonNull String getRootPermission() {
-            return mRootPerm;
+        public @NonNull String getSplitPermission() {
+            return mSplitPerm;
         }
 
         /**
          * Get the permissions that are added.
          */
-        public @NonNull String[] getNewPermissions() {
+        public @NonNull List<String> getNewPermissions() {
             return mNewPerms;
         }
 
@@ -126,9 +145,9 @@
             return mTargetSdk;
         }
 
-        private SplitPermissionInfo(@NonNull String rootPerm, @NonNull String[] newPerms,
+        private SplitPermissionInfo(@NonNull String rootPerm, @NonNull List<String> newPerms,
                 int targetSdk) {
-            mRootPerm = rootPerm;
+            mSplitPerm = rootPerm;
             mNewPerms = newPerms;
             mTargetSdk = targetSdk;
         }
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 112329e..25554b9 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -868,7 +868,11 @@
      */
     protected interface ContactOptionsColumns {
         /**
-         * The number of times a contact has been contacted
+         * The number of times a contact has been contacted.
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field is obsolete. For
+         * more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.</p>
          * <P>Type: INTEGER</P>
          *
          * @deprecated Contacts affinity information is no longer supported as of
@@ -880,6 +884,10 @@
 
         /**
          * The last time a contact was contacted.
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field is obsolete. For
+         * more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.</p>
          * <P>Type: INTEGER</P>
          *
          * @deprecated Contacts affinity information is no longer supported as of
@@ -1682,6 +1690,11 @@
          * TIMES_CONTACTED field is incremented by 1 and the LAST_TIME_CONTACTED
          * field is populated with the current system time.
          *
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this method is obsolete. For
+         * more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.
+         *
          * @param resolver the ContentResolver to use
          * @param contactId the person who was contacted
          *
@@ -1715,6 +1728,11 @@
          * {@link ContactsContract.Data}, filtered to include only starred contacts.
          * Frequent contacts are no longer included in the result as of
          * Android version {@link android.os.Build.VERSION_CODES#Q}.
+         *
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer sorts
+         * results based on contacts frequency. For more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.
          */
         public static final Uri CONTENT_STREQUENT_URI = Uri.withAppendedPath(
                 CONTENT_URI, "strequent");
@@ -1725,16 +1743,26 @@
          * @deprecated Frequent contacts are no longer supported as of
          * Android version {@link android.os.Build.VERSION_CODES#Q}.
          * This URI always returns an empty cursor.
+         *
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer sorts
+         * results based on contacts frequency. For more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.
          */
         @Deprecated
         public static final Uri CONTENT_FREQUENT_URI = Uri.withAppendedPath(
                 CONTENT_URI, "frequent");
 
         /**
-         * The content:// style URI used for "type-to-filter" functionality on the
+         * <p>The content:// style URI used for "type-to-filter" functionality on the
          * {@link #CONTENT_STREQUENT_URI} URI. The filter string will be used to match
          * various parts of the contact name. The filter argument should be passed
          * as an additional path segment after this URI.
+         *
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer sorts
+         * results based on contacts frequency. For more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.
          */
         public static final Uri CONTENT_STREQUENT_FILTER_URI = Uri.withAppendedPath(
                 CONTENT_STREQUENT_URI, "filter");
@@ -4262,6 +4290,11 @@
          * @deprecated Contacts affinity information is no longer supported as of
          * Android version {@link android.os.Build.VERSION_CODES#Q}.
          * This column always contains 0.
+         *
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field is obsolete.
+         * For more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.
          */
         @Deprecated
         public static final String LAST_TIME_USED = "last_time_used";
@@ -4271,6 +4304,11 @@
          * @deprecated Contacts affinity information is no longer supported as of
          * Android version {@link android.os.Build.VERSION_CODES#Q}.
          * This column always contains 0.
+         *
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field is obsolete.
+         * For more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.
          */
         @Deprecated
         public static final String TIMES_USED = "times_used";
@@ -5218,7 +5256,14 @@
         private PhoneLookup() {}
 
         /**
-         * The content:// style URI for this table. Append the phone number you want to lookup
+         * The content:// style URI for this table.
+         *
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer
+         * sorts results based on contacts frequency. For more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.
+         *
+         * Append the phone number you want to lookup
          * to this URI and query it to perform a lookup. For example:
          * <pre>
          * Uri lookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
@@ -5231,6 +5276,11 @@
         /**
          * <p>URI used for the "enterprise caller-id".</p>
          *
+         * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer
+         * sorts results based on contacts frequency. For more information, see the
+         * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+         * page.
+         *
          * <p>
          * It supports the same semantics as {@link #CONTENT_FILTER_URI} and returns the same
          * columns.  If the device has no corp profile that is linked to the current profile, it
@@ -6023,18 +6073,28 @@
                     Uri.withAppendedPath(Data.ENTERPRISE_CONTENT_URI, "phones");
 
             /**
-             * The content:// style URL for phone lookup using a filter. The filter returns
+             * <p>The content:// style URL for phone lookup using a filter. The filter returns
              * records of MIME type {@link #CONTENT_ITEM_TYPE}. The filter is applied
              * to display names as well as phone numbers. The filter argument should be passed
              * as an additional path segment after this URI.
+             *
+             * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer
+             * sorts results based on contacts frequency. For more information, see the
+             * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+             * page.
              */
             public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(CONTENT_URI,
                     "filter");
 
             /**
-             * It supports the similar semantics as {@link #CONTENT_FILTER_URI} and returns the same
-             * columns. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in
+             * <p>It supports the similar semantics as {@link #CONTENT_FILTER_URI} and returns the
+             * same columns. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in
              * parameters, otherwise it will throw IllegalArgumentException.
+             *
+             * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer sorts
+             * results based on contacts frequency. For more information, see the
+             * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+             * page.
              */
             public static final Uri ENTERPRISE_CONTENT_FILTER_URI = Uri.withAppendedPath(
                     CONTENT_URI, "filter_enterprise");
@@ -6202,7 +6262,7 @@
          */
         public static final class Email implements DataColumnsWithJoins, CommonColumns,
                 ContactCounts {
-            /**
+            /*
              * This utility class cannot be instantiated
              */
             private Email() {}
@@ -6293,12 +6353,17 @@
                     Uri.withAppendedPath(CONTENT_URI, "lookup_enterprise");
 
             /**
-             * <p>
-             * The content:// style URL for email lookup using a filter. The filter returns
+             * <p>The content:// style URL for email lookup using a filter. The filter returns
              * records of MIME type {@link #CONTENT_ITEM_TYPE}. The filter is applied
              * to display names as well as email addresses. The filter argument should be passed
              * as an additional path segment after this URI.
              * </p>
+             *
+             * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer sorts
+             * results based on contacts frequency. For more information, see the
+             * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+             * page.</p>
+             *
              * <p>The query in the following example will return "Robert Parr (bob@incredibles.com)"
              * as well as "Bob Parr (incredible@android.com)".
              * <pre>
@@ -6313,9 +6378,14 @@
                     "filter");
 
             /**
-             * It supports the similar semantics as {@link #CONTENT_FILTER_URI} and returns the same
-             * columns. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in
+             * <p>It supports the similar semantics as {@link #CONTENT_FILTER_URI} and returns the
+             * same columns. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in
              * parameters, otherwise it will throw IllegalArgumentException.
+             *
+             * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer
+             * sorts results based on contacts frequency. For more information, see the
+             * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+             * page.
              */
             public static final Uri ENTERPRISE_CONTENT_FILTER_URI = Uri.withAppendedPath(
                     CONTENT_URI, "filter_enterprise");
@@ -7528,16 +7598,26 @@
             public static final Uri CONTENT_URI = Uri.withAppendedPath(Data.CONTENT_URI,
                     "callables");
             /**
-             * Similar to {@link Phone#CONTENT_FILTER_URI}, but allows users to filter callable
+             * <p>Similar to {@link Phone#CONTENT_FILTER_URI}, but allows users to filter callable
              * data.
+             *
+             * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer
+             * sorts results based on contacts frequency. For more information, see the
+             * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+             * page.
              */
             public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(CONTENT_URI,
                     "filter");
 
             /**
-             * Similar to {@link Phone#ENTERPRISE_CONTENT_FILTER_URI}, but allows users to filter
+             * <p>Similar to {@link Phone#ENTERPRISE_CONTENT_FILTER_URI}, but allows users to filter
              * callable data. This URI requires {@link ContactsContract#DIRECTORY_PARAM_KEY} in
              * parameters, otherwise it will throw IllegalArgumentException.
+             *
+             * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer
+             * sorts results based on contacts frequency. For more information, see the
+             * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+             * page.</p>
              */
             public static final Uri ENTERPRISE_CONTENT_FILTER_URI = Uri.withAppendedPath(
                     CONTENT_URI, "filter_enterprise");
@@ -7562,8 +7642,13 @@
                     "contactables");
 
             /**
-             * The content:// style URI for these data items, which allows for a query parameter to
-             * be appended onto the end to filter for data items matching the query.
+             * <p>The content:// style URI for these data items, which allows for a query parameter
+             * to be appended onto the end to filter for data items matching the query.
+             *
+             * <p class="caution"><b>Caution: </b>As of January 7, 2019, this field no longer
+             * sorts results based on contacts frequency. For more information, see the
+             * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+             * page.
              */
             public static final Uri CONTENT_FILTER_URI = Uri.withAppendedPath(
                     Contactables.CONTENT_URI, "filter");
@@ -8212,6 +8297,11 @@
     }
 
     /**
+     * <p class="caution"><b>Caution: </b>As of January 7, 2019, this class is obsolete. For
+     * more information, see the
+     * <a href="/guide/topics/providers/contacts-provider#ObsoleteData">Contacts Provider</a>
+     * page.
+     * </p>
      * <p>
      * API allowing applications to send usage information for each {@link Data} row to the
      * Contacts Provider.  Applications can also clear all usage information.
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 8c40e0e..67e52aa 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -34,6 +34,7 @@
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.ImageDecoder;
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.media.ExifInterface;
@@ -53,6 +54,7 @@
 import android.system.Os;
 import android.util.DataUnit;
 import android.util.Log;
+import android.util.Size;
 
 import libcore.io.IoUtils;
 
@@ -136,10 +138,11 @@
     public static final String EXTRA_EXCLUDE_SELF = "android.provider.extra.EXCLUDE_SELF";
 
     /**
-     * Included in {@link AssetFileDescriptor#getExtras()} when returned
-     * thumbnail should be rotated.
+     * An extra number of degrees that an image should be rotated during the
+     * decode process to be presented correctly.
      *
-     * @see MediaStore.Images.ImageColumns#ORIENTATION
+     * @see AssetFileDescriptor#getExtras()
+     * @see android.provider.MediaStore.Images.ImageColumns#ORIENTATION
      */
     public static final String EXTRA_ORIENTATION = "android.provider.extra.ORIENTATION";
 
@@ -728,6 +731,8 @@
     public static final String EXTRA_PARENT_URI = "parentUri";
     /** {@hide} */
     public static final String EXTRA_URI = "uri";
+    /** {@hide} */
+    public static final String EXTRA_URI_PERMISSIONS = "uriPermissions";
 
     /**
      * @see #createWebLinkIntent(ContentResolver, Uri, Bundle)
@@ -1093,75 +1098,10 @@
 
     /** {@hide} */
     @UnsupportedAppUsage
-    public static Bitmap getDocumentThumbnail(
-            ContentProviderClient client, Uri documentUri, Point size, CancellationSignal signal)
-            throws RemoteException, IOException {
-        final Bundle openOpts = new Bundle();
-        openOpts.putParcelable(ContentResolver.EXTRA_SIZE, size);
-
-        AssetFileDescriptor afd = null;
-        Bitmap bitmap = null;
-        try {
-            afd = client.openTypedAssetFileDescriptor(documentUri, "image/*", openOpts, signal);
-
-            final FileDescriptor fd = afd.getFileDescriptor();
-            final long offset = afd.getStartOffset();
-
-            // Try seeking on the returned FD, since it gives us the most
-            // optimal decode path; otherwise fall back to buffering.
-            BufferedInputStream is = null;
-            try {
-                Os.lseek(fd, offset, SEEK_SET);
-            } catch (ErrnoException e) {
-                is = new BufferedInputStream(new FileInputStream(fd), THUMBNAIL_BUFFER_SIZE);
-                is.mark(THUMBNAIL_BUFFER_SIZE);
-            }
-
-            // We requested a rough thumbnail size, but the remote size may have
-            // returned something giant, so defensively scale down as needed.
-            final BitmapFactory.Options opts = new BitmapFactory.Options();
-            opts.inJustDecodeBounds = true;
-            if (is != null) {
-                BitmapFactory.decodeStream(is, null, opts);
-            } else {
-                BitmapFactory.decodeFileDescriptor(fd, null, opts);
-            }
-
-            final int widthSample = opts.outWidth / size.x;
-            final int heightSample = opts.outHeight / size.y;
-
-            opts.inJustDecodeBounds = false;
-            opts.inSampleSize = Math.min(widthSample, heightSample);
-            if (is != null) {
-                is.reset();
-                bitmap = BitmapFactory.decodeStream(is, null, opts);
-            } else {
-                try {
-                    Os.lseek(fd, offset, SEEK_SET);
-                } catch (ErrnoException e) {
-                    e.rethrowAsIOException();
-                }
-                bitmap = BitmapFactory.decodeFileDescriptor(fd, null, opts);
-            }
-
-            // Transform the bitmap if requested. We use a side-channel to
-            // communicate the orientation, since EXIF thumbnails don't contain
-            // the rotation flags of the original image.
-            final Bundle extras = afd.getExtras();
-            final int orientation = (extras != null) ? extras.getInt(EXTRA_ORIENTATION, 0) : 0;
-            if (orientation != 0) {
-                final int width = bitmap.getWidth();
-                final int height = bitmap.getHeight();
-
-                final Matrix m = new Matrix();
-                m.setRotate(orientation, width / 2, height / 2);
-                bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, false);
-            }
-        } finally {
-            IoUtils.closeQuietly(afd);
-        }
-
-        return bitmap;
+    public static Bitmap getDocumentThumbnail(ContentProviderClient client, Uri documentUri,
+            Point size, CancellationSignal signal) throws IOException {
+        return ContentResolver.loadThumbnail(client, documentUri, Point.convert(size), signal,
+                ImageDecoder.ALLOCATOR_DEFAULT);
     }
 
     /**
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 828fd73..57f33f0 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -29,7 +29,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.UriPermission;
-import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.graphics.Bitmap;
@@ -39,6 +38,7 @@
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.Environment;
+import android.os.OperationCanceledException;
 import android.os.RemoteException;
 import android.service.media.CameraPrewarmService;
 import android.util.ArrayMap;
@@ -46,9 +46,6 @@
 
 import com.android.internal.annotations.GuardedBy;
 
-import libcore.io.IoUtils;
-
-import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -82,6 +79,11 @@
      */
     public static final String RETRANSLATE_CALL = "update_titles";
 
+    /** {@hide} */
+    public static final String GET_DOCUMENT_URI_CALL = "get_document_uri";
+    /** {@hide} */
+    public static final String GET_MEDIA_URI_CALL = "get_media_uri";
+
     /**
      * This is for internal use by the media scanner only.
      * Name of the (optional) Uri parameter that determines whether to skip deleting
@@ -402,7 +404,16 @@
          * access.
          * <p>
          * Type: TEXT
+         *
+         * @deprecated Apps may not have filesystem permissions to directly
+         *             access this path. Instead of trying to open this path
+         *             directly, apps should use
+         *             {@link ContentResolver#openFileDescriptor(Uri, String)}
+         *             to gain access. This value will always be {@code NULL}
+         *             for apps targeting
+         *             {@link android.os.Build.VERSION_CODES#Q} or higher.
          */
+        @Deprecated
         public static final String DATA = "_data";
 
         /**
@@ -641,6 +652,7 @@
      * This class is used internally by Images.Thumbnails and Video.Thumbnails, it's not intended
      * to be accessed elsewhere.
      */
+    @Deprecated
     private static class InternalThumbnails implements BaseColumns {
         /**
          * Currently outstanding thumbnail requests that can be cancelled.
@@ -654,13 +666,14 @@
          *
          * @see #cancelThumbnail(ContentResolver, Uri)
          */
+        @Deprecated
         static @Nullable Bitmap getThumbnail(@NonNull ContentResolver cr, @NonNull Uri uri,
                 int kind, @Nullable BitmapFactory.Options opts) {
-            final Bundle openOpts = new Bundle();
+            final Point size;
             if (kind == ThumbnailConstants.MICRO_KIND) {
-                openOpts.putParcelable(ContentResolver.EXTRA_SIZE, ThumbnailConstants.MICRO_SIZE);
+                size = ThumbnailConstants.MICRO_SIZE;
             } else if (kind == ThumbnailConstants.MINI_KIND) {
-                openOpts.putParcelable(ContentResolver.EXTRA_SIZE, ThumbnailConstants.MINI_SIZE);
+                size = ThumbnailConstants.MINI_SIZE;
             } else {
                 throw new IllegalArgumentException("Unsupported kind: " + kind);
             }
@@ -674,9 +687,8 @@
                 }
             }
 
-            try (AssetFileDescriptor afd = cr.openTypedAssetFileDescriptor(uri,
-                    "image/*", openOpts, signal)) {
-                return BitmapFactory.decodeFileDescriptor(afd.getFileDescriptor(), null, opts);
+            try {
+                return cr.loadThumbnail(uri, Point.convert(size), signal);
             } catch (IOException e) {
                 Log.w(TAG, "Failed to obtain thumbnail for " + uri, e);
                 return null;
@@ -693,6 +705,7 @@
          * Only the original process which made the request can cancel their own
          * requests.
          */
+        @Deprecated
         static void cancelThumbnail(@NonNull ContentResolver cr, @NonNull Uri uri) {
             synchronized (sPending) {
                 final CancellationSignal signal = sPending.get(uri);
@@ -936,9 +949,8 @@
         }
 
         /**
-         * This class allows developers to query and get two kinds of thumbnails:
-         * MINI_KIND: 512 x 384 thumbnail
-         * MICRO_KIND: 96 x 96 thumbnail
+         * This class provides utility methods to obtain thumbnails for various
+         * {@link Images} items.
          */
         public static class Thumbnails implements BaseColumns {
             public static final Cursor query(ContentResolver cr, Uri uri, String[] projection) {
@@ -958,13 +970,19 @@
             }
 
             /**
-             * This method cancels the thumbnail request so clients waiting for getThumbnail will be
-             * interrupted and return immediately. Only the original process which made the getThumbnail
-             * requests can cancel their own requests.
+             * Cancel any outstanding {@link #getThumbnail} requests, causing
+             * them to return by throwing a {@link OperationCanceledException}.
+             * <p>
+             * This method has no effect on
+             * {@link ContentResolver#loadThumbnail} calls, since they provide
+             * their own {@link CancellationSignal}.
              *
-             * @param cr ContentResolver
-             * @param origId original image id
+             * @deprecated Callers should migrate to using
+             *             {@link ContentResolver#loadThumbnail}, since it
+             *             offers richer control over requested thumbnail sizes
+             *             and cancellation behavior.
              */
+            @Deprecated
             public static void cancelThumbnailRequest(ContentResolver cr, long origId) {
                 final Uri uri = ContentUris.withAppendedId(
                         Images.Media.EXTERNAL_CONTENT_URI, origId);
@@ -972,51 +990,66 @@
             }
 
             /**
-             * This method checks if the thumbnails of the specified image (origId) has been created.
-             * It will be blocked until the thumbnails are generated.
+             * Return thumbnail representing a specific image item. If a
+             * thumbnail doesn't exist, this method will block until it's
+             * generated. Callers are responsible for their own in-memory
+             * caching of returned values.
              *
-             * @param cr ContentResolver used to dispatch queries to MediaProvider.
-             * @param origId Original image id associated with thumbnail of interest.
-             * @param kind The type of thumbnail to fetch. Should be either MINI_KIND or MICRO_KIND.
-             * @param options this is only used for MINI_KIND when decoding the Bitmap
-             * @return A Bitmap instance. It could be null if the original image
-             *         associated with origId doesn't exist or memory is not enough.
+             * @param imageId the image item to obtain a thumbnail for.
+             * @param kind optimal thumbnail size desired.
+             * @return decoded thumbnail, or {@code null} if problem was
+             *         encountered.
+             * @deprecated Callers should migrate to using
+             *             {@link ContentResolver#loadThumbnail}, since it
+             *             offers richer control over requested thumbnail sizes
+             *             and cancellation behavior.
              */
-            public static Bitmap getThumbnail(ContentResolver cr, long origId, int kind,
+            @Deprecated
+            public static Bitmap getThumbnail(ContentResolver cr, long imageId, int kind,
                     BitmapFactory.Options options) {
                 final Uri uri = ContentUris.withAppendedId(
-                        Images.Media.EXTERNAL_CONTENT_URI, origId);
+                        Images.Media.EXTERNAL_CONTENT_URI, imageId);
                 return InternalThumbnails.getThumbnail(cr, uri, kind, options);
             }
 
             /**
-             * This method cancels the thumbnail request so clients waiting for getThumbnail will be
-             * interrupted and return immediately. Only the original process which made the getThumbnail
-             * requests can cancel their own requests.
+             * Cancel any outstanding {@link #getThumbnail} requests, causing
+             * them to return by throwing a {@link OperationCanceledException}.
+             * <p>
+             * This method has no effect on
+             * {@link ContentResolver#loadThumbnail} calls, since they provide
+             * their own {@link CancellationSignal}.
              *
-             * @param cr ContentResolver
-             * @param origId original image id
-             * @param groupId the same groupId used in getThumbnail.
+             * @deprecated Callers should migrate to using
+             *             {@link ContentResolver#loadThumbnail}, since it
+             *             offers richer control over requested thumbnail sizes
+             *             and cancellation behavior.
              */
-            public static void cancelThumbnailRequest(ContentResolver cr, long origId, long groupId) {
+            @Deprecated
+            public static void cancelThumbnailRequest(ContentResolver cr, long origId,
+                    long groupId) {
                 cancelThumbnailRequest(cr, origId);
             }
 
             /**
-             * This method checks if the thumbnails of the specified image (origId) has been created.
-             * It will be blocked until the thumbnails are generated.
+             * Return thumbnail representing a specific image item. If a
+             * thumbnail doesn't exist, this method will block until it's
+             * generated. Callers are responsible for their own in-memory
+             * caching of returned values.
              *
-             * @param cr ContentResolver used to dispatch queries to MediaProvider.
-             * @param origId Original image id associated with thumbnail of interest.
-             * @param groupId the id of group to which this request belongs
-             * @param kind The type of thumbnail to fetch. Should be either MINI_KIND or MICRO_KIND.
-             * @param options this is only used for MINI_KIND when decoding the Bitmap
-             * @return A Bitmap instance. It could be null if the original image
-             *         associated with origId doesn't exist or memory is not enough.
+             * @param imageId the image item to obtain a thumbnail for.
+             * @param kind optimal thumbnail size desired.
+             * @return decoded thumbnail, or {@code null} if problem was
+             *         encountered.
+             * @deprecated Callers should migrate to using
+             *             {@link ContentResolver#loadThumbnail}, since it
+             *             offers richer control over requested thumbnail sizes
+             *             and cancellation behavior.
              */
-            public static Bitmap getThumbnail(ContentResolver cr, long origId, long groupId,
+            @Deprecated
+            public static Bitmap getThumbnail(ContentResolver cr, long imageId, long groupId,
                     int kind, BitmapFactory.Options options) {
-                return getThumbnail(cr, origId, kind, options);
+                return getThumbnail(cr, imageId, kind, options);
             }
 
             /**
@@ -1059,7 +1092,16 @@
              * access.
              * <p>
              * Type: TEXT
+             *
+             * @deprecated Apps may not have filesystem permissions to directly
+             *             access this path. Instead of trying to open this path
+             *             directly, apps should use
+             *             {@link ContentResolver#loadThumbnail}
+             *             to gain access. This value will always be
+             *             {@code NULL} for apps targeting
+             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
              */
+            @Deprecated
             public static final String DATA = "_data";
 
             /**
@@ -1509,7 +1551,16 @@
              * access.
              * <p>
              * Type: TEXT
+             *
+             * @deprecated Apps may not have filesystem permissions to directly
+             *             access this path. Instead of trying to open this path
+             *             directly, apps should use
+             *             {@link ContentResolver#openFileDescriptor(Uri, String)}
+             *             to gain access. This value will always be
+             *             {@code NULL} for apps targeting
+             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
              */
+            @Deprecated
             public static final String DATA = "_data";
 
             /**
@@ -1790,7 +1841,16 @@
             /**
              * Cached album art.
              * <P>Type: TEXT</P>
+             *
+             * @deprecated Apps may not have filesystem permissions to directly
+             *             access this path. Instead of trying to open this path
+             *             directly, apps should use
+             *             {@link ContentResolver#loadThumbnail}
+             *             to gain access. This value will always be
+             *             {@code NULL} for apps targeting
+             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
              */
+            @Deprecated
             public static final String ALBUM_ART = "album_art";
         }
 
@@ -2009,20 +2069,24 @@
         }
 
         /**
-         * This class allows developers to query and get two kinds of thumbnails:
-         * MINI_KIND: 512 x 384 thumbnail
-         * MICRO_KIND: 96 x 96 thumbnail
-         *
+         * This class provides utility methods to obtain thumbnails for various
+         * {@link Video} items.
          */
         public static class Thumbnails implements BaseColumns {
             /**
-             * This method cancels the thumbnail request so clients waiting for getThumbnail will be
-             * interrupted and return immediately. Only the original process which made the getThumbnail
-             * requests can cancel their own requests.
+             * Cancel any outstanding {@link #getThumbnail} requests, causing
+             * them to return by throwing a {@link OperationCanceledException}.
+             * <p>
+             * This method has no effect on
+             * {@link ContentResolver#loadThumbnail} calls, since they provide
+             * their own {@link CancellationSignal}.
              *
-             * @param cr ContentResolver
-             * @param origId original video id
+             * @deprecated Callers should migrate to using
+             *             {@link ContentResolver#loadThumbnail}, since it
+             *             offers richer control over requested thumbnail sizes
+             *             and cancellation behavior.
              */
+            @Deprecated
             public static void cancelThumbnailRequest(ContentResolver cr, long origId) {
                 final Uri uri = ContentUris.withAppendedId(
                         Video.Media.EXTERNAL_CONTENT_URI, origId);
@@ -2030,51 +2094,66 @@
             }
 
             /**
-             * This method checks if the thumbnails of the specified image (origId) has been created.
-             * It will be blocked until the thumbnails are generated.
+             * Return thumbnail representing a specific video item. If a
+             * thumbnail doesn't exist, this method will block until it's
+             * generated. Callers are responsible for their own in-memory
+             * caching of returned values.
              *
-             * @param cr ContentResolver used to dispatch queries to MediaProvider.
-             * @param origId Original image id associated with thumbnail of interest.
-             * @param kind The type of thumbnail to fetch. Should be either MINI_KIND or MICRO_KIND.
-             * @param options this is only used for MINI_KIND when decoding the Bitmap
-             * @return A Bitmap instance. It could be null if the original image
-             *         associated with origId doesn't exist or memory is not enough.
+             * @param videoId the video item to obtain a thumbnail for.
+             * @param kind optimal thumbnail size desired.
+             * @return decoded thumbnail, or {@code null} if problem was
+             *         encountered.
+             * @deprecated Callers should migrate to using
+             *             {@link ContentResolver#loadThumbnail}, since it
+             *             offers richer control over requested thumbnail sizes
+             *             and cancellation behavior.
              */
-            public static Bitmap getThumbnail(ContentResolver cr, long origId, int kind,
+            @Deprecated
+            public static Bitmap getThumbnail(ContentResolver cr, long videoId, int kind,
                     BitmapFactory.Options options) {
                 final Uri uri = ContentUris.withAppendedId(
-                        Video.Media.EXTERNAL_CONTENT_URI, origId);
+                        Video.Media.EXTERNAL_CONTENT_URI, videoId);
                 return InternalThumbnails.getThumbnail(cr, uri, kind, options);
             }
 
             /**
-             * This method checks if the thumbnails of the specified image (origId) has been created.
-             * It will be blocked until the thumbnails are generated.
+             * Cancel any outstanding {@link #getThumbnail} requests, causing
+             * them to return by throwing a {@link OperationCanceledException}.
+             * <p>
+             * This method has no effect on
+             * {@link ContentResolver#loadThumbnail} calls, since they provide
+             * their own {@link CancellationSignal}.
              *
-             * @param cr ContentResolver used to dispatch queries to MediaProvider.
-             * @param origId Original image id associated with thumbnail of interest.
-             * @param groupId the id of group to which this request belongs
-             * @param kind The type of thumbnail to fetch. Should be either MINI_KIND or MICRO_KIND
-             * @param options this is only used for MINI_KIND when decoding the Bitmap
-             * @return A Bitmap instance. It could be null if the original image associated with
-             *         origId doesn't exist or memory is not enough.
+             * @deprecated Callers should migrate to using
+             *             {@link ContentResolver#loadThumbnail}, since it
+             *             offers richer control over requested thumbnail sizes
+             *             and cancellation behavior.
              */
-            public static Bitmap getThumbnail(ContentResolver cr, long origId, long groupId,
-                    int kind, BitmapFactory.Options options) {
-                return getThumbnail(cr, origId, kind, options);
+            @Deprecated
+            public static void cancelThumbnailRequest(ContentResolver cr, long videoId,
+                    long groupId) {
+                cancelThumbnailRequest(cr, videoId);
             }
 
             /**
-             * This method cancels the thumbnail request so clients waiting for getThumbnail will be
-             * interrupted and return immediately. Only the original process which made the getThumbnail
-             * requests can cancel their own requests.
+             * Return thumbnail representing a specific video item. If a
+             * thumbnail doesn't exist, this method will block until it's
+             * generated. Callers are responsible for their own in-memory
+             * caching of returned values.
              *
-             * @param cr ContentResolver
-             * @param origId original video id
-             * @param groupId the same groupId used in getThumbnail.
+             * @param videoId the video item to obtain a thumbnail for.
+             * @param kind optimal thumbnail size desired.
+             * @return decoded thumbnail, or {@code null} if problem was
+             *         encountered.
+             * @deprecated Callers should migrate to using
+             *             {@link ContentResolver#loadThumbnail}, since it
+             *             offers richer control over requested thumbnail sizes
+             *             and cancellation behavior.
              */
-            public static void cancelThumbnailRequest(ContentResolver cr, long origId, long groupId) {
-                cancelThumbnailRequest(cr, origId);
+            @Deprecated
+            public static Bitmap getThumbnail(ContentResolver cr, long videoId, long groupId,
+                    int kind, BitmapFactory.Options options) {
+                return getThumbnail(cr, videoId, kind, options);
             }
 
             /**
@@ -2110,14 +2189,17 @@
             /**
              * Path to the thumbnail file on disk.
              * <p>
-             * Note that apps may not have filesystem permissions to directly
-             * access this path. Instead of trying to open this path directly,
-             * apps should use
-             * {@link ContentResolver#openFileDescriptor(Uri, String)} to gain
-             * access.
-             * <p>
              * Type: TEXT
+             *
+             * @deprecated Apps may not have filesystem permissions to directly
+             *             access this path. Instead of trying to open this path
+             *             directly, apps should use
+             *             {@link ContentResolver#openFileDescriptor(Uri, String)}
+             *             to gain access. This value will always be
+             *             {@code NULL} for apps targeting
+             *             {@link android.os.Build.VERSION_CODES#Q} or higher.
              */
+            @Deprecated
             public static final String DATA = "_data";
 
             /**
@@ -2195,84 +2277,62 @@
     }
 
     /**
-     * Gets a URI backed by a {@link DocumentsProvider} that points to the same media
-     * file as the specified mediaUri. This allows apps who have permissions to access
-     * media files in Storage Access Framework to perform file operations through that
-     * on media files.
+     * Return a {@link DocumentsProvider} Uri that is an equivalent to the given
+     * {@link MediaStore} Uri.
      * <p>
-     * Note: this method doesn't grant any URI permission. Callers need to obtain
-     * permission before calling this method. One way to obtain permission is through
-     * a 3-step process:
-     * <ol>
-     *     <li>Call {@link android.os.storage.StorageManager#getStorageVolume(File)} to
-     *     obtain the {@link android.os.storage.StorageVolume} of a media file;</li>
+     * This allows apps with Storage Access Framework permissions to convert
+     * between {@link MediaStore} and {@link DocumentsProvider} Uris that refer
+     * to the same underlying item. Note that this method doesn't grant any new
+     * permissions; callers must already hold permissions obtained with
+     * {@link Intent#ACTION_OPEN_DOCUMENT} or related APIs.
      *
-     *     <li>Invoke the intent returned by
-     *     {@link android.os.storage.StorageVolume#createAccessIntent(String)} to
-     *     obtain the access of the volume or one of its specific subdirectories;</li>
-     *
-     *     <li>Check whether permission is granted and take persistent permission.</li>
-     * </ol>
-     * @param mediaUri the media URI which document URI is requested
-     * @return the document URI
+     * @param mediaUri The {@link MediaStore} Uri to convert.
+     * @return An equivalent {@link DocumentsProvider} Uri. Returns {@code null}
+     *         if no equivalent was found.
+     * @see #getMediaUri(Context, Uri)
      */
     public static Uri getDocumentUri(Context context, Uri mediaUri) {
+        final ContentResolver resolver = context.getContentResolver();
+        final List<UriPermission> uriPermissions = resolver.getPersistedUriPermissions();
 
-        try {
-            final ContentResolver resolver = context.getContentResolver();
-
-            final String path = getFilePath(resolver, mediaUri);
-            final List<UriPermission> uriPermissions = resolver.getPersistedUriPermissions();
-
-            return getDocumentUri(resolver, path, uriPermissions);
+        try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) {
+            final Bundle in = new Bundle();
+            in.putParcelable(DocumentsContract.EXTRA_URI, mediaUri);
+            in.putParcelableList(DocumentsContract.EXTRA_URI_PERMISSIONS, uriPermissions);
+            final Bundle out = client.call(GET_DOCUMENT_URI_CALL, null, in);
+            return out.getParcelable(DocumentsContract.EXTRA_URI);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
         }
     }
 
-    private static String getFilePath(ContentResolver resolver, Uri mediaUri)
-            throws RemoteException {
+    /**
+     * Return a {@link MediaStore} Uri that is an equivalent to the given
+     * {@link DocumentsProvider} Uri.
+     * <p>
+     * This allows apps with Storage Access Framework permissions to convert
+     * between {@link MediaStore} and {@link DocumentsProvider} Uris that refer
+     * to the same underlying item. Note that this method doesn't grant any new
+     * permissions; callers must already hold permissions obtained with
+     * {@link Intent#ACTION_OPEN_DOCUMENT} or related APIs.
+     *
+     * @param documentUri The {@link DocumentsProvider} Uri to convert.
+     * @return An equivalent {@link MediaStore} Uri. Returns {@code null} if no
+     *         equivalent was found.
+     * @see #getDocumentUri(Context, Uri)
+     */
+    public static Uri getMediaUri(Context context, Uri documentUri) {
+        final ContentResolver resolver = context.getContentResolver();
+        final List<UriPermission> uriPermissions = resolver.getPersistedUriPermissions();
 
-        try (ContentProviderClient client =
-                     resolver.acquireUnstableContentProviderClient(AUTHORITY)) {
-            final Cursor c = client.query(
-                    mediaUri,
-                    new String[]{ MediaColumns.DATA },
-                    null, /* selection */
-                    null, /* selectionArg */
-                    null /* sortOrder */);
-
-            final String path;
-            try {
-                if (c.getCount() == 0) {
-                    throw new IllegalStateException("Not found media file under URI: " + mediaUri);
-                }
-
-                if (!c.moveToFirst()) {
-                    throw new IllegalStateException("Failed to move cursor to the first item.");
-                }
-
-                path = c.getString(0);
-            } finally {
-                IoUtils.closeQuietly(c);
-            }
-
-            return path;
-        }
-    }
-
-    private static Uri getDocumentUri(
-            ContentResolver resolver, String path, List<UriPermission> uriPermissions)
-            throws RemoteException {
-
-        try (ContentProviderClient client = resolver.acquireUnstableContentProviderClient(
-                DocumentsContract.EXTERNAL_STORAGE_PROVIDER_AUTHORITY)) {
+        try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) {
             final Bundle in = new Bundle();
-            in.putParcelableList(
-                    DocumentsContract.EXTERNAL_STORAGE_PROVIDER_AUTHORITY + ".extra.uriPermissions",
-                    uriPermissions);
-            final Bundle out = client.call("getDocumentId", path, in);
+            in.putParcelable(DocumentsContract.EXTRA_URI, documentUri);
+            in.putParcelableList(DocumentsContract.EXTRA_URI_PERMISSIONS, uriPermissions);
+            final Bundle out = client.call(GET_MEDIA_URI_CALL, null, in);
             return out.getParcelable(DocumentsContract.EXTRA_URI);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
         }
     }
 }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 80dbfe5..80e8f78 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -497,6 +497,16 @@
             "android.settings.BLUETOOTH_SETTINGS";
 
     /**
+     * Activity action: Show Settings app search UI when this action is available for device.
+     * <p>
+     * Input: Nothing.
+     * <p>
+     * Output: Nothing.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_APP_SEARCH_SETTINGS = "android.settings.APP_SEARCH_SETTINGS";
+
+    /**
      * Activity Action: Show settings to allow configuration of Assist Gesture.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
@@ -1463,12 +1473,13 @@
      * <p> If an user action is disabled by policy, this dialog can be triggered to let
      * the user know about this.
      * <p>
-     * Input: Nothing.
+     * Input: {@link Intent#EXTRA_USER}: The user of the admin.
      * <p>
      * Output: Nothing.
      *
      * @hide
      */
+    // Intent#EXTRA_USER_ID can also be used
     @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_SHOW_ADMIN_SUPPORT_DETAILS
@@ -1603,6 +1614,11 @@
     public static final String CALL_METHOD_GET_GLOBAL = "GET_global";
 
     /**
+     * @hide - Private call() method on SettingsProvider to read from 'config' table.
+     */
+    public static final String CALL_METHOD_GET_CONFIG = "GET_config";
+
+    /**
      * @hide - Specifies that the caller of the fast-path call()-based flow tracks
      * the settings generation in order to cache values locally. If this key is
      * mapped to a <code>null</code> string extra in the request bundle, the response
@@ -1661,9 +1677,15 @@
     /** @hide - Private call() method to write to 'global' table */
     public static final String CALL_METHOD_PUT_GLOBAL= "PUT_global";
 
+    /** @hide - Private call() method to write to 'configuration' table */
+    public static final String CALL_METHOD_PUT_CONFIG = "PUT_config";
+
     /** @hide - Private call() method to reset to defaults the 'global' table */
     public static final String CALL_METHOD_RESET_GLOBAL = "RESET_global";
 
+    /** @hide - Private call() method to reset to defaults the 'configuration' table */
+    public static final String CALL_METHOD_RESET_CONFIG = "RESET_config";
+
     /** @hide - Private call() method to reset to defaults the 'secure' table */
     public static final String CALL_METHOD_RESET_SECURE = "RESET_secure";
 
@@ -7365,6 +7387,15 @@
         public static final String DIALER_DEFAULT_APPLICATION = "dialer_default_application";
 
         /**
+         * Specifies the package name currently configured to be the default application to perform
+         * the user-defined call redirection service with Telecom.
+         * @hide
+         */
+        @UnsupportedAppUsage
+        public static final String CALL_REDIRECTION_DEFAULT_APPLICATION =
+                "call_redirection_default_application";
+
+        /**
          * Specifies the package name currently configured to be the emergency assistance application
          *
          * @see android.telephony.TelephonyManager#ACTION_EMERGENCY_ASSISTANCE
@@ -10876,6 +10907,7 @@
          * idle_pending_to                  (long)
          * max_idle_pending_to              (long)
          * idle_pending_factor              (float)
+         * quick_doze_delay_to              (long)
          * idle_to                          (long)
          * max_idle_to                      (long)
          * idle_factor                      (float)
@@ -10909,6 +10941,11 @@
          * gps_mode                          (int)
          * adjust_brightness_disabled        (boolean)
          * adjust_brightness_factor          (float)
+         * force_all_apps_standby            (boolean)
+         * force_background_check            (boolean)
+         * optional_sensors_disabled         (boolean)
+         * aod_disabled                      (boolean)
+         * quick_doze_enabled                (boolean)
          * </pre>
          * @hide
          * @see com.android.server.power.BatterySaverPolicy
@@ -11612,6 +11649,12 @@
         public static final String GPU_DEBUG_LAYERS = "gpu_debug_layers";
 
         /**
+         * Addition app for GPU layer discovery
+         * @hide
+         */
+        public static final String GPU_DEBUG_LAYER_APP = "gpu_debug_layer_app";
+
+        /**
          * Control whether the process CPU usage meter should be shown.
          *
          * @deprecated This functionality is no longer available as of
@@ -12332,6 +12375,40 @@
                 "location_global_kill_switch";
 
         /**
+         * If set to 1, app cannot request read sms permission unless it's the default sms handler.
+         *
+         * STOPSHIP: Remove this once we ship with the restriction enabled.
+         *
+         * @hide
+         */
+        @SystemApi
+        @TestApi
+        public static final String SMS_ACCESS_RESTRICTION_ENABLED =
+                "sms_access_restriction_enabled";
+
+        /**
+         * If set to 1, an app must have the READ_PRIVILEGED_PHONE_STATE permission (or be a device
+         * / profile owner with the READ_PHONE_STATE permission) to access device identifiers.
+         *
+         * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
+         *
+         * @hide
+         */
+        public static final String PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED =
+                "privileged_device_identifier_check_enabled";
+
+        /**
+         * If set to 1, an app that is targeting Q and does not meet the new requirements to access
+         * device identifiers will receive a SecurityException.
+         *
+         * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
+         *
+         * @hide
+         */
+        public static final String PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED =
+                "privileged_device_identifier_target_q_behavior_enabled";
+
+        /**
          * If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored
          * and restoring to lower version of platform API will be skipped.
          *
@@ -13401,6 +13478,112 @@
     }
 
     /**
+     * Configuration system settings, containing settings which are applied identically for all
+     * defined users. Only Android can read these and only a specific configuration service can
+     * write these.
+     *
+     * @hide
+     */
+    public static final class Config extends NameValueTable {
+        /**
+         * The content:// style URL for the config table.
+         *
+         * TODO(b/113100523): Move this to DeviceConfig.java when it is added, and expose it as a
+         *     System API.
+         */
+        private static final Uri CONTENT_URI =
+                Uri.parse("content://" + AUTHORITY + "/config");
+
+        private static final ContentProviderHolder sProviderHolder =
+                new ContentProviderHolder(CONTENT_URI);
+
+        // Populated lazily, guarded by class object:
+        private static final NameValueCache sNameValueCache = new NameValueCache(
+                CONTENT_URI,
+                CALL_METHOD_GET_CONFIG,
+                CALL_METHOD_PUT_CONFIG,
+                sProviderHolder);
+
+        /**
+         * Look up a name in the database.
+         * @param resolver to access the database with
+         * @param name to look up in the table
+         * @return the corresponding value, or null if not present
+         *
+         * @hide
+         */
+        // TODO(b/117663715): require a new read permission
+        static String getString(ContentResolver resolver, String name) {
+            return sNameValueCache.getStringForUser(resolver, name, resolver.getUserId());
+        }
+
+        /**
+         * Store a name/value pair into the database.
+         * <p>
+         * The method takes an optional tag to associate with the setting which can be used to clear
+         * only settings made by your package and associated with this tag by passing the tag to
+         * {@link #resetToDefaults(ContentResolver, String)}. The value of this setting can be
+         * overridden by future calls to this or other put methods, and the tag provided in those
+         * calls, which may be null, will override the tag provided in this call. Any call to a put
+         * method which does not accept a tag will effectively set the tag to null.
+         * </p><p>
+         * Also the method takes an argument whether to make the value the default for this setting.
+         * If the system already specified a default value, then the one passed in here will
+         * <strong>not</strong> be set as the default.
+         * </p>
+         *
+         * @param resolver to access the database with.
+         * @param name to store.
+         * @param value to associate with the name.
+         * @param tag to associated with the setting.
+         * @param makeDefault whether to make the value the default one.
+         * @return true if the value was set, false on database errors.
+         *
+         * @see #resetToDefaults(ContentResolver, String)
+         *
+         * @hide
+         */
+        // TODO(b/117663715): require a new write permission restricted to a single source
+        @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+        static boolean putString(@NonNull ContentResolver resolver,
+                @NonNull String name, @Nullable String value, @Nullable String tag,
+                boolean makeDefault) {
+            return sNameValueCache.putStringForUser(resolver, name, value, tag, makeDefault,
+                    resolver.getUserId());
+        }
+
+        /**
+         * Reset the settings to their defaults. This would reset <strong>only</strong> settings set
+         * by the caller's package. Passing in the optional tag will reset only settings changed by
+         * your package and associated with this tag.
+         *
+         * @param resolver Handle to the content resolver.
+         * @param tag Optional tag which should be associated with the settings to reset.
+         *
+         * @see #putString(ContentResolver, String, String, String, boolean)
+         *
+         * @hide
+         */
+        // TODO(b/117663715): require a new write permission restricted to a single source
+        @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+        static void resetToDefaults(@NonNull ContentResolver resolver,
+                @Nullable String tag) {
+            try {
+                Bundle arg = new Bundle();
+                arg.putInt(CALL_METHOD_USER_KEY, resolver.getUserId());
+                if (tag != null) {
+                    arg.putString(CALL_METHOD_TAG_KEY, tag);
+                }
+                arg.putInt(CALL_METHOD_RESET_MODE_KEY, RESET_MODE_PACKAGE_DEFAULTS);
+                IContentProvider cp = sProviderHolder.getProvider(resolver);
+                cp.call(resolver.getPackageName(), CALL_METHOD_RESET_CONFIG, null, arg);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Can't reset to defaults for " + CONTENT_URI, e);
+            }
+        }
+    }
+
+    /**
      * User-defined bookmarks and shortcuts.  The target of each bookmark is an
      * Intent URL, allowing it to be either a web page or a particular
      * application activity.
diff --git a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
index c748c87..035b226 100644
--- a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
+++ b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
@@ -113,19 +113,6 @@
     }
 
     /**
-     * Public key used to encrypt {@code encryptedRecoveryKeyBlob}.
-     *
-     * See implementation for binary key format.
-     *
-     * @deprecated Use {@link #getTrustedHardwareCertPath} instead.
-     * @removed
-     */
-    @Deprecated
-    public @NonNull byte[] getTrustedHardwarePublicKey() {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * CertPath containing the public key used to encrypt {@code encryptedRecoveryKeyBlob}.
      */
     public @NonNull CertPath getTrustedHardwareCertPath() {
@@ -223,18 +210,6 @@
         }
 
         /**
-         * Sets public key used to encrypt recovery blob.
-         *
-         * @param publicKey The public key
-         * @return This builder.
-         * @removed Use {@link #setTrustedHardwareCertPath} instead.
-         */
-        @Deprecated
-        public Builder setTrustedHardwarePublicKey(byte[] publicKey) {
-            throw new UnsupportedOperationException();
-        }
-
-        /**
          * Sets CertPath used to validate the trusted hardware public key. The CertPath should
          * contain a certificate of the trusted hardware public key and any necessary intermediate
          * certificates.
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index 70054fc..31a5962 100644
--- a/core/java/android/security/keystore/recovery/RecoveryController.java
+++ b/core/java/android/security/keystore/recovery/RecoveryController.java
@@ -23,7 +23,6 @@
 import android.app.KeyguardManager;
 import android.app.PendingIntent;
 import android.content.Context;
-import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
@@ -301,18 +300,6 @@
     }
 
     /**
-     * @deprecated Use {@link #initRecoveryService(String, byte[], byte[])} instead.
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public void initRecoveryService(
-            @NonNull String rootCertificateAlias, @NonNull byte[] signedPublicKeyList)
-            throws CertificateException, InternalRecoveryServiceException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Initializes the recovery service for the calling application. The detailed steps should be:
      * <ol>
      *     <li>Parse {@code signatureFile} to get relevant information.
@@ -363,16 +350,6 @@
     }
 
     /**
-     * @deprecated Use {@link #getKeyChainSnapshot()}
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public @Nullable KeyChainSnapshot getRecoveryData() throws InternalRecoveryServiceException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Returns data necessary to store all recoverable keys. Key material is
      * encrypted with user secret and recovery public key.
      *
@@ -440,17 +417,6 @@
     }
 
     /**
-     * @deprecated Use {@link #getAliases()}.
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public List<String> getAliases(@Nullable String packageName)
-            throws InternalRecoveryServiceException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Returns a list of aliases of keys belonging to the application.
      */
     @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
@@ -466,18 +432,6 @@
     }
 
     /**
-     * @deprecated Use {@link #setRecoveryStatus(String, int)}
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public void setRecoveryStatus(
-            @NonNull String packageName, String alias, int status)
-            throws NameNotFoundException, InternalRecoveryServiceException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Sets the recovery status for given key. It is used to notify the keystore that the key was
      * successfully stored on the server or that there was an error. An application can check this
      * value using {@link #getRecoveryStatus(String, String)}.
@@ -501,17 +455,6 @@
     }
 
     /**
-     * @deprecated Use {@link #getRecoveryStatus(String)}.
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public int getRecoveryStatus(String packageName, String alias)
-            throws InternalRecoveryServiceException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Returns the recovery status for the key with the given {@code alias}.
      *
      * <ul>
@@ -584,39 +527,6 @@
     }
 
     /**
-     * Deprecated.
-     * Generates a AES256/GCM/NoPADDING key called {@code alias} and loads it into the recoverable
-     * key store. Returns the raw material of the key.
-     *
-     * @param alias The key alias.
-     * @param account The account associated with the key
-     * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
-     *     service.
-     * @throws LockScreenRequiredException if the user has not set a lock screen. This is required
-     *     to generate recoverable keys, as the snapshots are encrypted using a key derived from the
-     *     lock screen.
-     * @deprecated Use {@link #generateKey(String)}
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public byte[] generateAndStoreKey(@NonNull String alias, byte[] account)
-            throws InternalRecoveryServiceException, LockScreenRequiredException {
-        throw new UnsupportedOperationException("Operation is not supported, use generateKey");
-    }
-
-    /**
-     * @deprecated Use {@link #generateKey(String)}.
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public Key generateKey(@NonNull String alias, byte[] account)
-            throws InternalRecoveryServiceException, LockScreenRequiredException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Generates a recoverable key with the given {@code alias}.
      *
      * @throws InternalRecoveryServiceException if an unexpected error occurred in the recovery
diff --git a/core/java/android/security/keystore/recovery/RecoverySession.java b/core/java/android/security/keystore/recovery/RecoverySession.java
index 3bb6421..42e7182 100644
--- a/core/java/android/security/keystore/recovery/RecoverySession.java
+++ b/core/java/android/security/keystore/recovery/RecoverySession.java
@@ -78,36 +78,6 @@
     }
 
     /**
-     * @deprecated Use {@link #start(String, CertPath, byte[], byte[], List)} instead.
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    @NonNull public byte[] start(
-            @NonNull byte[] verifierPublicKey,
-            @NonNull byte[] vaultParams,
-            @NonNull byte[] vaultChallenge,
-            @NonNull List<KeyChainProtectionParams> secrets)
-            throws CertificateException, InternalRecoveryServiceException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * @deprecated Use {@link #start(String, CertPath, byte[], byte[], List)} instead.
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    @NonNull public byte[] start(
-            @NonNull CertPath verifierCertPath,
-            @NonNull byte[] vaultParams,
-            @NonNull byte[] vaultChallenge,
-            @NonNull List<KeyChainProtectionParams> secrets)
-            throws CertificateException, InternalRecoveryServiceException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Starts a recovery session and returns a blob with proof of recovery secret possession.
      * The method generates a symmetric key for a session, which trusted remote device can use to
      * return recovery key.
@@ -162,20 +132,6 @@
     }
 
     /**
-     * @deprecated Use {@link #recoverKeyChainSnapshot(byte[], List)} instead.
-     * @removed
-     */
-    @Deprecated
-    @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
-    public Map<String, byte[]> recoverKeys(
-            @NonNull byte[] recoveryKeyBlob,
-            @NonNull List<WrappedApplicationKey> applicationKeys)
-            throws SessionExpiredException, DecryptionFailedException,
-            InternalRecoveryServiceException {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
      * Imports key chain snapshot recovered from a remote vault.
      *
      * @param recoveryKeyBlob Recovery blob encrypted by symmetric key generated for this session.
diff --git a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
index 187a671..ae4448f 100644
--- a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
+++ b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
@@ -75,15 +75,6 @@
         }
 
         /**
-         * @deprecated AOSP does not associate keys with accounts. This may be done by system app.
-         * @removed
-         */
-        @Deprecated
-        public Builder setAccount(@NonNull byte[] account) {
-            throw new UnsupportedOperationException();
-        }
-
-        /**
          * Sets key material encrypted by recovery key.
          *
          * @param encryptedKeyMaterial The key material
@@ -133,15 +124,6 @@
         return mEncryptedKeyMaterial;
     }
 
-    /**
-     * @deprecated AOSP does not associate keys with accounts. This may be done by system app.
-     * @removed
-     */
-    @Deprecated
-    public @NonNull byte[] getAccount() {
-        throw new UnsupportedOperationException();
-    }
-
     public static final Parcelable.Creator<WrappedApplicationKey> CREATOR =
             new Parcelable.Creator<WrappedApplicationKey>() {
                 public WrappedApplicationKey createFromParcel(Parcel in) {
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index d7fe15d..b8e0387 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -737,7 +737,8 @@
      * <p>This method will throw a security exception if you don't have access to notifications
      * for the given user.</p>
      * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
-     * device} in order to use this method.
+     * device} or be the {@link NotificationAssistantService notification assistant} in order to
+     * use this method.
      *
      * @param pkg The package to retrieve channels for.
      */
@@ -760,7 +761,8 @@
      * <p>This method will throw a security exception if you don't have access to notifications
      * for the given user.</p>
      * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
-     * device} in order to use this method.
+     * device} or be the {@link NotificationAssistantService notification assistant} in order to
+     * use this method.
      *
      * @param pkg The package to retrieve channel groups for.
      */
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 5012d77..37a9b10 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -473,6 +473,15 @@
         }
     }
 
+    private static Long tryParseLong(String value, Long defValue) {
+        if (TextUtils.isEmpty(value)) return defValue;
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            return defValue;
+        }
+    }
+
     public static ZenModeConfig readXml(XmlPullParser parser)
             throws XmlPullParserException, IOException {
         int type = parser.getEventType();
@@ -1288,7 +1297,9 @@
                 .authority(SYSTEM_AUTHORITY)
                 .appendPath(EVENT_PATH)
                 .appendQueryParameter("userId", Long.toString(event.userId))
-                .appendQueryParameter("calendar", event.calendar != null ? event.calendar : "")
+                .appendQueryParameter("calendar", event.calName != null ? event.calName : "")
+                .appendQueryParameter("calendarId", event.calendarId != null
+                        ? event.calendarId.toString() : "")
                 .appendQueryParameter("reply", Integer.toString(event.reply))
                 .build();
     }
@@ -1306,10 +1317,11 @@
         if (!isEvent) return null;
         final EventInfo rt = new EventInfo();
         rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL);
-        rt.calendar = conditionId.getQueryParameter("calendar");
-        if (TextUtils.isEmpty(rt.calendar) || tryParseLong(rt.calendar, -1L) != -1L) {
-            rt.calendar = null;
+        rt.calName = conditionId.getQueryParameter("calendar");
+        if (TextUtils.isEmpty(rt.calName)) {
+            rt.calName = null;
         }
+        rt.calendarId = tryParseLong(conditionId.getQueryParameter("calendarId"), null);
         rt.reply = tryParseInt(conditionId.getQueryParameter("reply"), 0);
         return rt;
     }
@@ -1324,12 +1336,13 @@
         public static final int REPLY_YES = 2;
 
         public int userId = UserHandle.USER_NULL;  // USER_NULL = unspecified - use current user
-        public String calendar;  // CalendarContract.Calendars.OWNER_ACCOUNT, or null for any
+        public String calName;  // CalendarContract.Calendars.DISPLAY_NAME, or null for any
+        public Long calendarId; // Calendars._ID, or null if restored from < Q calendar
         public int reply;
 
         @Override
         public int hashCode() {
-            return 0;
+            return Objects.hash(userId, calName, calendarId, reply);
         }
 
         @Override
@@ -1337,15 +1350,17 @@
             if (!(o instanceof EventInfo)) return false;
             final EventInfo other = (EventInfo) o;
             return userId == other.userId
-                    && Objects.equals(calendar, other.calendar)
-                    && reply == other.reply;
+                    && Objects.equals(calName, other.calName)
+                    && reply == other.reply
+                    && Objects.equals(calendarId, other.calendarId);
         }
 
         public EventInfo copy() {
             final EventInfo rt = new EventInfo();
             rt.userId = userId;
-            rt.calendar = calendar;
+            rt.calName = calName;
             rt.reply = reply;
+            rt.calendarId = calendarId;
             return rt;
         }
 
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index b461c0d..7af9db8 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -405,8 +405,8 @@
                 PackageManager.MATCH_SYSTEM_ONLY);
 
         if ((ri == null) || (ri.serviceInfo == null)) {
-            Slog.w(LOG_TAG, String.format("Package or service not found in package %s",
-                    packageName));
+            Slog.w(LOG_TAG, String.format("Package or service not found in package %s for user %d",
+                    packageName, context.getUserId()));
             return null;
         }
         final ServiceInfo si = ri.serviceInfo;
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index 10d7911..ec63cd9 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -1112,7 +1112,6 @@
 
         @Override
         protected void playImpl() {
-            dispatchOnStart();
             super.playImpl();
             try {
               mFileOutputStream.close();
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index c89617f..3ab8a0a 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -23,6 +23,7 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Rect;
+import android.graphics.text.LineBreaker;
 import android.text.method.TextKeyListener;
 import android.text.style.AlignmentSpan;
 import android.text.style.LeadingMarginSpan;
@@ -50,9 +51,9 @@
 public abstract class Layout {
     /** @hide */
     @IntDef(prefix = { "BREAK_STRATEGY_" }, value = {
-            NativeLineBreaker.BREAK_STRATEGY_SIMPLE,
-            NativeLineBreaker.BREAK_STRATEGY_HIGH_QUALITY,
-            NativeLineBreaker.BREAK_STRATEGY_BALANCED
+            LineBreaker.BREAK_STRATEGY_SIMPLE,
+            LineBreaker.BREAK_STRATEGY_HIGH_QUALITY,
+            LineBreaker.BREAK_STRATEGY_BALANCED
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface BreakStrategy {}
@@ -63,20 +64,19 @@
      * before it (which yields a more consistent user experience when editing), but layout may not
      * be the highest quality.
      */
-    public static final int BREAK_STRATEGY_SIMPLE = NativeLineBreaker.BREAK_STRATEGY_SIMPLE;
+    public static final int BREAK_STRATEGY_SIMPLE = LineBreaker.BREAK_STRATEGY_SIMPLE;
 
     /**
      * Value for break strategy indicating high quality line breaking, including automatic
      * hyphenation and doing whole-paragraph optimization of line breaks.
      */
-    public static final int BREAK_STRATEGY_HIGH_QUALITY =
-            NativeLineBreaker.BREAK_STRATEGY_HIGH_QUALITY;
+    public static final int BREAK_STRATEGY_HIGH_QUALITY = LineBreaker.BREAK_STRATEGY_HIGH_QUALITY;
 
     /**
      * Value for break strategy indicating balanced line breaking. The breaks are chosen to
      * make all lines as close to the same length as possible, including automatic hyphenation.
      */
-    public static final int BREAK_STRATEGY_BALANCED = NativeLineBreaker.BREAK_STRATEGY_BALANCED;
+    public static final int BREAK_STRATEGY_BALANCED = LineBreaker.BREAK_STRATEGY_BALANCED;
 
     /** @hide */
     @IntDef(prefix = { "HYPHENATION_FREQUENCY_" }, value = {
@@ -94,32 +94,29 @@
      * layout and there is otherwise no valid break. Soft hyphens are ignored and will not be used
      * as suggestions for potential line breaks.
      */
-    public static final int HYPHENATION_FREQUENCY_NONE =
-            NativeLineBreaker.HYPHENATION_FREQUENCY_NONE;
+    public static final int HYPHENATION_FREQUENCY_NONE = LineBreaker.HYPHENATION_FREQUENCY_NONE;
 
     /**
      * Value for hyphenation frequency indicating a light amount of automatic hyphenation, which
      * is a conservative default. Useful for informal cases, such as short sentences or chat
      * messages.
      */
-    public static final int HYPHENATION_FREQUENCY_NORMAL =
-            NativeLineBreaker.HYPHENATION_FREQUENCY_NORMAL;
+    public static final int HYPHENATION_FREQUENCY_NORMAL = LineBreaker.HYPHENATION_FREQUENCY_NORMAL;
 
     /**
      * Value for hyphenation frequency indicating the full amount of automatic hyphenation, typical
      * in typography. Useful for running text and where it's important to put the maximum amount of
      * text in a screen with limited space.
      */
-    public static final int HYPHENATION_FREQUENCY_FULL =
-            NativeLineBreaker.HYPHENATION_FREQUENCY_FULL;
+    public static final int HYPHENATION_FREQUENCY_FULL = LineBreaker.HYPHENATION_FREQUENCY_FULL;
 
     private static final ParagraphStyle[] NO_PARA_SPANS =
         ArrayUtils.emptyArray(ParagraphStyle.class);
 
     /** @hide */
     @IntDef(prefix = { "JUSTIFICATION_MODE_" }, value = {
-            NativeLineBreaker.JUSTIFICATION_MODE_NONE,
-            NativeLineBreaker.JUSTIFICATION_MODE_INTER_WORD
+            LineBreaker.JUSTIFICATION_MODE_NONE,
+            LineBreaker.JUSTIFICATION_MODE_INTER_WORD
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface JustificationMode {}
@@ -127,13 +124,13 @@
     /**
      * Value for justification mode indicating no justification.
      */
-    public static final int JUSTIFICATION_MODE_NONE = NativeLineBreaker.JUSTIFICATION_MODE_NONE;
+    public static final int JUSTIFICATION_MODE_NONE = LineBreaker.JUSTIFICATION_MODE_NONE;
 
     /**
      * Value for justification mode indicating the text is justified by stretching word spacing.
      */
     public static final int JUSTIFICATION_MODE_INTER_WORD =
-            NativeLineBreaker.JUSTIFICATION_MODE_INTER_WORD;
+            LineBreaker.JUSTIFICATION_MODE_INTER_WORD;
 
     /*
      * Line spacing multiplier for default line spacing.
@@ -1809,6 +1806,7 @@
         }
 
     }
+
     /**
      * Fills in the specified Path with a representation of a cursor
      * at the specified offset.  This will often be a vertical line
@@ -1824,7 +1822,6 @@
 
         boolean clamped = shouldClampCursor(line);
         float h1 = getPrimaryHorizontal(point, clamped) - 0.5f;
-        float h2 = isLevelBoundary(point) ? getSecondaryHorizontal(point, clamped) - 0.5f : h1;
 
         int caps = TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SHIFT_ON) |
                    TextKeyListener.getMetaState(editingBuffer, TextKeyListener.META_SELECTING);
@@ -1842,34 +1839,24 @@
 
         if (h1 < 0.5f)
             h1 = 0.5f;
-        if (h2 < 0.5f)
-            h2 = 0.5f;
 
-        if (Float.compare(h1, h2) == 0) {
-            dest.moveTo(h1, top);
-            dest.lineTo(h1, bottom);
-        } else {
-            dest.moveTo(h1, top);
-            dest.lineTo(h1, (top + bottom) >> 1);
-
-            dest.moveTo(h2, (top + bottom) >> 1);
-            dest.lineTo(h2, bottom);
-        }
+        dest.moveTo(h1, top);
+        dest.lineTo(h1, bottom);
 
         if (caps == 2) {
-            dest.moveTo(h2, bottom);
-            dest.lineTo(h2 - dist, bottom + dist);
-            dest.lineTo(h2, bottom);
-            dest.lineTo(h2 + dist, bottom + dist);
+            dest.moveTo(h1, bottom);
+            dest.lineTo(h1 - dist, bottom + dist);
+            dest.lineTo(h1, bottom);
+            dest.lineTo(h1 + dist, bottom + dist);
         } else if (caps == 1) {
-            dest.moveTo(h2, bottom);
-            dest.lineTo(h2 - dist, bottom + dist);
+            dest.moveTo(h1, bottom);
+            dest.lineTo(h1 - dist, bottom + dist);
 
-            dest.moveTo(h2 - dist, bottom + dist - 0.5f);
-            dest.lineTo(h2 + dist, bottom + dist - 0.5f);
+            dest.moveTo(h1 - dist, bottom + dist - 0.5f);
+            dest.lineTo(h1 + dist, bottom + dist - 0.5f);
 
-            dest.moveTo(h2 + dist, bottom + dist);
-            dest.lineTo(h2, bottom);
+            dest.moveTo(h1 + dist, bottom + dist);
+            dest.lineTo(h1, bottom);
         }
 
         if (fn == 2) {
diff --git a/core/java/android/text/MeasuredParagraph.java b/core/java/android/text/MeasuredParagraph.java
index 9bf8cd2..f9370a8 100644
--- a/core/java/android/text/MeasuredParagraph.java
+++ b/core/java/android/text/MeasuredParagraph.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.graphics.Paint;
 import android.graphics.Rect;
+import android.graphics.text.MeasuredText;
 import android.text.AutoGrowArray.ByteArray;
 import android.text.AutoGrowArray.FloatArray;
 import android.text.AutoGrowArray.IntArray;
@@ -121,7 +122,7 @@
     private @Nullable IntArray mFontMetrics = new IntArray(4 * 4);
 
     // The native MeasuredParagraph.
-    private @Nullable NativeMeasuredParagraph mNativeMeasuredParagraph;
+    private @Nullable MeasuredText mMeasuredText;
 
     // Following two objects are for avoiding object allocation.
     private @NonNull TextPaint mCachedPaint = new TextPaint();
@@ -149,7 +150,7 @@
         mWidths.clear();
         mFontMetrics.clear();
         mSpanEndCache.clear();
-        mNativeMeasuredParagraph = null;
+        mMeasuredText = null;
     }
 
     /**
@@ -245,8 +246,8 @@
      * This is available only if the MeasuredParagraph is computed with buildForStaticLayout.
      * Returns null in other cases.
      */
-    public NativeMeasuredParagraph getNativeMeasuredParagraph() {
-        return mNativeMeasuredParagraph;
+    public MeasuredText getMeasuredText() {
+        return mMeasuredText;
     }
 
     /**
@@ -259,7 +260,7 @@
      * @param end the exclusive end offset of the target region in the text
      */
     public float getWidth(int start, int end) {
-        if (mNativeMeasuredParagraph == null) {
+        if (mMeasuredText == null) {
             // We have result in Java.
             final float[] widths = mWidths.getRawArray();
             float r = 0.0f;
@@ -269,7 +270,7 @@
             return r;
         } else {
             // We have result in native.
-            return mNativeMeasuredParagraph.getWidth(start, end);
+            return mMeasuredText.getWidth(start, end);
         }
     }
 
@@ -281,7 +282,7 @@
      */
     public void getBounds(@IntRange(from = 0) int start, @IntRange(from = 0) int end,
             @NonNull Rect bounds) {
-        mNativeMeasuredParagraph.getBounds(mCopiedBuffer, start, end, bounds);
+        mMeasuredText.getBounds(start, end, bounds);
     }
 
     /**
@@ -290,7 +291,7 @@
      * This is available only if the MeasuredParagraph is computed with buildForStaticLayout.
      */
     public float getCharWidthAt(@IntRange(from = 0) int offset) {
-        return mNativeMeasuredParagraph.getCharWidthAt(offset);
+        return mMeasuredText.getCharWidthAt(offset);
     }
 
     /**
@@ -391,12 +392,13 @@
             @Nullable MeasuredParagraph recycle) {
         final MeasuredParagraph mt = recycle == null ? obtain() : recycle;
         mt.resetAndAnalyzeBidi(text, start, end, textDir);
-        final NativeMeasuredParagraph.Builder builder = new NativeMeasuredParagraph.Builder();
+        final MeasuredText.Builder builder = new MeasuredText.Builder(mt.mCopiedBuffer);
+        builder.setComputeHyphenation(computeHyphenation);
+        builder.setComputeLayout(computeLayout);
         if (mt.mTextLength == 0) {
             // Need to build empty native measured text for StaticLayout.
             // TODO: Stop creating empty measured text for empty lines.
-            mt.mNativeMeasuredParagraph = builder.build(mt.mCopiedBuffer, computeHyphenation,
-                        computeLayout);
+            mt.mMeasuredText = builder.build();
         } else {
             if (mt.mSpanned == null) {
                 // No style change by MetricsAffectingSpan. Just measure all text.
@@ -417,8 +419,7 @@
                     mt.mSpanEndCache.append(spanEnd);
                 }
             }
-            mt.mNativeMeasuredParagraph = builder.build(mt.mCopiedBuffer, computeHyphenation,
-                    computeLayout);
+            mt.mMeasuredText = builder.build();
         }
 
         return mt;
@@ -490,7 +491,7 @@
     private void applyReplacementRun(@NonNull ReplacementSpan replacement,
                                      @IntRange(from = 0) int start,  // inclusive, in copied buffer
                                      @IntRange(from = 0) int end,  // exclusive, in copied buffer
-                                     @Nullable NativeMeasuredParagraph.Builder builder) {
+                                     @Nullable MeasuredText.Builder builder) {
         // Use original text. Shouldn't matter.
         // TODO: passing uninitizlied FontMetrics to developers. Do we need to keep this for
         //       backward compatibility? or Should we initialize them for getFontMetricsInt?
@@ -504,13 +505,13 @@
             }
             mWholeWidth += width;
         } else {
-            builder.addReplacementRun(mCachedPaint, start, end, width);
+            builder.appendReplacementRun(mCachedPaint, end - start, width);
         }
     }
 
     private void applyStyleRun(@IntRange(from = 0) int start,  // inclusive, in copied buffer
                                @IntRange(from = 0) int end,  // exclusive, in copied buffer
-                               @Nullable NativeMeasuredParagraph.Builder builder) {
+                               @Nullable MeasuredText.Builder builder) {
 
         if (mLtrWithoutBidi) {
             // If the whole text is LTR direction, just apply whole region.
@@ -519,7 +520,7 @@
                         mCopiedBuffer, start, end - start, start, end - start, false /* isRtl */,
                         mWidths.getRawArray(), start);
             } else {
-                builder.addStyleRun(mCachedPaint, start, end, false /* isRtl */);
+                builder.appendStyleRun(mCachedPaint, end - start, false /* isRtl */);
             }
         } else {
             // If there is multiple bidi levels, split into individual bidi level and apply style.
@@ -535,7 +536,7 @@
                                 mCopiedBuffer, levelStart, levelLength, levelStart, levelLength,
                                 isRtl, mWidths.getRawArray(), levelStart);
                     } else {
-                        builder.addStyleRun(mCachedPaint, levelStart, levelEnd, isRtl);
+                        builder.appendStyleRun(mCachedPaint, levelEnd - levelStart, isRtl);
                     }
                     if (levelEnd == end) {
                         break;
@@ -552,7 +553,7 @@
             @Nullable MetricAffectingSpan[] spans,
             @IntRange(from = 0) int start,  // inclusive, in original text buffer
             @IntRange(from = 0) int end,  // exclusive, in original text buffer
-            @Nullable NativeMeasuredParagraph.Builder builder) {
+            @Nullable MeasuredText.Builder builder) {
         mCachedPaint.set(paint);
         // XXX paint should not have a baseline shift, but...
         mCachedPaint.baselineShift = 0;
@@ -658,6 +659,6 @@
      * This only works if the MeasuredParagraph is computed with buildForStaticLayout.
      */
     public @IntRange(from = 0) int getMemoryUsage() {
-        return mNativeMeasuredParagraph.getMemoryUsage();
+        return mMeasuredText.getMemoryUsage();
     }
 }
diff --git a/core/java/android/text/NativeMeasuredParagraph.java b/core/java/android/text/NativeMeasuredParagraph.java
deleted file mode 100644
index bfdccca..0000000
--- a/core/java/android/text/NativeMeasuredParagraph.java
+++ /dev/null
@@ -1,185 +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.text;
-
-import android.annotation.FloatRange;
-import android.annotation.IntRange;
-import android.annotation.NonNull;
-import android.graphics.Paint;
-import android.graphics.Rect;
-
-import dalvik.annotation.optimization.CriticalNative;
-
-import libcore.util.NativeAllocationRegistry;
-
-/**
- * A native implementation of measured paragraph.
- * TODO: Consider to make this class public.
- * @hide
- */
-public class NativeMeasuredParagraph {
-    private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-            NativeMeasuredParagraph.class.getClassLoader(), nGetReleaseFunc(), 1024);
-
-    private long mNativePtr;
-    private @NonNull char[] mChars;
-
-    // Use builder instead.
-    private NativeMeasuredParagraph(long ptr, @NonNull char[] chars) {
-        mNativePtr = ptr;
-        mChars = chars;
-    }
-
-    /**
-     * Returns a characters of this paragraph.
-     */
-    public char[] getChars() {
-        return mChars;
-    }
-
-    /**
-     * Returns a width of the given region
-     */
-    public float getWidth(int start, int end) {
-        return nGetWidth(mNativePtr, start, end);
-    }
-
-    /**
-     * Returns a memory usage of the native object.
-     */
-    public int getMemoryUsage() {
-        return nGetMemoryUsage(mNativePtr);
-    }
-
-    /**
-     * Fills the boundary box of the given region
-     */
-    public void getBounds(char[] buf, int start, int end, Rect rect) {
-        nGetBounds(mNativePtr, buf, start, end, rect);
-    }
-
-    /**
-     * Returns the width of the character at the given offset
-     */
-    public float getCharWidthAt(int offset) {
-        return nGetCharWidthAt(mNativePtr, offset);
-    }
-
-    /**
-     * Returns a native pointer of the underlying native object.
-     */
-    public long getNativePtr() {
-        return mNativePtr;
-    }
-
-    @CriticalNative
-    private static native float nGetWidth(/* Non Zero */ long nativePtr,
-                                         @IntRange(from = 0) int start,
-                                         @IntRange(from = 0) int end);
-
-    @CriticalNative
-    private static native /* Non Zero */ long nGetReleaseFunc();
-
-    @CriticalNative
-    private static native int nGetMemoryUsage(/* Non Zero */ long nativePtr);
-
-    private static native void nGetBounds(long nativePtr, char[] buf, int start, int end,
-            Rect rect);
-
-    @CriticalNative
-    private static native float nGetCharWidthAt(long nativePtr, int offset);
-
-    /**
-     * A builder for the NativeMeasuredParagraph
-     */
-    public static class Builder {
-        private final long mNativePtr;
-
-        public Builder() {
-            mNativePtr = nInitBuilder();
-        }
-
-        /**
-         * Apply styles to given range
-         */
-        public void addStyleRun(@NonNull Paint paint, int start, int end, boolean isRtl) {
-            nAddStyleRun(mNativePtr, paint.getNativeInstance(), start, end, isRtl);
-        }
-
-        /**
-         * Tells native that the given range is replaced with the object of given width.
-         */
-        public void addReplacementRun(@NonNull Paint paint, int start, int end, float width) {
-            nAddReplacementRun(mNativePtr, paint.getNativeInstance(), start, end, width);
-        }
-
-        /**
-         * Build the NativeMeasuredParagraph
-         */
-        public NativeMeasuredParagraph build(char[] text, boolean computeHyphenation,
-                boolean computeLayout) {
-            try {
-                long ptr = nBuildNativeMeasuredParagraph(mNativePtr, text, computeHyphenation,
-                        computeLayout);
-                NativeMeasuredParagraph res = new NativeMeasuredParagraph(ptr, text);
-                sRegistry.registerNativeAllocation(res, ptr);
-                return res;
-            } finally {
-                nFreeBuilder(mNativePtr);
-            }
-        }
-
-        private static native /* Non Zero */ long nInitBuilder();
-
-        /**
-         * Apply style to make native measured text.
-         *
-         * @param nativeBuilderPtr The native MeasuredParagraph builder pointer.
-         * @param paintPtr The native paint pointer to be applied.
-         * @param start The start offset in the copied buffer.
-         * @param end The end offset in the copied buffer.
-         * @param isRtl True if the text is RTL.
-         */
-        private static native void nAddStyleRun(/* Non Zero */ long nativeBuilderPtr,
-                                                /* Non Zero */ long paintPtr,
-                                                @IntRange(from = 0) int start,
-                                                @IntRange(from = 0) int end,
-                                                boolean isRtl);
-        /**
-         * Apply ReplacementRun to make native measured text.
-         *
-         * @param nativeBuilderPtr The native MeasuredParagraph builder pointer.
-         * @param paintPtr The native paint pointer to be applied.
-         * @param start The start offset in the copied buffer.
-         * @param end The end offset in the copied buffer.
-         * @param width The width of the replacement.
-         */
-        private static native void nAddReplacementRun(/* Non Zero */ long nativeBuilderPtr,
-                                                      /* Non Zero */ long paintPtr,
-                                                      @IntRange(from = 0) int start,
-                                                      @IntRange(from = 0) int end,
-                                                      @FloatRange(from = 0) float width);
-
-        private static native long nBuildNativeMeasuredParagraph(
-                /* Non Zero */ long nativeBuilderPtr,
-                @NonNull char[] text,
-                boolean computeHyphenation,
-                boolean computeLayout);
-
-        private static native void nFreeBuilder(/* Non Zero */ long nativeBuilderPtr);
-    }
-}
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index d2f0853..2cf0262 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Paint;
+import android.graphics.text.LineBreaker;
 import android.os.Build;
 import android.text.style.LeadingMarginSpan;
 import android.text.style.LeadingMarginSpan.LeadingMarginSpan2;
@@ -55,7 +56,7 @@
      *
      *   - Create MeasuredParagraph by MeasuredParagraph.buildForStaticLayout which measures in
      *     native.
-     *   - Run NativeLineBreaker.computeLineBreaks() to obtain line breaks for the paragraph.
+     *   - Run LineBreaker.computeLineBreaks() to obtain line breaks for the paragraph.
      *
      * After all paragraphs, call finish() to release expensive buffers.
      */
@@ -634,7 +635,7 @@
             indents = null;
         }
 
-        final NativeLineBreaker lineBreaker = new NativeLineBreaker.Builder()
+        final LineBreaker lineBreaker = new LineBreaker.Builder()
                 .setBreakStrategy(b.mBreakStrategy)
                 .setHyphenationFrequency(b.mHyphenationFrequency)
                 // TODO: Support more justification mode, e.g. letter spacing, stretching.
@@ -642,8 +643,8 @@
                 .setIndents(indents)
                 .build();
 
-        NativeLineBreaker.ParagraphConstraints constraints =
-                new NativeLineBreaker.ParagraphConstraints();
+        LineBreaker.ParagraphConstraints constraints =
+                new LineBreaker.ParagraphConstraints();
 
         PrecomputedText.ParagraphInfo[] paragraphInfo = null;
         final Spanned spanned = (source instanceof Spanned) ? (Spanned) source : null;
@@ -739,8 +740,8 @@
             constraints.setIndent(firstWidth, firstWidthLineCount);
             constraints.setTabStops(variableTabStops, TAB_INCREMENT);
 
-            NativeLineBreaker.Result res = lineBreaker.computeLineBreaks(
-                    measuredPara.getNativeMeasuredParagraph(), constraints, mLineCount);
+            LineBreaker.Result res = lineBreaker.computeLineBreaks(
+                    measuredPara.getMeasuredText(), constraints, mLineCount);
             int breakCount = res.getLineCount();
             if (lineBreakCapacity < breakCount) {
                 lineBreakCapacity = breakCount;
@@ -776,7 +777,7 @@
                         width += lineWidths[i];
                     } else {
                         for (int j = (i == 0 ? 0 : breaks[i - 1]); j < breaks[i]; j++) {
-                            width += measuredPara.getCharWidthAt(j - paraStart);
+                            width += measuredPara.getCharWidthAt(j);
                         }
                     }
                     hasTab |= hasTabs[i];
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index e31e928..195de07 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -16,7 +16,10 @@
 
 package android.text;
 
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
 import android.annotation.FloatRange;
+import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -42,6 +45,7 @@
 import android.text.style.EasyEditSpan;
 import android.text.style.ForegroundColorSpan;
 import android.text.style.LeadingMarginSpan;
+import android.text.style.LineBackgroundSpan;
 import android.text.style.LocaleSpan;
 import android.text.style.ParagraphStyle;
 import android.text.style.QuoteSpan;
@@ -69,7 +73,9 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
 
+import java.lang.annotation.Retention;
 import java.lang.reflect.Array;
+import java.util.BitSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
@@ -87,6 +93,44 @@
     private static final String ELLIPSIS_NORMAL = "\u2026"; // HORIZONTAL ELLIPSIS (…)
     private static final String ELLIPSIS_TWO_DOTS = "\u2025"; // TWO DOT LEADER (‥)
 
+    private static final int LINE_FEED_CODE_POINT = 10;
+    private static final int NBSP_CODE_POINT = 160;
+
+    /**
+     * Flags for {@link #makeSafeForPresentation(String, int, float, int)}
+     *
+     * @hide
+     */
+    @Retention(SOURCE)
+    @IntDef(flag = true, prefix = "CLEAN_STRING_FLAG_",
+            value = {SAFE_STRING_FLAG_TRIM, SAFE_STRING_FLAG_SINGLE_LINE,
+                    SAFE_STRING_FLAG_FIRST_LINE})
+    public @interface SafeStringFlags {}
+
+    /**
+     * Remove {@link Character#isWhitespace(int) whitespace} and non-breaking spaces from the edges
+     * of the label.
+     *
+     * @see #makeSafeForPresentation(String, int, float, int)
+     */
+    public static final int SAFE_STRING_FLAG_TRIM = 0x1;
+
+    /**
+     * Force entire string into single line of text (no newlines). Cannot be set at the same time as
+     * {@link #SAFE_STRING_FLAG_FIRST_LINE}.
+     *
+     * @see #makeSafeForPresentation(String, int, float, int)
+     */
+    public static final int SAFE_STRING_FLAG_SINGLE_LINE = 0x2;
+
+    /**
+     * Return only first line of text (truncate at first newline). Cannot be set at the same time as
+     * {@link #SAFE_STRING_FLAG_SINGLE_LINE}.
+     *
+     * @see #makeSafeForPresentation(String, int, float, int)
+     */
+    public static final int SAFE_STRING_FLAG_FIRST_LINE = 0x4;
+
     /** {@hide} */
     @NonNull
     public static String getEllipsisString(@NonNull TextUtils.TruncateAt method) {
@@ -687,7 +731,9 @@
     /** @hide */
     public static final int ACCESSIBILITY_URL_SPAN = 26;
     /** @hide */
-    public static final int LAST_SPAN = ACCESSIBILITY_URL_SPAN;
+    public static final int LINE_BACKGROUND_SPAN = 27;
+    /** @hide */
+    public static final int LAST_SPAN = LINE_BACKGROUND_SPAN;
 
     /**
      * Flatten a CharSequence and whatever styles can be copied across processes
@@ -878,6 +924,10 @@
                     readSpan(p, sp, new AccessibilityURLSpan(p));
                     break;
 
+                case LINE_BACKGROUND_SPAN:
+                    readSpan(p, sp, new LineBackgroundSpan.Standard(p));
+                    break;
+
                 default:
                     throw new RuntimeException("bogus span encoding " + kind);
                 }
@@ -2116,6 +2166,222 @@
         return trimmed;
     }
 
+    private static boolean isNewline(int codePoint) {
+        int type = Character.getType(codePoint);
+        return type == Character.PARAGRAPH_SEPARATOR || type == Character.LINE_SEPARATOR
+                || codePoint == LINE_FEED_CODE_POINT;
+    }
+
+    private static boolean isWhiteSpace(int codePoint) {
+        return Character.isWhitespace(codePoint) || codePoint == NBSP_CODE_POINT;
+    }
+
+    /**
+     * Remove html, remove bad characters, and truncate string.
+     *
+     * <p>This method is meant to remove common mistakes and nefarious formatting from strings that
+     * were loaded from untrusted sources (such as other packages).
+     *
+     * <p>This method first {@link Html#fromHtml treats the string like HTML} and then ...
+     * <ul>
+     * <li>Removes new lines or truncates at first new line
+     * <li>Trims the white-space off the end
+     * <li>Truncates the string
+     * </ul>
+     * ... if specified.
+     *
+     * @param unclean The input string
+     * @param maxCharactersToConsider The maximum number of characters of {@code unclean} to
+     *                                consider from the input string. {@code 0} disables this
+     *                                feature.
+     * @param ellipsizeDip Assuming maximum length of the string (in dip), assuming font size 42.
+     *                     This is roughly 50 characters for {@code ellipsizeDip == 1000}.<br />
+     *                     Usually ellipsizing should be left to the view showing the string. If a
+     *                     string is used as an input to another string, it might be useful to
+     *                     control the length of the input string though. {@code 0} disables this
+     *                     feature.
+     * @param flags Flags controlling cleaning behavior (Can be {@link #SAFE_STRING_FLAG_TRIM},
+     *              {@link #SAFE_STRING_FLAG_SINGLE_LINE},
+     *              and {@link #SAFE_STRING_FLAG_FIRST_LINE})
+     *
+     * @return The cleaned string
+     */
+    public static @NonNull CharSequence makeSafeForPresentation(@NonNull String unclean,
+            @IntRange(from = 0) int maxCharactersToConsider,
+            @FloatRange(from = 0) float ellipsizeDip, @SafeStringFlags int flags) {
+        boolean onlyKeepFirstLine = ((flags & SAFE_STRING_FLAG_FIRST_LINE) != 0);
+        boolean forceSingleLine = ((flags & SAFE_STRING_FLAG_SINGLE_LINE) != 0);
+        boolean trim = ((flags & SAFE_STRING_FLAG_TRIM) != 0);
+
+        Preconditions.checkNotNull(unclean);
+        Preconditions.checkArgumentNonnegative(maxCharactersToConsider);
+        Preconditions.checkArgumentNonNegative(ellipsizeDip, "ellipsizeDip");
+        Preconditions.checkFlagsArgument(flags, SAFE_STRING_FLAG_TRIM
+                | SAFE_STRING_FLAG_SINGLE_LINE | SAFE_STRING_FLAG_FIRST_LINE);
+        Preconditions.checkArgument(!(onlyKeepFirstLine && forceSingleLine),
+                "Cannot set SAFE_STRING_FLAG_SINGLE_LINE and SAFE_STRING_FLAG_FIRST_LINE at the"
+                        + "same time");
+
+        String shortString;
+        if (maxCharactersToConsider > 0) {
+            shortString = unclean.substring(0, Math.min(unclean.length(), maxCharactersToConsider));
+        } else {
+            shortString = unclean;
+        }
+
+        // Treat string as HTML. This
+        // - converts HTML symbols: e.g. &szlig; -> ß
+        // - applies some HTML tags: e.g. <br> -> \n
+        // - removes invalid characters such as \b
+        // - removes html styling, such as <b>
+        // - applies html formatting: e.g. a<p>b</p>c -> a\n\nb\n\nc
+        // - replaces some html tags by "object replacement" markers: <img> -> \ufffc
+        // - Removes leading white space
+        // - Removes all trailing white space beside a single space
+        // - Collapses double white space
+        StringWithRemovedChars gettingCleaned = new StringWithRemovedChars(
+                Html.fromHtml(shortString).toString());
+
+        int firstNonWhiteSpace = -1;
+        int firstTrailingWhiteSpace = -1;
+
+        // Remove new lines (if requested) and control characters.
+        int uncleanLength = gettingCleaned.length();
+        for (int offset = 0; offset < uncleanLength; ) {
+            int codePoint = gettingCleaned.codePointAt(offset);
+            int type = Character.getType(codePoint);
+            int codePointLen = Character.charCount(codePoint);
+            boolean isNewline = isNewline(codePoint);
+
+            if (onlyKeepFirstLine && isNewline) {
+                gettingCleaned.removeAllCharAfter(offset);
+                break;
+            } else if (forceSingleLine && isNewline) {
+                gettingCleaned.removeRange(offset, offset + codePointLen);
+            } else if (type == Character.CONTROL && !isNewline) {
+                gettingCleaned.removeRange(offset, offset + codePointLen);
+            } else if (trim && !isWhiteSpace(codePoint)) {
+                // This is only executed if the code point is not removed
+                if (firstNonWhiteSpace == -1) {
+                    firstNonWhiteSpace = offset;
+                }
+                firstTrailingWhiteSpace = offset + codePointLen;
+            }
+
+            offset += codePointLen;
+        }
+
+        if (trim) {
+            // Remove leading and trailing white space
+            if (firstNonWhiteSpace == -1) {
+                // No non whitespace found, remove all
+                gettingCleaned.removeAllCharAfter(0);
+            } else {
+                if (firstNonWhiteSpace > 0) {
+                    gettingCleaned.removeAllCharBefore(firstNonWhiteSpace);
+                }
+                if (firstTrailingWhiteSpace < uncleanLength) {
+                    gettingCleaned.removeAllCharAfter(firstTrailingWhiteSpace);
+                }
+            }
+        }
+
+        if (ellipsizeDip == 0) {
+            return gettingCleaned.toString();
+        } else {
+            // Truncate
+            final TextPaint paint = new TextPaint();
+            paint.setTextSize(42);
+
+            return TextUtils.ellipsize(gettingCleaned.toString(), paint, ellipsizeDip,
+                    TextUtils.TruncateAt.END);
+        }
+    }
+
+    /**
+     * A special string manipulation class. Just records removals and executes the when onString()
+     * is called.
+     */
+    private static class StringWithRemovedChars {
+        /** The original string */
+        private final String mOriginal;
+
+        /**
+         * One bit per char in string. If bit is set, character needs to be removed. If whole
+         * bit field is not initialized nothing needs to be removed.
+         */
+        private BitSet mRemovedChars;
+
+        StringWithRemovedChars(@NonNull String original) {
+            mOriginal = original;
+        }
+
+        /**
+         * Mark all chars in a range {@code [firstRemoved - firstNonRemoved[} (not including
+         * firstNonRemoved) as removed.
+         */
+        void removeRange(int firstRemoved, int firstNonRemoved) {
+            if (mRemovedChars == null) {
+                mRemovedChars = new BitSet(mOriginal.length());
+            }
+
+            mRemovedChars.set(firstRemoved, firstNonRemoved);
+        }
+
+        /**
+         * Remove all characters before {@code firstNonRemoved}.
+         */
+        void removeAllCharBefore(int firstNonRemoved) {
+            if (mRemovedChars == null) {
+                mRemovedChars = new BitSet(mOriginal.length());
+            }
+
+            mRemovedChars.set(0, firstNonRemoved);
+        }
+
+        /**
+         * Remove all characters after and including {@code firstRemoved}.
+         */
+        void removeAllCharAfter(int firstRemoved) {
+            if (mRemovedChars == null) {
+                mRemovedChars = new BitSet(mOriginal.length());
+            }
+
+            mRemovedChars.set(firstRemoved, mOriginal.length());
+        }
+
+        @Override
+        public String toString() {
+            // Common case, no chars removed
+            if (mRemovedChars == null) {
+                return mOriginal;
+            }
+
+            StringBuilder sb = new StringBuilder(mOriginal.length());
+            for (int i = 0; i < mOriginal.length(); i++) {
+                if (!mRemovedChars.get(i)) {
+                    sb.append(mOriginal.charAt(i));
+                }
+            }
+
+            return sb.toString();
+        }
+
+        /**
+         * Return length or the original string
+         */
+        int length() {
+            return mOriginal.length();
+        }
+
+        /**
+         * Return codePoint of original string at a certain {@code offset}
+         */
+        int codePointAt(int offset) {
+            return mOriginal.codePointAt(offset);
+        }
+    }
+
     private static Object sLock = new Object();
 
     private static char[] sTemp = null;
diff --git a/core/java/android/text/style/LineBackgroundSpan.java b/core/java/android/text/style/LineBackgroundSpan.java
index 9c7859f..5a55fd7 100644
--- a/core/java/android/text/style/LineBackgroundSpan.java
+++ b/core/java/android/text/style/LineBackgroundSpan.java
@@ -16,15 +16,110 @@
 
 package android.text.style;
 
+import android.annotation.ColorInt;
+import android.annotation.NonNull;
+import android.annotation.Px;
 import android.graphics.Canvas;
 import android.graphics.Paint;
+import android.os.Parcel;
+import android.text.ParcelableSpan;
+import android.text.TextUtils;
 
-public interface LineBackgroundSpan
-extends ParagraphStyle
+/**
+ * Used to change the background of lines where the span is attached to.
+ */
+public interface LineBackgroundSpan extends ParagraphStyle
 {
-    public void drawBackground(Canvas c, Paint p,
-                               int left, int right,
-                               int top, int baseline, int bottom,
-                               CharSequence text, int start, int end,
-                               int lnum);
+    /**
+     * Draw the background on the canvas.
+     *
+     * @param canvas      canvas on which the span should be rendered
+     * @param paint       paint used to draw text, which should be left unchanged on exit
+     * @param left        left position of the line relative to input canvas, in pixels
+     * @param right       right position of the line relative to input canvas, in pixels
+     * @param top         top position of the line relative to input canvas, in pixels
+     * @param baseline    baseline of the text relative to input canvas, in pixels
+     * @param bottom      bottom position of the line relative to input canvas, in pixels
+     * @param text        current text
+     * @param start       start character index of the line
+     * @param end         end character index of the line
+     * @param lineNumber  line number in the current text layout
+     */
+    void drawBackground(@NonNull Canvas canvas, @NonNull Paint paint,
+                               @Px int left, @Px int right,
+                               @Px int top, @Px int baseline, @Px int bottom,
+                               @NonNull CharSequence text, int start, int end,
+                               int lineNumber);
+    /**
+     * Default implementation of the {@link LineBackgroundSpan}, which changes the background
+     * color of the lines to which the span is attached.
+     */
+    class Standard implements LineBackgroundSpan, ParcelableSpan {
+
+        private final int mColor;
+
+        /**
+         * Constructor taking a color integer.
+         *
+         * @param color Color integer that defines the background color.
+         */
+        public Standard(@ColorInt int color) {
+            mColor = color;
+        }
+
+        /**
+         * Creates a {@link LineBackgroundSpan.Standard} from a parcel
+         */
+        public Standard(@NonNull Parcel src) {
+            mColor = src.readInt();
+        }
+
+        @Override
+        public int getSpanTypeId() {
+            return getSpanTypeIdInternal();
+        }
+
+        /** @hide */
+        @Override
+        public int getSpanTypeIdInternal() {
+            return TextUtils.LINE_BACKGROUND_SPAN;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            writeToParcelInternal(dest, flags);
+        }
+
+        /** @hide */
+        @Override
+        public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
+            dest.writeInt(mColor);
+        }
+
+        /**
+         * @return the color of this span.
+         * @see Standard#Standard(int)
+         */
+        @ColorInt
+        public final int getColor() {
+            return mColor;
+        }
+
+        @Override
+        public void drawBackground(@NonNull Canvas canvas, @NonNull Paint paint,
+                @Px int left, @Px int right,
+                @Px int top, @Px int baseline, @Px int bottom,
+                @NonNull CharSequence text, int start, int end,
+                int lineNumber) {
+            final int originColor = paint.getColor();
+            paint.setColor(mColor);
+            canvas.drawRect(left, right, top, bottom, paint);
+            paint.setColor(originColor);
+        }
+    }
 }
diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java
index 2dc4f60..2355769 100644
--- a/core/java/android/text/style/TextAppearanceSpan.java
+++ b/core/java/android/text/style/TextAppearanceSpan.java
@@ -22,15 +22,41 @@
 import android.content.res.TypedArray;
 import android.graphics.LeakyTypefaceStorage;
 import android.graphics.Typeface;
-import android.graphics.fonts.Font;
+import android.graphics.fonts.FontStyle;
+import android.os.LocaleList;
 import android.os.Parcel;
 import android.text.ParcelableSpan;
 import android.text.TextPaint;
 import android.text.TextUtils;
 
 /**
- * Sets the text color, size, style, and typeface to match a TextAppearance
- * resource.
+ * Sets the text appearance using the given
+ * {@link android.R.styleable#TextAppearance TextAppearance} attributes.
+ * By default {@link TextAppearanceSpan} only changes the specified attributes in XML.
+ * {@link android.R.styleable#TextAppearance_textColorHighlight textColorHighlight},
+ * {@link android.R.styleable#TextAppearance_textColorHint textColorHint},
+ * {@link android.R.styleable#TextAppearance_textAllCaps textAllCaps} and
+ * {@link android.R.styleable#TextAppearance_fallbackLineSpacing fallbackLineSpacing}
+ * are not supported by {@link TextAppearanceSpan}.
+ *
+ * {@see android.widget.TextView#setTextAppearance(int)}
+ *
+ * @attr ref android.R.styleable#TextAppearance_fontFamily
+ * @attr ref android.R.styleable#TextAppearance_textColor
+ * @attr ref android.R.styleable#TextAppearance_textColorLink
+ * @attr ref android.R.styleable#TextAppearance_textFontWeight
+ * @attr ref android.R.styleable#TextAppearance_textSize
+ * @attr ref android.R.styleable#TextAppearance_textStyle
+ * @attr ref android.R.styleable#TextAppearance_typeface
+ * @attr ref android.R.styleable#TextAppearance_shadowColor
+ * @attr ref android.R.styleable#TextAppearance_shadowDx
+ * @attr ref android.R.styleable#TextAppearance_shadowDy
+ * @attr ref android.R.styleable#TextAppearance_shadowRadius
+ * @attr ref android.R.styleable#TextAppearance_elegantTextHeight
+ * @attr ref android.R.styleable#TextAppearance_letterSpacing
+ * @attr ref android.R.styleable#TextAppearance_fontFeatureSettings
+ * @attr ref android.R.styleable#TextAppearance_fontVariationSettings
+ *
  */
 public class TextAppearanceSpan extends MetricAffectingSpan implements ParcelableSpan {
     private final String mFamilyName;
@@ -41,6 +67,7 @@
     private final Typeface mTypeface;
 
     private final int mTextFontWeight;
+    private final LocaleList mTextLocales;
 
     private final float mShadowRadius;
     private final float mShadowDx;
@@ -124,6 +151,19 @@
         mTextFontWeight = a.getInt(com.android.internal.R.styleable
                 .TextAppearance_textFontWeight, -1);
 
+        final String localeString = a.getString(com.android.internal.R.styleable
+                .TextAppearance_textLocale);
+        if (localeString != null) {
+            LocaleList localeList = LocaleList.forLanguageTags(localeString);
+            if (!localeList.isEmpty()) {
+                mTextLocales = localeList;
+            } else {
+                mTextLocales = null;
+            }
+        } else {
+            mTextLocales = null;
+        }
+
         mShadowRadius = a.getFloat(com.android.internal.R.styleable
                 .TextAppearance_shadowRadius, 0.0f);
         mShadowDx = a.getFloat(com.android.internal.R.styleable
@@ -176,6 +216,7 @@
         mTypeface = null;
 
         mTextFontWeight = -1;
+        mTextLocales = null;
 
         mShadowRadius = 0.0f;
         mShadowDx = 0.0f;
@@ -208,6 +249,7 @@
         mTypeface = LeakyTypefaceStorage.readTypefaceFromParcel(src);
 
         mTextFontWeight = src.readInt();
+        mTextLocales = src.readParcelable(LocaleList.class.getClassLoader());
 
         mShadowRadius = src.readFloat();
         mShadowDx = src.readFloat();
@@ -260,6 +302,7 @@
         LeakyTypefaceStorage.writeTypefaceToParcel(mTypeface, dest);
 
         dest.writeInt(mTextFontWeight);
+        dest.writeParcelable(mTextLocales, flags);
 
         dest.writeFloat(mShadowRadius);
         dest.writeFloat(mShadowDx);
@@ -324,6 +367,15 @@
     }
 
     /**
+     * Returns the {@link android.os.LocaleList} specified by this span, or <code>null</code>
+     * if it does not specify one.
+     */
+    @Nullable
+    public LocaleList getTextLocales() {
+        return mTextLocales;
+    }
+
+    /**
      * Returns the typeface specified by this span, or <code>null</code>
      * if it does not specify one.
      */
@@ -438,7 +490,7 @@
         if (styledTypeface != null) {
             final Typeface readyTypeface;
             if (mTextFontWeight >= 0) {
-                final int weight = Math.min(Font.FONT_WEIGHT_MAX, mTextFontWeight);
+                final int weight = Math.min(FontStyle.FONT_WEIGHT_MAX, mTextFontWeight);
                 final boolean italic = (style & Typeface.ITALIC) != 0;
                 readyTypeface = ds.setTypeface(Typeface.create(styledTypeface, weight, italic));
             } else {
@@ -462,6 +514,10 @@
             ds.setTextSize(mTextSize);
         }
 
+        if (mTextLocales != null) {
+            ds.setTextLocales(mTextLocales);
+        }
+
         if (mHasElegantTextHeight) {
             ds.setElegantTextHeight(mElegantTextHeight);
         }
diff --git a/core/java/android/transition/TransitionManager.java b/core/java/android/transition/TransitionManager.java
index 4608e20..0e5252e 100644
--- a/core/java/android/transition/TransitionManager.java
+++ b/core/java/android/transition/TransitionManager.java
@@ -315,6 +315,7 @@
                     ArrayList<Transition> currentTransitions =
                             runningTransitions.get(mSceneRoot);
                     currentTransitions.remove(transition);
+                    transition.removeListener(this);
                 }
             });
             mTransition.captureValues(mSceneRoot, false);
diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java
index 319f080..bd2bef4 100644
--- a/core/java/android/transition/Visibility.java
+++ b/core/java/android/transition/Visibility.java
@@ -25,6 +25,7 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroupOverlay;
 
 import com.android.internal.R;
 
@@ -413,7 +414,6 @@
             }
         }
         final int finalVisibility = endVisibility;
-        final ViewGroup finalSceneRoot = sceneRoot;
 
         if (overlayView != null) {
             // TODO: Need to do this for general case of adding to overlay
@@ -424,16 +424,32 @@
             sceneRoot.getLocationOnScreen(loc);
             overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
             overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
-            sceneRoot.getOverlay().add(overlayView);
+            final ViewGroupOverlay overlay = sceneRoot.getOverlay();
+            overlay.add(overlayView);
             Animator animator = onDisappear(sceneRoot, overlayView, startValues, endValues);
             if (animator == null) {
-                sceneRoot.getOverlay().remove(overlayView);
+                overlay.remove(overlayView);
             } else {
                 final View finalOverlayView = overlayView;
                 addListener(new TransitionListenerAdapter() {
+
+                    @Override
+                    public void onTransitionPause(Transition transition) {
+                        overlay.remove(finalOverlayView);
+                    }
+
+                    @Override
+                    public void onTransitionResume(Transition transition) {
+                        if (finalOverlayView.getParent() == null) {
+                            overlay.add(finalOverlayView);
+                        } else {
+                            cancel();
+                        }
+                    }
+
                     @Override
                     public void onTransitionEnd(Transition transition) {
-                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+                        overlay.remove(finalOverlayView);
                         transition.removeListener(this);
                     }
                 });
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 183e833..db2c190 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -47,7 +47,7 @@
         DEFAULT_FLAGS.put("settings_mobile_network_v2", "false");
         DEFAULT_FLAGS.put("settings_data_usage_v2", "false");
         DEFAULT_FLAGS.put("settings_seamless_transfer", "false");
-        DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "true");
+        DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
         DEFAULT_FLAGS.put(EMERGENCY_DIAL_SHORTCUTS, "false");
     }
 
diff --git a/core/java/android/util/JsonReader.java b/core/java/android/util/JsonReader.java
index 7d1c6c4..50f63f8 100644
--- a/core/java/android/util/JsonReader.java
+++ b/core/java/android/util/JsonReader.java
@@ -16,13 +16,15 @@
 
 package android.util;
 
+import libcore.internal.StringPool;
+
 import java.io.Closeable;
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.Reader;
 import java.util.ArrayList;
 import java.util.List;
-import libcore.internal.StringPool;
+
 
 /**
  * Reads a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
@@ -295,7 +297,7 @@
 
     /**
      * Consumes the next token from the JSON stream and asserts that it is the
-     * end of the current array.
+     * end of the current object.
      */
     public void endObject() throws IOException {
         expect(JsonToken.END_OBJECT);
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index a299b11..ac4ea75 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -81,19 +81,17 @@
             Certificate[][] signerCerts = new Certificate[][] { vSigner.certs };
             Signature[] signerSigs = convertToSignatures(signerCerts);
             Signature[] pastSignerSigs = null;
-            int[] pastSignerSigsFlags = null;
             if (vSigner.por != null) {
                 // populate proof-of-rotation information
                 pastSignerSigs = new Signature[vSigner.por.certs.size()];
-                pastSignerSigsFlags = new int[vSigner.por.flagsList.size()];
                 for (int i = 0; i < pastSignerSigs.length; i++) {
                     pastSignerSigs[i] = new Signature(vSigner.por.certs.get(i).getEncoded());
-                    pastSignerSigsFlags[i] = vSigner.por.flagsList.get(i);
+                    pastSignerSigs[i].setFlags(vSigner.por.flagsList.get(i));
                 }
             }
             return new PackageParser.SigningDetails(
                     signerSigs, SignatureSchemeVersion.SIGNING_BLOCK_V3,
-                    pastSignerSigs, pastSignerSigsFlags);
+                    pastSignerSigs);
         } catch (SignatureNotFoundException e) {
             // not signed with v3, try older if allowed
             if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V3) {
@@ -323,19 +321,17 @@
             Certificate[][] signerCerts = new Certificate[][] { vSigner.certs };
             Signature[] signerSigs = convertToSignatures(signerCerts);
             Signature[] pastSignerSigs = null;
-            int[] pastSignerSigsFlags = null;
             if (vSigner.por != null) {
                 // populate proof-of-rotation information
                 pastSignerSigs = new Signature[vSigner.por.certs.size()];
-                pastSignerSigsFlags = new int[vSigner.por.flagsList.size()];
                 for (int i = 0; i < pastSignerSigs.length; i++) {
                     pastSignerSigs[i] = new Signature(vSigner.por.certs.get(i).getEncoded());
-                    pastSignerSigsFlags[i] = vSigner.por.flagsList.get(i);
+                    pastSignerSigs[i].setFlags(vSigner.por.flagsList.get(i));
                 }
             }
             return new PackageParser.SigningDetails(
                     signerSigs, SignatureSchemeVersion.SIGNING_BLOCK_V3,
-                    pastSignerSigs, pastSignerSigsFlags);
+                    pastSignerSigs);
         } catch (SignatureNotFoundException e) {
             // not signed with v3, try older if allowed
             if (minSignatureSchemeVersion >= SignatureSchemeVersion.SIGNING_BLOCK_V3) {
diff --git a/core/java/android/util/proto/ProtoInputStream.java b/core/java/android/util/proto/ProtoInputStream.java
index 209451b..cd2b6ce 100644
--- a/core/java/android/util/proto/ProtoInputStream.java
+++ b/core/java/android/util/proto/ProtoInputStream.java
@@ -737,8 +737,7 @@
         fillBuffer();
         if (mOffset + n <= mEnd) {
             // fast path read. String is well within the current buffer
-            String value = StringFactory.newStringFromBytes(mBuffer, mOffset, n,
-                    StandardCharsets.UTF_8);
+            String value = new String(mBuffer, mOffset, n, StandardCharsets.UTF_8);
             incOffset(n);
             return value;
         } else if (n <= mBufferSize) {
@@ -752,14 +751,13 @@
             mDiscardedBytes += mOffset;
             mOffset = 0;
 
-            String value = StringFactory.newStringFromBytes(mBuffer, mOffset, n,
-                    StandardCharsets.UTF_8);
+            String value = new String(mBuffer, mOffset, n, StandardCharsets.UTF_8);
             incOffset(n);
             return value;
         }
         // Otherwise, the string is too large to use the buffer. Create the string from a
         // separate byte array.
-        return StringFactory.newStringFromBytes(readRawBytes(n), 0, n, StandardCharsets.UTF_8);
+        return new String(readRawBytes(n), 0, n, StandardCharsets.UTF_8);
     }
 
     /**
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 4d96fc3..719a401 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -221,6 +221,18 @@
     public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
 
     /**
+     * Display flag: Indicates that the display should show system decorations.
+     * <p>
+     * This flag identifies secondary displays that should show system decorations, such as status
+     * bar, navigation bar, home activity or IME.
+     * </p>
+     *
+     * @see #supportsSystemDecorations
+     * @hide
+     */
+    public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 6;
+
+    /**
      * Display flag: Indicates that the contents of the display should not be scaled
      * to fit the physical screen dimensions.  Used for development only to emulate
      * devices with smaller physicals screens while preserving density.
@@ -874,6 +886,16 @@
     }
 
     /**
+     * Returns whether this display should support showing system decorations.
+     *
+     * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+     * @hide
+     */
+    public boolean supportsSystemDecorations() {
+        return (mDisplayInfo.flags & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0;
+    }
+
+    /**
      * Returns the display's HDR capabilities.
      *
      * @see #isHdr()
diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java
index 5f80d31..e9f1edf 100644
--- a/core/java/android/view/DisplayCutout.java
+++ b/core/java/android/view/DisplayCutout.java
@@ -18,12 +18,19 @@
 
 import static android.util.DisplayMetrics.DENSITY_DEFAULT;
 import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
-import static android.view.DisplayCutoutProto.BOUNDS;
+import static android.view.DisplayCutoutProto.BOUND_BOTTOM;
+import static android.view.DisplayCutoutProto.BOUND_LEFT;
+import static android.view.DisplayCutoutProto.BOUND_RIGHT;
+import static android.view.DisplayCutoutProto.BOUND_TOP;
 import static android.view.DisplayCutoutProto.INSETS;
 
 import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
 
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.res.Resources;
+import android.graphics.Insets;
 import android.graphics.Matrix;
 import android.graphics.Path;
 import android.graphics.Rect;
@@ -42,7 +49,10 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -68,14 +78,14 @@
             "com.android.internal.display_cutout_emulation";
 
     private static final Rect ZERO_RECT = new Rect();
-    private static final Region EMPTY_REGION = new Region();
 
     /**
      * An instance where {@link #isEmpty()} returns {@code true}.
      *
      * @hide
      */
-    public static final DisplayCutout NO_CUTOUT = new DisplayCutout(ZERO_RECT, EMPTY_REGION,
+    public static final DisplayCutout NO_CUTOUT = new DisplayCutout(
+            ZERO_RECT, ZERO_RECT, ZERO_RECT, ZERO_RECT, ZERO_RECT,
             false /* copyArguments */);
 
 
@@ -94,7 +104,151 @@
     private static Pair<Path, DisplayCutout> sCachedCutout = NULL_PAIR;
 
     private final Rect mSafeInsets;
-    private final Region mBounds;
+
+
+    /**
+     * The bound is at the left of the screen.
+     * @hide
+     */
+    public static final int BOUNDS_POSITION_LEFT = 0;
+
+    /**
+     * The bound is at the top of the screen.
+     * @hide
+     */
+    public static final int BOUNDS_POSITION_TOP = 1;
+
+    /**
+     * The bound is at the right of the screen.
+     * @hide
+     */
+    public static final int BOUNDS_POSITION_RIGHT = 2;
+
+    /**
+     * The bound is at the bottom of the screen.
+     * @hide
+     */
+    public static final int BOUNDS_POSITION_BOTTOM = 3;
+
+    /**
+     * The number of possible positions at which bounds can be located.
+     * @hide
+     */
+    public static final int BOUNDS_POSITION_LENGTH = 4;
+
+    /** @hide */
+    @IntDef(prefix = { "BOUNDS_POSITION_" }, value = {
+            BOUNDS_POSITION_LEFT,
+            BOUNDS_POSITION_TOP,
+            BOUNDS_POSITION_RIGHT,
+            BOUNDS_POSITION_BOTTOM
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BoundsPosition {}
+
+    private static class Bounds {
+        private final Rect[] mRects;
+
+        private Bounds(Rect left, Rect top, Rect right, Rect bottom, boolean copyArguments) {
+            mRects = new Rect[BOUNDS_POSITION_LENGTH];
+            mRects[BOUNDS_POSITION_LEFT] = getCopyOrRef(left, copyArguments);
+            mRects[BOUNDS_POSITION_TOP] = getCopyOrRef(top, copyArguments);
+            mRects[BOUNDS_POSITION_RIGHT] = getCopyOrRef(right, copyArguments);
+            mRects[BOUNDS_POSITION_BOTTOM] = getCopyOrRef(bottom, copyArguments);
+
+        }
+
+        private Bounds(Rect[] rects, boolean copyArguments) {
+            if (rects.length != BOUNDS_POSITION_LENGTH) {
+                throw new IllegalArgumentException(
+                        "rects must have exactly 4 elements: rects=" + Arrays.toString(rects));
+            }
+            if (copyArguments) {
+                mRects = new Rect[BOUNDS_POSITION_LENGTH];
+                for (int i = 0; i < BOUNDS_POSITION_LENGTH; ++i) {
+                    mRects[i] = new Rect(rects[i]);
+                }
+            } else {
+                for (Rect rect : rects) {
+                    if (rect == null) {
+                        throw new IllegalArgumentException(
+                                "rects must have non-null elements: rects="
+                                        + Arrays.toString(rects));
+                    }
+                }
+                mRects = rects;
+            }
+        }
+
+        private boolean isEmpty() {
+            for (Rect rect : mRects) {
+                if (!rect.isEmpty()) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        private Rect getRect(@BoundsPosition int pos) {
+            return new Rect(mRects[pos]);
+        }
+
+        private Rect[] getRects() {
+            Rect[] rects = new Rect[BOUNDS_POSITION_LENGTH];
+            for (int i = 0; i < BOUNDS_POSITION_LENGTH; ++i) {
+                rects[i] = new Rect(mRects[i]);
+            }
+            return rects;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = 0;
+            for (Rect rect : mRects) {
+                result = result * 48271 + rect.hashCode();
+            }
+            return result;
+        }
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            }
+            if (o instanceof Bounds) {
+                Bounds b = (Bounds) o;
+                return Arrays.deepEquals(mRects, b.mRects);
+            }
+            return false;
+        }
+
+        @Override
+        public String toString() {
+            return "Bounds=" + Arrays.toString(mRects);
+        }
+
+    }
+
+    private final Bounds mBounds;
+
+    /**
+     * Creates a DisplayCutout instance.
+     *
+     * @param safeInsets the insets from each edge which avoid the display cutout as returned by
+     *                   {@link #getSafeInsetTop()} etc.
+     * @param boundLeft the left bounding rect of the display cutout in pixels. If null is passed,
+     *                  it's treated as an empty rectangle (0,0)-(0,0).
+     * @param boundTop the top bounding rect of the display cutout in pixels.  If null is passed,
+     *                  it's treated as an empty rectangle (0,0)-(0,0).
+     * @param boundRight the right bounding rect of the display cutout in pixels.  If null is
+     *                  passed, it's treated as an empty rectangle (0,0)-(0,0).
+     * @param boundBottom the bottom bounding rect of the display cutout in pixels.  If null is
+     *                   passed, it's treated as an empty rectangle (0,0)-(0,0).
+     */
+    // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
+    public DisplayCutout(@NonNull Insets safeInsets, @Nullable Rect boundLeft,
+            @Nullable Rect boundTop, @Nullable Rect boundRight, @Nullable Rect boundBottom) {
+        this(safeInsets.toRect(), boundLeft, boundTop, boundRight, boundBottom, true);
+    }
 
     /**
      * Creates a DisplayCutout instance.
@@ -103,25 +257,87 @@
      *                   {@link #getSafeInsetTop()} etc.
      * @param boundingRects the bounding rects of the display cutouts as returned by
      *               {@link #getBoundingRects()} ()}.
+     * @deprecated Use {@link DisplayCutout#DisplayCutout(Insets, Rect, Rect, Rect, Rect)} instead.
      */
     // TODO(b/73953958): @VisibleForTesting(visibility = PRIVATE)
-    public DisplayCutout(Rect safeInsets, List<Rect> boundingRects) {
-        this(safeInsets != null ? new Rect(safeInsets) : ZERO_RECT,
-                boundingRectsToRegion(boundingRects),
+    @Deprecated
+    public DisplayCutout(@Nullable Rect safeInsets, @Nullable List<Rect> boundingRects) {
+        this(safeInsets, extractBoundsFromList(safeInsets, boundingRects),
                 true /* copyArguments */);
     }
 
     /**
      * Creates a DisplayCutout instance.
      *
+     * @param safeInsets the insets from each edge which avoid the display cutout as returned by
+     *                   {@link #getSafeInsetTop()} etc.
      * @param copyArguments if true, create a copy of the arguments. If false, the passed arguments
      *                      are not copied and MUST remain unchanged forever.
      */
-    private DisplayCutout(Rect safeInsets, Region bounds, boolean copyArguments) {
-        mSafeInsets = safeInsets == null ? ZERO_RECT :
-                (copyArguments ? new Rect(safeInsets) : safeInsets);
-        mBounds = bounds == null ? Region.obtain() :
-                (copyArguments ? Region.obtain(bounds) : bounds);
+    private DisplayCutout(Rect safeInsets, Rect boundLeft, Rect boundTop, Rect boundRight,
+                         Rect boundBottom, boolean copyArguments) {
+        mSafeInsets = getCopyOrRef(safeInsets, copyArguments);
+        mBounds = new Bounds(boundLeft, boundTop, boundRight, boundBottom, copyArguments);
+    }
+
+    private DisplayCutout(Rect safeInsets, Rect[] bounds, boolean copyArguments) {
+        mSafeInsets = getCopyOrRef(safeInsets, copyArguments);
+        mBounds = new Bounds(bounds, copyArguments);
+    }
+
+    private DisplayCutout(Rect safeInsets, Bounds bounds) {
+        mSafeInsets = safeInsets;
+        mBounds = bounds;
+
+    }
+
+    private static Rect getCopyOrRef(Rect r, boolean copyArguments) {
+        if (r == null) {
+            return ZERO_RECT;
+        } else if (copyArguments) {
+            return new Rect(r);
+        } else {
+            return r;
+        }
+    }
+
+    /**
+     * Find the position of the bounding rect, and create an array of Rect whose index represents
+     * the position (= BoundsPosition).
+     *
+     * @hide
+     */
+    public static Rect[] extractBoundsFromList(Rect safeInsets, List<Rect> boundingRects) {
+        Rect[] sortedBounds = new Rect[BOUNDS_POSITION_LENGTH];
+        for (int i = 0; i < sortedBounds.length; ++i) {
+            sortedBounds[i] = ZERO_RECT;
+        }
+        if (safeInsets != null && boundingRects != null) {
+            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;
+                }
+            }
+        }
+        return sortedBounds;
+    }
+
+    /**
+     * Returns true if there is no cutout, i.e. the bounds are empty.
+     *
+     * @hide
+     */
+    public boolean isBoundsEmpty() {
+        return mBounds.isEmpty();
     }
 
     /**
@@ -134,15 +350,6 @@
         return mSafeInsets.equals(ZERO_RECT);
     }
 
-    /**
-     * Returns true if there is no cutout, i.e. the bounds are empty.
-     *
-     * @hide
-     */
-    public boolean isBoundsEmpty() {
-        return mBounds.isEmpty();
-    }
-
     /** Returns the inset from the top which avoids the display cutout in pixels. */
     public int getSafeInsetTop() {
         return mSafeInsets.top;
@@ -174,69 +381,90 @@
     }
 
     /**
-     * Returns the bounding region of the cutout.
-     *
-     * <p>
-     * <strong>Note:</strong> There may be more than one cutout, in which case the returned
-     * {@code Region} will be non-contiguous and its bounding rect will be meaningless without
-     * intersecting it first.
-     *
-     * Example:
-     * <pre>
-     *     // Getting the bounding rectangle of the top display cutout
-     *     Region bounds = displayCutout.getBounds();
-     *     bounds.op(0, 0, Integer.MAX_VALUE, displayCutout.getSafeInsetTop(), Region.Op.INTERSECT);
-     *     Rect topDisplayCutout = bounds.getBoundingRect();
-     * </pre>
-     *
-     * @return the bounding region of the cutout. Coordinates are relative
-     *         to the top-left corner of the content view and in pixel units.
-     * @hide
-     */
-    public Region getBounds() {
-        return Region.obtain(mBounds);
-    }
-
-    /**
      * Returns a list of {@code Rect}s, each of which is the bounding rectangle for a non-functional
      * area on the display.
      *
      * There will be at most one non-functional area per short edge of the device, and none on
      * the long edges.
      *
-     * @return a list of bounding {@code Rect}s, one for each display cutout area.
+     * @return a list of bounding {@code Rect}s, one for each display cutout area. No empty Rect is
+     * returned.
      */
+    @NonNull
     public List<Rect> getBoundingRects() {
         List<Rect> result = new ArrayList<>();
-        Region bounds = Region.obtain();
-        // top
-        bounds.set(mBounds);
-        bounds.op(0, 0, Integer.MAX_VALUE, getSafeInsetTop(), Region.Op.INTERSECT);
-        if (!bounds.isEmpty()) {
-            result.add(bounds.getBounds());
+        for (Rect bound : getBoundingRectsAll()) {
+            if (!bound.isEmpty()) {
+                result.add(new Rect(bound));
+            }
         }
-        // left
-        bounds.set(mBounds);
-        bounds.op(0, 0, getSafeInsetLeft(), Integer.MAX_VALUE, Region.Op.INTERSECT);
-        if (!bounds.isEmpty()) {
-            result.add(bounds.getBounds());
-        }
-        // right & bottom
-        bounds.set(mBounds);
-        bounds.op(getSafeInsetLeft() + 1, getSafeInsetTop() + 1,
-                Integer.MAX_VALUE, Integer.MAX_VALUE, Region.Op.INTERSECT);
-        if (!bounds.isEmpty()) {
-            result.add(bounds.getBounds());
-        }
-        bounds.recycle();
         return result;
     }
 
+    /**
+     * Returns an array of {@code Rect}s, each of which is the bounding rectangle for a non-
+     * functional area on the display. Ordinal value of BoundPosition is used as an index of
+     * the array.
+     *
+     * There will be at most one non-functional area per short edge of the device, and none on
+     * the long edges.
+     *
+     * @return an array of bounding {@code Rect}s, one for each display cutout area. This might
+     * contain ZERO_RECT, which means there is no cutout area at the position.
+     *
+     * @hide
+     */
+    public Rect[] getBoundingRectsAll() {
+        return mBounds.getRects();
+    }
+
+    /**
+     * Returns a bounding rectangle for a non-functional area on the display which is located on
+     * the left of the screen.
+     *
+     * @return bounding rectangle in pixels. In case of no bounding rectangle, an empty rectangle
+     * is returned.
+     */
+    public @NonNull Rect getBoundingRectLeft() {
+        return mBounds.getRect(BOUNDS_POSITION_LEFT);
+    }
+
+    /**
+     * Returns a bounding rectangle for a non-functional area on the display which is located on
+     * the top of the screen.
+     *
+     * @return bounding rectangle in pixels. In case of no bounding rectangle, an empty rectangle
+     * is returned.
+     */
+    public @NonNull Rect getBoundingRectTop() {
+        return mBounds.getRect(BOUNDS_POSITION_TOP);
+    }
+
+    /**
+     * Returns a bounding rectangle for a non-functional area on the display which is located on
+     * the right of the screen.
+     *
+     * @return bounding rectangle in pixels. In case of no bounding rectangle, an empty rectangle
+     * is returned.
+     */
+    public @NonNull Rect getBoundingRectRight() {
+        return mBounds.getRect(BOUNDS_POSITION_RIGHT);
+    }
+
+    /**
+     * Returns a bounding rectangle for a non-functional area on the display which is located on
+     * the bottom of the screen.
+     *
+     * @return bounding rectangle in pixels. In case of no bounding rectangle, an empty rectangle
+     * is returned.
+     */
+    public @NonNull Rect getBoundingRectBottom() {
+        return mBounds.getRect(BOUNDS_POSITION_BOTTOM);
+    }
+
     @Override
     public int hashCode() {
-        int result = mSafeInsets.hashCode();
-        result = result * 31 + mBounds.getBounds().hashCode();
-        return result;
+        return mSafeInsets.hashCode() * 48271 + mBounds.hashCode();
     }
 
     @Override
@@ -246,8 +474,7 @@
         }
         if (o instanceof DisplayCutout) {
             DisplayCutout c = (DisplayCutout) o;
-            return mSafeInsets.equals(c.mSafeInsets)
-                    && mBounds.equals(c.mBounds);
+            return mSafeInsets.equals(c.mSafeInsets) && mBounds.equals(c.mBounds);
         }
         return false;
     }
@@ -255,7 +482,7 @@
     @Override
     public String toString() {
         return "DisplayCutout{insets=" + mSafeInsets
-                + " boundingRect=" + mBounds.getBounds()
+                + " boundingRect={" + mBounds + "}"
                 + "}";
     }
 
@@ -265,7 +492,10 @@
     public void writeToProto(ProtoOutputStream proto, long fieldId) {
         final long token = proto.start(fieldId);
         mSafeInsets.writeToProto(proto, INSETS);
-        mBounds.getBounds().writeToProto(proto, BOUNDS);
+        mBounds.getRect(BOUNDS_POSITION_LEFT).writeToProto(proto, BOUND_LEFT);
+        mBounds.getRect(BOUNDS_POSITION_TOP).writeToProto(proto, BOUND_TOP);
+        mBounds.getRect(BOUNDS_POSITION_RIGHT).writeToProto(proto, BOUND_RIGHT);
+        mBounds.getRect(BOUNDS_POSITION_BOTTOM).writeToProto(proto, BOUND_BOTTOM);
         proto.end(token);
     }
 
@@ -276,13 +506,12 @@
      * @hide
      */
     public DisplayCutout inset(int insetLeft, int insetTop, int insetRight, int insetBottom) {
-        if (mBounds.isEmpty()
+        if (isBoundsEmpty()
                 || insetLeft == 0 && insetTop == 0 && insetRight == 0 && insetBottom == 0) {
             return this;
         }
 
         Rect safeInsets = new Rect(mSafeInsets);
-        Region bounds = Region.obtain(mBounds);
 
         // Note: it's not really well defined what happens when the inset is negative, because we
         // don't know if the safe inset needs to expand in general.
@@ -299,7 +528,13 @@
             safeInsets.right = atLeastZero(safeInsets.right - insetRight);
         }
 
-        bounds.translate(-insetLeft, -insetTop);
+        Rect[] bounds = mBounds.getRects();
+        for (int i = 0; i < bounds.length; ++i) {
+            if (!bounds[i].equals(ZERO_RECT)) {
+                bounds[i].offset(-insetLeft, -insetTop);
+            }
+        }
+
         return new DisplayCutout(safeInsets, bounds, false /* copyArguments */);
     }
 
@@ -312,7 +547,7 @@
      * @hide
      */
     public DisplayCutout replaceSafeInsets(Rect safeInsets) {
-        return new DisplayCutout(new Rect(safeInsets), mBounds, false /* copyArguments */);
+        return new DisplayCutout(new Rect(safeInsets), mBounds);
     }
 
     private static int atLeastZero(int value) {
@@ -326,10 +561,13 @@
      * @hide
      */
     @VisibleForTesting
-    public static DisplayCutout fromBoundingRect(int left, int top, int right, int bottom) {
-        Region r = Region.obtain();
-        r.set(left, top, right, bottom);
-        return fromBounds(r);
+    public static DisplayCutout fromBoundingRect(
+            int left, int top, int right, int bottom, @BoundsPosition int pos) {
+        Rect[] bounds = new Rect[BOUNDS_POSITION_LENGTH];
+        for (int i = 0; i < BOUNDS_POSITION_LENGTH; ++i) {
+            bounds[i] = (pos == i) ? new Rect(left, top, right, bottom) : new Rect();
+        }
+        return new DisplayCutout(ZERO_RECT, bounds, false /* copyArguments */);
     }
 
     /**
@@ -337,8 +575,8 @@
      *
      * @hide
      */
-    public static DisplayCutout fromBounds(Region region) {
-        return new DisplayCutout(ZERO_RECT, region, false /* copyArguments */);
+    public static DisplayCutout fromBounds(Rect[] bounds) {
+        return new DisplayCutout(ZERO_RECT, bounds, false /* copyArguments */);
     }
 
     /**
@@ -423,10 +661,11 @@
         m.postTranslate(offsetX, 0);
         p.transform(m);
 
-        final Rect tmpRect = new Rect();
-        toRectAndAddToRegion(p, r, tmpRect);
-        final int topInset = tmpRect.bottom;
+        Rect boundTop = new Rect();
+        toRectAndAddToRegion(p, r, boundTop);
+        final int topInset = boundTop.bottom;
 
+        Rect boundBottom = null;
         final int bottomInset;
         if (bottomSpec != null) {
             final Path bottomPath;
@@ -440,15 +679,17 @@
             m.postTranslate(0, displayHeight);
             bottomPath.transform(m);
             p.addPath(bottomPath);
-            toRectAndAddToRegion(bottomPath, r, tmpRect);
-            bottomInset = displayHeight - tmpRect.top;
+            boundBottom = new Rect();
+            toRectAndAddToRegion(bottomPath, r, boundBottom);
+            bottomInset = displayHeight - boundBottom.top;
         } else {
             bottomInset = 0;
         }
 
-        // Reuse tmpRect as the inset rect we store into the DisplayCutout instance.
-        tmpRect.set(0, topInset, 0, bottomInset);
-        final DisplayCutout cutout = new DisplayCutout(tmpRect, r, false /* copyArguments */);
+        Rect safeInset = new Rect(0, topInset, 0, bottomInset);
+        final DisplayCutout cutout = new DisplayCutout(
+                safeInset, null /* boundLeft */, boundTop, null /* boundRight */, boundBottom,
+                false /* copyArguments */);
 
         final Pair<Path, DisplayCutout> result = new Pair<>(p, cutout);
         synchronized (CACHE_LOCK) {
@@ -468,16 +709,6 @@
         inoutRegion.op(inoutRect, Op.UNION);
     }
 
-    private static Region boundingRectsToRegion(List<Rect> rects) {
-        Region result = Region.obtain();
-        if (rects != null) {
-            for (Rect r : rects) {
-                result.op(r, Region.Op.UNION);
-            }
-        }
-        return result;
-    }
-
     /**
      * Helper class for passing {@link DisplayCutout} through binder.
      *
@@ -520,7 +751,7 @@
             } else {
                 out.writeInt(1);
                 out.writeTypedObject(cutout.mSafeInsets, flags);
-                out.writeTypedObject(cutout.mBounds, flags);
+                out.writeTypedArray(cutout.mBounds.getRects(), flags);
             }
         }
 
@@ -561,7 +792,8 @@
             }
 
             Rect safeInsets = in.readTypedObject(Rect.CREATOR);
-            Region bounds = in.readTypedObject(Region.CREATOR);
+            Rect[] bounds = new Rect[BOUNDS_POSITION_LENGTH];
+            in.readTypedArray(bounds, Rect.CREATOR);
 
             return new DisplayCutout(safeInsets, bounds, false /* copyArguments */);
         }
diff --git a/core/java/android/view/GhostView.java b/core/java/android/view/GhostView.java
index fa7b067..98ed217 100644
--- a/core/java/android/view/GhostView.java
+++ b/core/java/android/view/GhostView.java
@@ -18,6 +18,8 @@
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.widget.FrameLayout;
 
 import java.util.ArrayList;
@@ -46,8 +48,8 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (canvas instanceof DisplayListCanvas) {
-            DisplayListCanvas dlCanvas = (DisplayListCanvas) canvas;
+        if (canvas instanceof RecordingCanvas) {
+            RecordingCanvas dlCanvas = (RecordingCanvas) canvas;
             mView.mRecreateDisplayList = true;
             RenderNode renderNode = mView.updateDisplayListIfDirty();
             if (renderNode.isValid()) {
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 3bab87a..0c3a295 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -87,7 +87,6 @@
     void setEventDispatching(boolean enabled);
     void addWindowToken(IBinder token, int type, int displayId);
     void removeWindowToken(IBinder token, int displayId);
-    void setFocusedApp(IBinder token, boolean moveFocusNow);
     void prepareAppTransition(int transit, boolean alwaysKeepCurrent);
     int getPendingAppTransition();
     void overridePendingAppTransition(String packageName, int enterAnim, int exitAnim,
@@ -227,27 +226,52 @@
     int getPreferredOptionsPanelGravity(int displayId);
 
     /**
-     * Lock the device orientation to the specified rotation, or to the
-     * current rotation if -1.  Sensor input will be ignored until
-     * thawRotation() is called.
-     * @hide
+     * Equivalent to calling {@link #freezeDisplayRotation(int, int)} with {@link
+     * android.view.Display#DEFAULT_DISPLAY} and given rotation.
      */
     void freezeRotation(int rotation);
 
     /**
-     * Release the orientation lock imposed by freezeRotation().
-     * @hide
+     * Equivalent to calling {@link #thawDisplayRotation(int)} with {@link
+     * android.view.Display#DEFAULT_DISPLAY}.
      */
     void thawRotation();
 
     /**
-     * Gets whether the rotation is frozen.
-     *
-     * @return Whether the rotation is frozen.
+     * Equivelant to call {@link #isDisplayRotationFrozen(int)} with {@link
+     * android.view.Display#DEFAULT_DISPLAY}.
      */
     boolean isRotationFrozen();
 
     /**
+     * Lock the display orientation to the specified rotation, or to the current
+     * rotation if -1. Sensor input will be ignored until thawRotation() is called.
+     *
+     * @param displayId the ID of display which rotation should be frozen.
+     * @param rotation one of {@link android.view.Surface#ROTATION_0},
+     *        {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
+     *        {@link android.view.Surface#ROTATION_270} or -1 to freeze it to current rotation.
+     * @hide
+     */
+    void freezeDisplayRotation(int displayId, int rotation);
+
+    /**
+     * Release the orientation lock imposed by freezeRotation() on the display.
+     *
+     * @param displayId the ID of display which rotation should be thawed.
+     * @hide
+     */
+    void thawDisplayRotation(int displayId);
+
+    /**
+     * Gets whether the rotation is frozen on the display.
+     *
+     * @param displayId the ID of display which frozen is needed.
+     * @return Whether the rotation is frozen.
+     */
+    boolean isDisplayRotationFrozen(int displayId);
+
+    /**
      * Screenshot the current wallpaper layer, including the whole screen.
      */
     Bitmap screenshotWallpaper();
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index c38fcf3..0a3403b 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -896,8 +896,8 @@
      * @deprecated No longer used by the input system.
      * {@link #getAction} value: multiple duplicate key events have
      * occurred in a row, or a complex string is being delivered.  If the
-     * key code is not {#link {@link #KEYCODE_UNKNOWN} then the
-     * {#link {@link #getRepeatCount()} method returns the number of times
+     * key code is not {@link #KEYCODE_UNKNOWN} then the
+     * {@link #getRepeatCount()} method returns the number of times
      * the given key code should be executed.
      * Otherwise, if the key code is {@link #KEYCODE_UNKNOWN}, then
      * this is a sequence of characters as returned by {@link #getCharacters}.
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 29c58dc..b59d8c7 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1776,6 +1776,47 @@
     static public MotionEvent obtain(long downTime, long eventTime, int action,
             float x, float y, float pressure, float size, int metaState,
             float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
+        return obtain(downTime, eventTime, action, x, y, pressure, size, metaState,
+                xPrecision, yPrecision, deviceId, edgeFlags, InputDevice.SOURCE_UNKNOWN,
+                DEFAULT_DISPLAY);
+    }
+
+    /**
+     * Create a new MotionEvent, filling in all of the basic values that
+     * define the motion.
+     *
+     * @param downTime The time (in ms) when the user originally pressed down to start
+     * a stream of position events.  This must be obtained from {@link SystemClock#uptimeMillis()}.
+     * @param eventTime  The the time (in ms) when this specific event was generated.  This
+     * must be obtained from {@link SystemClock#uptimeMillis()}.
+     * @param action The kind of action being performed, such as {@link #ACTION_DOWN}.
+     * @param x The X coordinate of this event.
+     * @param y The Y coordinate of this event.
+     * @param pressure The current pressure of this event.  The pressure generally
+     * ranges from 0 (no pressure at all) to 1 (normal pressure), however
+     * values higher than 1 may be generated depending on the calibration of
+     * the input device.
+     * @param size A scaled value of the approximate size of the area being pressed when
+     * touched with the finger. The actual value in pixels corresponding to the finger
+     * touch is normalized with a device specific range of values
+     * and scaled to a value between 0 and 1.
+     * @param metaState The state of any meta / modifier keys that were in effect when
+     * the event was generated.
+     * @param xPrecision The precision of the X coordinate being reported.
+     * @param yPrecision The precision of the Y coordinate being reported.
+     * @param deviceId The id for the device that this event came from.  An id of
+     * zero indicates that the event didn't come from a physical device; other
+     * numbers are arbitrary and you shouldn't depend on the values.
+     * @param source The source of this event.
+     * @param edgeFlags A bitfield indicating which edges, if any, were touched by this
+     * MotionEvent.
+     * @param displayId The display ID associated with this event.
+     * @hide
+     */
+    public static MotionEvent obtain(long downTime, long eventTime, int action,
+            float x, float y, float pressure, float size, int metaState,
+            float xPrecision, float yPrecision, int deviceId, int edgeFlags, int source,
+            int displayId) {
         MotionEvent ev = obtain();
         synchronized (gSharedTempLock) {
             ensureSharedTempPointerCapacity(1);
@@ -1791,7 +1832,7 @@
             pc[0].size = size;
 
             ev.mNativePtr = nativeInitialize(ev.mNativePtr,
-                    deviceId, InputDevice.SOURCE_UNKNOWN, DEFAULT_DISPLAY,
+                    deviceId, source, displayId,
                     action, 0, edgeFlags, metaState, 0,
                     0, 0, xPrecision, yPrecision,
                     downTime * NS_PER_MS, eventTime * NS_PER_MS,
diff --git a/core/java/android/view/RenderNodeAnimator.java b/core/java/android/view/RenderNodeAnimator.java
index e48bcfd..9d31bd1 100644
--- a/core/java/android/view/RenderNodeAnimator.java
+++ b/core/java/android/view/RenderNodeAnimator.java
@@ -22,6 +22,8 @@
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.CanvasProperty;
 import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 import android.util.SparseIntArray;
 
 import com.android.internal.util.VirtualRefBasePtr;
@@ -286,8 +288,8 @@
         setTarget(mViewTarget.mRenderNode);
     }
 
-    /** Sets the animation target to the owning view of the DisplayListCanvas */
-    public void setTarget(DisplayListCanvas canvas) {
+    /** Sets the animation target to the owning view of the RecordingCanvas */
+    public void setTarget(RecordingCanvas canvas) {
         setTarget(canvas.mNode);
     }
 
@@ -405,7 +407,7 @@
         return listeners;
     }
 
-    long getNativeAnimator() {
+    public long getNativeAnimator() {
         return mNativePtr.get();
     }
 
diff --git a/core/java/android/view/RenderNodeAnimatorSetHelper.java b/core/java/android/view/RenderNodeAnimatorSetHelper.java
index e1ef059..d222e07 100644
--- a/core/java/android/view/RenderNodeAnimatorSetHelper.java
+++ b/core/java/android/view/RenderNodeAnimatorSetHelper.java
@@ -16,6 +16,8 @@
 package android.view;
 
 import android.animation.TimeInterpolator;
+import android.graphics.RecordingCanvas;
+import android.graphics.RenderNode;
 
 import com.android.internal.view.animation.FallbackLUTInterpolator;
 import com.android.internal.view.animation.NativeInterpolatorFactory;
@@ -29,10 +31,12 @@
  */
 public class RenderNodeAnimatorSetHelper {
 
-    public static RenderNode getTarget(DisplayListCanvas recordingCanvas) {
+    /** checkstyle @hide */
+    public static RenderNode getTarget(RecordingCanvas recordingCanvas) {
         return recordingCanvas.mNode;
     }
 
+    /** checkstyle @hide */
     public static long createNativeInterpolator(TimeInterpolator interpolator, long
             duration) {
         if (interpolator == null) {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 6fb1bba..f3cb376 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -22,7 +22,9 @@
 import android.graphics.Canvas;
 import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.RenderNode;
 import android.graphics.SurfaceTexture;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -889,13 +891,13 @@
     private final class HwuiContext {
         private final RenderNode mRenderNode;
         private long mHwuiRenderer;
-        private DisplayListCanvas mCanvas;
+        private RecordingCanvas mCanvas;
         private final boolean mIsWideColorGamut;
 
         HwuiContext(boolean isWideColorGamut) {
             mRenderNode = RenderNode.create("HwuiCanvas", null);
             mRenderNode.setClipToBounds(false);
-            mRenderNode.setAllowForceDark(false);
+            mRenderNode.setForceDarkAllowed(false);
             mIsWideColorGamut = isWideColorGamut;
             mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject,
                     isWideColorGamut);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 7271a9e..0d33bbd 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -97,6 +97,8 @@
     private static native void nativeSetMatrix(long transactionObj, long nativeObject,
             float dsdx, float dtdx,
             float dtdy, float dsdy);
+    private static native void nativeSetColorTransform(long transactionObj, long nativeObject,
+            float[] matrix, float[] translation);
     private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color);
     private static native void nativeSetFlags(long transactionObj, long nativeObject,
             int flags, int mask);
@@ -945,6 +947,18 @@
         }
     }
 
+    /**
+     * Sets the color transform for the Surface.
+     * @param matrix A float array with 9 values represents a 3x3 transform matrix
+     * @param translation A float array with 3 values represents a translation vector
+     */
+    public void setColorTransform(@Size(9) float[] matrix, @Size(3) float[] translation) {
+        checkNotReleased();
+        synchronized (SurfaceControl.class) {
+            sGlobalTransaction.setColorTransform(this, matrix, translation);
+        }
+    }
+
     public void setWindowCrop(Rect crop) {
         checkNotReleased();
         synchronized (SurfaceControl.class) {
@@ -1438,6 +1452,18 @@
             return this;
         }
 
+        /**
+         * Sets the color transform for the Surface.
+         * @param matrix A float array with 9 values represents a 3x3 transform matrix
+         * @param translation A float array with 3 values represents a translation vector
+         */
+        public Transaction setColorTransform(SurfaceControl sc, @Size(9) float[] matrix,
+                @Size(3) float[] translation) {
+            sc.checkNotReleased();
+            nativeSetColorTransform(mNativeObject, sc.mNativeObject, matrix, translation);
+            return this;
+        }
+
         @UnsupportedAppUsage
         public Transaction setWindowCrop(SurfaceControl sc, Rect crop) {
             sc.checkNotReleased();
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index e71182c..67f9399 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -30,6 +30,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.graphics.RenderNode;
 import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
diff --git a/core/java/android/view/TextureLayer.java b/core/java/android/view/TextureLayer.java
index 35a886f..d89d634 100644
--- a/core/java/android/view/TextureLayer.java
+++ b/core/java/android/view/TextureLayer.java
@@ -31,7 +31,7 @@
  *
  * @hide
  */
-final class TextureLayer {
+public final class TextureLayer {
     private ThreadedRenderer mRenderer;
     private VirtualRefBasePtr mFinalizer;
 
diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java
index 997e48fe..0175ba2 100644
--- a/core/java/android/view/TextureView.java
+++ b/core/java/android/view/TextureView.java
@@ -23,6 +23,7 @@
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
 import android.graphics.drawable.Drawable;
@@ -343,7 +344,7 @@
         properties (alpha, layer paint) affect all of the content of a TextureView. */
 
         if (canvas.isHardwareAccelerated()) {
-            DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
+            RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
 
             TextureLayer layer = getTextureLayer();
             if (layer != null) {
@@ -351,7 +352,7 @@
                 applyTransformMatrix();
 
                 mLayer.setLayerPaint(mLayerPaint); // ensure layer paint is up to date
-                displayListCanvas.drawTextureLayer(layer);
+                recordingCanvas.drawTextureLayer(layer);
             }
         }
     }
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 42690ce..c1ab4d4 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -24,7 +24,9 @@
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Point;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.RenderNode;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
@@ -693,7 +695,7 @@
         updateViewTreeDisplayList(view);
 
         if (mRootNodeNeedsUpdate || !mRootNode.isValid()) {
-            DisplayListCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
+            RecordingCanvas canvas = mRootNode.start(mSurfaceWidth, mSurfaceHeight);
             try {
                 final int saveCount = canvas.save();
                 canvas.translate(mInsetLeft, mInsetTop);
@@ -770,7 +772,7 @@
          *
          * @param canvas The Canvas used to render the view.
          */
-        void onPreDraw(DisplayListCanvas canvas);
+        void onPreDraw(RecordingCanvas canvas);
 
         /**
          * Invoked after a view is drawn by a threaded renderer.
@@ -778,7 +780,7 @@
          *
          * @param canvas The Canvas used to render the view.
          */
-        void onPostDraw(DisplayListCanvas canvas);
+        void onPostDraw(RecordingCanvas canvas);
     }
 
     /**
diff --git a/core/java/android/view/TouchDelegate.java b/core/java/android/view/TouchDelegate.java
index b361ab4..6fb32e3 100644
--- a/core/java/android/view/TouchDelegate.java
+++ b/core/java/android/view/TouchDelegate.java
@@ -16,8 +16,12 @@
 
 package android.view;
 
+import android.annotation.NonNull;
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Rect;
+import android.graphics.Region;
+import android.util.ArrayMap;
+import android.view.accessibility.AccessibilityNodeInfo.TouchDelegateInfo;
 
 /**
  * Helper class to handle situations where you want a view to have a larger touch area than its
@@ -78,6 +82,11 @@
     private int mSlop;
 
     /**
+     * Touch delegate information for accessibility
+     */
+    private TouchDelegateInfo mTouchDelegateInfo;
+
+    /**
      * Constructor
      *
      * @param bounds Bounds in local coordinates of the containing view that should be mapped to
@@ -145,4 +154,24 @@
         }
         return handled;
     }
+
+    /**
+     * Return a {@link TouchDelegateInfo} mapping from regions (in view coordinates) to
+     * delegated views for accessibility usage.
+     *
+     * @return A TouchDelegateInfo.
+     */
+    @NonNull
+    public TouchDelegateInfo getTouchDelegateInfo() {
+        if (mTouchDelegateInfo == null) {
+            final ArrayMap<Region, View> targetMap = new ArrayMap<>(1);
+            Rect bounds = mBounds;
+            if (bounds == null) {
+                bounds = new Rect();
+            }
+            targetMap.put(new Region(bounds), mDelegateView);
+            mTouchDelegateInfo = new TouchDelegateInfo(targetMap);
+        }
+        return mTouchDelegateInfo;
+    }
 }
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b2944d6..1157b28 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -57,9 +57,11 @@
 import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Region;
+import android.graphics.RenderNode;
 import android.graphics.Shader;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -5540,6 +5542,10 @@
                     break;
                 case com.android.internal.R.styleable.View_accessibilityHeading:
                     setAccessibilityHeading(a.getBoolean(attr, false));
+                    break;
+                case R.styleable.View_forceDarkAllowed:
+                    mRenderNode.setForceDarkAllowed(a.getBoolean(attr, true));
+                    break;
             }
         }
 
@@ -7315,17 +7321,16 @@
         // Here we check whether we still need the default focus highlight, and switch it on/off.
         switchDefaultFocusHighlight();
 
-        InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
         if (!gainFocus) {
             if (isPressed()) {
                 setPressed(false);
             }
-            if (imm != null && mAttachInfo != null && mAttachInfo.mHasWindowFocus) {
-                imm.focusOut(this);
+            if (mAttachInfo != null && mAttachInfo.mHasWindowFocus) {
+                notifyFocusChangeToInputMethodManager(false /* hasFocus */);
             }
             onFocusLost();
-        } else if (imm != null && mAttachInfo != null && mAttachInfo.mHasWindowFocus) {
-            imm.focusIn(this);
+        } else if (mAttachInfo != null && mAttachInfo.mHasWindowFocus) {
+            notifyFocusChangeToInputMethodManager(true /* hasFocus */);
         }
 
         invalidate(true);
@@ -7341,6 +7346,26 @@
         notifyEnterOrExitForAutoFillIfNeeded(gainFocus);
     }
 
+    /**
+     * Notify {@link InputMethodManager} about the focus change of the {@link View}.
+     *
+     * <p>Does nothing when {@link InputMethodManager} is not available.</p>
+     *
+     * @param hasFocus {@code true} when the {@link View} is being focused.
+     */
+    private void notifyFocusChangeToInputMethodManager(boolean hasFocus) {
+        final InputMethodManager imm =
+                getContext().getSystemService(InputMethodManager.class);
+        if (imm == null) {
+            return;
+        }
+        if (hasFocus) {
+            imm.focusIn(this);
+        } else {
+            imm.focusOut(this);
+        }
+    }
+
     /** @hide */
     public void notifyEnterOrExitForAutoFillIfNeeded(boolean enter) {
         if (canNotifyAutofillEnterExitEvent()) {
@@ -8881,6 +8906,10 @@
         populateAccessibilityNodeInfoDrawingOrderInParent(info);
         info.setPaneTitle(mAccessibilityPaneTitle);
         info.setHeading(isAccessibilityHeading());
+
+        if (mTouchDelegate != null) {
+            info.setTouchDelegateInfo(mTouchDelegate.getTouchDelegateInfo());
+        }
     }
 
     /**
@@ -12481,7 +12510,7 @@
         mPrivateFlags3 &= ~PFLAG3_TEMPORARY_DETACH;
         onFinishTemporaryDetach();
         if (hasWindowFocus() && hasFocus()) {
-            getContext().getSystemService(InputMethodManager.class).focusIn(this);
+            notifyFocusChangeToInputMethodManager(true /* hasFocus */);
         }
         notifyEnterOrExitForAutoFillIfNeeded(true);
     }
@@ -12872,20 +12901,19 @@
      *        focus, false otherwise.
      */
     public void onWindowFocusChanged(boolean hasWindowFocus) {
-        InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
         if (!hasWindowFocus) {
             if (isPressed()) {
                 setPressed(false);
             }
             mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
-            if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
-                imm.focusOut(this);
+            if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
+                notifyFocusChangeToInputMethodManager(false /* hasFocus */);
             }
             removeLongPressCallback();
             removeTapCallback();
             onFocusLost();
-        } else if (imm != null && (mPrivateFlags & PFLAG_FOCUSED) != 0) {
-            imm.focusIn(this);
+        } else if ((mPrivateFlags & PFLAG_FOCUSED) != 0) {
+            notifyFocusChangeToInputMethodManager(true /* hasFocus */);
         }
 
         refreshDrawableState();
@@ -14255,9 +14283,10 @@
             }
 
             if (mParent instanceof ViewGroup) {
-                ((ViewGroup) mParent).onChildVisibilityChanged(this,
-                        (changed & VISIBILITY_MASK), newVisibility);
-                ((View) mParent).invalidate(true);
+                ViewGroup parent = (ViewGroup) mParent;
+                parent.onChildVisibilityChanged(this, (changed & VISIBILITY_MASK),
+                        newVisibility);
+                parent.invalidate(true);
             } else if (mParent != null) {
                 mParent.invalidateChild(this, null);
             }
@@ -14639,9 +14668,10 @@
      * Recomputes the matrix if necessary.
      *
      * @return True if the transform matrix is the identity matrix, false otherwise.
+     * @hide
      */
     @UnsupportedAppUsage
-    final boolean hasIdentityMatrix() {
+    public final boolean hasIdentityMatrix() {
         return mRenderNode.hasIdentityMatrix();
     }
 
@@ -15260,11 +15290,9 @@
      * If a theme is isLightTheme="false", then force dark is globally disabled for that theme.
      *
      * @param allow Whether or not to allow force dark.
-     *
-     * @hide
      */
-    public void setAllowForceDark(boolean allow) {
-        if (mRenderNode.setAllowForceDark(allow)) {
+    public void setForceDarkAllowed(boolean allow) {
+        if (mRenderNode.setForceDarkAllowed(allow)) {
             // Currently toggling force-dark requires a new display list push to apply
             // TODO: Make it not clobber the display list so this is just a damageSelf() instead
             invalidate();
@@ -15272,15 +15300,13 @@
     }
 
     /**
-     * See {@link #setAllowForceDark(boolean)}
+     * See {@link #setForceDarkAllowed(boolean)}
      *
      * @return true if force dark is allowed (default), false if it is disabled
-     *
-     * @hide
      */
     @ViewDebug.ExportedProperty(category = "drawing")
-    public boolean getAllowForceDark() {
-        return mRenderNode.getAllowForceDark();
+    public boolean isForceDarkAllowed() {
+        return mRenderNode.isForceDarkAllowed();
     }
 
     /**
@@ -17975,10 +18001,7 @@
         rebuildOutline();
 
         if (isFocused()) {
-            InputMethodManager imm = getContext().getSystemService(InputMethodManager.class);
-            if (imm != null) {
-                imm.focusIn(this);
-            }
+            notifyFocusChangeToInputMethodManager(true /* hasFocus */);
         }
     }
 
@@ -19212,7 +19235,7 @@
             int height = mBottom - mTop;
             int layerType = getLayerType();
 
-            final DisplayListCanvas canvas = renderNode.start(width, height);
+            final RecordingCanvas canvas = renderNode.start(width, height);
 
             try {
                 if (layerType == LAYER_TYPE_SOFTWARE) {
@@ -20229,7 +20252,7 @@
         if (!drawingWithDrawingCache) {
             if (drawingWithRenderNode) {
                 mPrivateFlags &= ~PFLAG_DIRTY_MASK;
-                ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
+                ((RecordingCanvas) canvas).drawRenderNode(renderNode);
             } else {
                 // Fast path for layouts with no backgrounds
                 if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
@@ -20560,7 +20583,7 @@
             final RenderNode renderNode = mBackgroundRenderNode;
             if (renderNode != null && renderNode.isValid()) {
                 setBackgroundRenderNodeProperties(renderNode);
-                ((DisplayListCanvas) canvas).drawRenderNode(renderNode);
+                ((RecordingCanvas) canvas).drawRenderNode(renderNode);
                 return;
             }
         }
@@ -20612,7 +20635,7 @@
         final Rect bounds = drawable.getBounds();
         final int width = bounds.width();
         final int height = bounds.height();
-        final DisplayListCanvas canvas = renderNode.start(width, height);
+        final RecordingCanvas canvas = renderNode.start(width, height);
 
         // Reverse left/top translation done by drawable canvas, which will
         // instead be applied by rendernode's LTRB bounds below. This way, the
@@ -24171,7 +24194,7 @@
      *     </ul>
      * @return {@code true} if the method completes successfully, or
      * {@code false} if it fails anywhere. Returning {@code false} means the system was unable to
-     * do a drag, and so no drag operation is in progress.
+     * do a drag because of another ongoing operation or some other reasons.
      */
     public final boolean startDragAndDrop(ClipData data, DragShadowBuilder shadowBuilder,
             Object myLocalState, int flags) {
@@ -24214,51 +24237,51 @@
             Log.d(VIEW_LOG_TAG, "drag shadow: width=" + shadowSize.x + " height=" + shadowSize.y
                     + " shadowX=" + shadowTouchPoint.x + " shadowY=" + shadowTouchPoint.y);
         }
-        if (mAttachInfo.mDragSurface != null) {
-            mAttachInfo.mDragSurface.release();
-        }
-        mAttachInfo.mDragSurface = new Surface();
-        mAttachInfo.mDragToken = null;
 
         final ViewRootImpl root = mAttachInfo.mViewRootImpl;
         final SurfaceSession session = new SurfaceSession(root.mSurface);
-        final SurfaceControl surface = new SurfaceControl.Builder(session)
+        final SurfaceControl surfaceControl = new SurfaceControl.Builder(session)
                 .setName("drag surface")
                 .setSize(shadowSize.x, shadowSize.y)
                 .setFormat(PixelFormat.TRANSLUCENT)
                 .build();
+        final Surface surface = new Surface();
+        surface.copyFrom(surfaceControl);
+        IBinder token = null;
         try {
-            mAttachInfo.mDragSurface.copyFrom(surface);
-            final Canvas canvas = mAttachInfo.mDragSurface.lockCanvas(null);
+            final Canvas canvas = surface.lockCanvas(null);
             try {
                 canvas.drawColor(0, PorterDuff.Mode.CLEAR);
                 shadowBuilder.onDrawShadow(canvas);
             } finally {
-                mAttachInfo.mDragSurface.unlockCanvasAndPost(canvas);
+                surface.unlockCanvasAndPost(canvas);
             }
 
-            // Cache the local state object for delivery with DragEvents
-            root.setLocalDragState(myLocalState);
-
             // repurpose 'shadowSize' for the last touch point
             root.getLastTouchPoint(shadowSize);
 
-            mAttachInfo.mDragToken = mAttachInfo.mSession.performDrag(
-                    mAttachInfo.mWindow, flags, surface, root.getLastTouchSource(),
+            token = mAttachInfo.mSession.performDrag(
+                    mAttachInfo.mWindow, flags, surfaceControl, root.getLastTouchSource(),
                     shadowSize.x, shadowSize.y, shadowTouchPoint.x, shadowTouchPoint.y, data);
             if (ViewDebug.DEBUG_DRAG) {
-                Log.d(VIEW_LOG_TAG, "performDrag returned " + mAttachInfo.mDragToken);
+                Log.d(VIEW_LOG_TAG, "performDrag returned " + token);
             }
-
-            return mAttachInfo.mDragToken != null;
+            if (token != null) {
+                if (mAttachInfo.mDragSurface != null) {
+                    mAttachInfo.mDragSurface.release();
+                }
+                mAttachInfo.mDragSurface = surface;
+                mAttachInfo.mDragToken = token;
+                // Cache the local state object for delivery with DragEvents
+                root.setLocalDragState(myLocalState);
+            }
+            return token != null;
         } catch (Exception e) {
             Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
             return false;
         } finally {
-            if (mAttachInfo.mDragToken == null) {
-                mAttachInfo.mDragSurface.destroy();
-                mAttachInfo.mDragSurface = null;
-                root.setLocalDragState(null);
+            if (token == null) {
+                surface.destroy();
             }
             session.kill();
         }
diff --git a/core/java/android/view/ViewAnimationHostBridge.java b/core/java/android/view/ViewAnimationHostBridge.java
index 58f555d..e0fae21 100644
--- a/core/java/android/view/ViewAnimationHostBridge.java
+++ b/core/java/android/view/ViewAnimationHostBridge.java
@@ -16,6 +16,8 @@
 
 package android.view;
 
+import android.graphics.RenderNode;
+
 /**
  * Maps a View to a RenderNode's AnimationHost
  *
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 8dd0347..292e933 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -23,7 +23,9 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Picture;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.RenderNode;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.RemoteException;
@@ -601,7 +603,7 @@
         }
 
         if (view.isHardwareAccelerated()) {
-            DisplayListCanvas canvas = node.start(dm.widthPixels, dm.heightPixels);
+            RecordingCanvas canvas = node.start(dm.widthPixels, dm.heightPixels);
             try {
                 return profileViewOperation(view, () -> view.draw(canvas));
             } finally {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 1b3e62d..58febb05 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -541,11 +541,11 @@
     private static final int CHILD_TOP_INDEX = 1;
 
     // Child views of this ViewGroup
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private View[] mChildren;
     // Number of valid children in the mChildren array, the rest should be null or not
     // considered as children
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
     private int mChildrenCount;
 
     // Whether layout calls are currently being suppressed, controlled by calls to
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index e3e2069..a0ab362 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
+import android.graphics.RenderNode;
 
 import java.util.ArrayList;
 import java.util.HashMap;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bef8e8f..170c783 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -51,8 +51,10 @@
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.PorterDuff;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.graphics.RenderNode;
 import android.graphics.drawable.Drawable;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
@@ -1094,15 +1096,21 @@
     private void updateForceDarkMode() {
         if (mAttachInfo.mThreadedRenderer == null) return;
 
-        boolean nightMode = getNightMode() == Configuration.UI_MODE_NIGHT_YES;
-        TypedArray a = mContext.obtainStyledAttributes(R.styleable.Theme);
-        boolean isLightTheme = a.getBoolean(R.styleable.Theme_isLightTheme, false);
-        a.recycle();
+        boolean useAutoDark = getNightMode() == Configuration.UI_MODE_NIGHT_YES;
 
-        boolean changed = mAttachInfo.mThreadedRenderer.setForceDark(nightMode);
-        changed |= mAttachInfo.mThreadedRenderer.getRootNode().setAllowForceDark(isLightTheme);
+        // Allow debug.hwui.force_dark to override the target SDK check
+        if (useAutoDark && !SystemProperties.getBoolean("debug.hwui.force_dark", false)) {
+            useAutoDark = mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.Q;
+        }
 
-        if (changed) {
+        if (useAutoDark) {
+            TypedArray a = mContext.obtainStyledAttributes(R.styleable.Theme);
+            useAutoDark = a.getBoolean(R.styleable.Theme_isLightTheme, true)
+                    && a.getBoolean(R.styleable.Theme_forceDarkAllowed, true);
+            a.recycle();
+        }
+
+        if (mAttachInfo.mThreadedRenderer.setForceDark(useAutoDark)) {
             // TODO: Don't require regenerating all display lists to apply this setting
             invalidateWorld(mView);
         }
@@ -3120,7 +3128,7 @@
     int mHardwareYOffset;
 
     @Override
-    public void onPreDraw(DisplayListCanvas canvas) {
+    public void onPreDraw(RecordingCanvas canvas) {
         // If mCurScrollY is not 0 then this influences the hardwareYOffset. The end result is we
         // can apply offsets that are not handled by anything else, resulting in underdraw as
         // the View is shifted (thus shifting the window background) exposing unpainted
@@ -3134,7 +3142,7 @@
     }
 
     @Override
-    public void onPostDraw(DisplayListCanvas canvas) {
+    public void onPostDraw(RecordingCanvas canvas) {
         drawAccessibilityFocusedDrawableIfNeeded(canvas);
         if (mUseMTRenderer) {
             for (int i = mWindowCallbacks.size() - 1; i >= 0; i--) {
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 982737a..c1e94d8 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1085,6 +1085,19 @@
      *
      * <p>Refer to the individual flags for the permissions needed.
      *
+     * @param flags The flag bits to add.
+     *
+     * @hide
+     */
+    public void addPrivateFlags(int flags) {
+        setPrivateFlags(flags, flags);
+    }
+
+    /**
+     * Add system flag bits.
+     *
+     * <p>Refer to the individual flags for the permissions needed.
+     *
      * <p>Note: Only for updateable system components (aka. mainline modules)
      *
      * @param flags The flag bits to add.
@@ -1092,8 +1105,8 @@
      * @hide
      */
     @SystemApi
-    public void addPrivateFlags(int flags) {
-        setPrivateFlags(flags, flags);
+    public void addSystemFlags(@WindowManager.LayoutParams.SystemFlags int flags) {
+        addPrivateFlags(flags);
     }
 
     /**
diff --git a/core/java/android/view/WindowCallbacks.java b/core/java/android/view/WindowCallbacks.java
index b2dc1e9..a997302 100644
--- a/core/java/android/view/WindowCallbacks.java
+++ b/core/java/android/view/WindowCallbacks.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 
 /**
@@ -82,5 +83,5 @@
      *
      * @param canvas The canvas to draw on.
      */
-    void onPostDraw(DisplayListCanvas canvas);
+    void onPostDraw(RecordingCanvas canvas);
 }
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 742df5e8..2d77cb4 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1670,7 +1670,7 @@
          */
         @SystemApi
         @RequiresPermission(permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS)
-        public static final int PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 0x00080000;
+        public static final int SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 0x00080000;
 
         /**
          * Indicates that this window is the rounded corners overlay present on some
@@ -1708,6 +1708,18 @@
         public static final int PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION = 0x00800000;
 
         /**
+         * An internal annotation for flags that can be specified to {@link #softInputMode}.
+         *
+         * @hide
+         */
+        @SystemApi
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, prefix = { "SYSTEM_FLAG_" }, value = {
+                SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
+        })
+        public @interface SystemFlags {}
+
+        /**
          * Control flags that are private to the platform.
          * @hide
          */
@@ -1781,8 +1793,8 @@
                         equals = PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE,
                         name = "SUSTAINED_PERFORMANCE_MODE"),
                 @ViewDebug.FlagToString(
-                        mask = PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
-                        equals = PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
+                        mask = SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
+                        equals = SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS,
                         name = "HIDE_NON_SYSTEM_OVERLAY_WINDOWS"),
                 @ViewDebug.FlagToString(
                         mask = PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY,
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 4d3f0fc..e129091 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -23,10 +23,12 @@
 
 import android.accessibilityservice.AccessibilityService;
 import android.accessibilityservice.AccessibilityServiceInfo;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.graphics.Rect;
+import android.graphics.Region;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -39,17 +41,21 @@
 import android.text.style.AccessibilityURLSpan;
 import android.text.style.ClickableSpan;
 import android.text.style.URLSpan;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.LongArray;
 import android.util.Pools.SynchronizedPool;
+import android.view.TouchDelegate;
 import android.view.View;
 
 import com.android.internal.R;
 import com.android.internal.util.CollectionUtils;
+import com.android.internal.util.Preconditions;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -748,6 +754,8 @@
     private CollectionInfo mCollectionInfo;
     private CollectionItemInfo mCollectionItemInfo;
 
+    private TouchDelegateInfo mTouchDelegateInfo;
+
     /**
      * Hide constructor from clients.
      */
@@ -810,7 +818,7 @@
     public AccessibilityNodeInfo findFocus(int focus) {
         enforceSealed();
         enforceValidFocusType(focus);
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return null;
         }
         return AccessibilityInteractionClient.getInstance().findFocus(mConnectionId, mWindowId,
@@ -834,7 +842,7 @@
     public AccessibilityNodeInfo focusSearch(int direction) {
         enforceSealed();
         enforceValidFocusDirection(direction);
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return null;
         }
         return AccessibilityInteractionClient.getInstance().focusSearch(mConnectionId, mWindowId,
@@ -866,7 +874,7 @@
     @UnsupportedAppUsage
     public boolean refresh(Bundle arguments, boolean bypassCache) {
         enforceSealed();
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return false;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
@@ -967,7 +975,7 @@
         if (mChildNodeIds == null) {
             return null;
         }
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return null;
         }
         final long childId = mChildNodeIds.get(index);
@@ -1271,7 +1279,7 @@
      */
     public AccessibilityNodeInfo getTraversalBefore() {
         enforceSealed();
-        return getNodeForAccessibilityId(mTraversalBefore);
+        return getNodeForAccessibilityId(mConnectionId, mWindowId, mTraversalBefore);
     }
 
     /**
@@ -1332,7 +1340,7 @@
      */
     public AccessibilityNodeInfo getTraversalAfter() {
         enforceSealed();
-        return getNodeForAccessibilityId(mTraversalAfter);
+        return getNodeForAccessibilityId(mConnectionId, mWindowId, mTraversalAfter);
     }
 
     /**
@@ -1489,7 +1497,7 @@
      */
     public boolean performAction(int action) {
         enforceSealed();
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return false;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
@@ -1512,7 +1520,7 @@
      */
     public boolean performAction(int action, Bundle arguments) {
         enforceSealed();
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return false;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
@@ -1536,7 +1544,7 @@
      */
     public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByText(String text) {
         enforceSealed();
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return Collections.emptyList();
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
@@ -1567,7 +1575,7 @@
      */
     public List<AccessibilityNodeInfo> findAccessibilityNodeInfosByViewId(String viewId) {
         enforceSealed();
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return Collections.emptyList();
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
@@ -1584,7 +1592,7 @@
      */
     public AccessibilityWindowInfo getWindow() {
         enforceSealed();
-        if (!canPerformRequestOverConnection(mSourceNodeId)) {
+        if (!canPerformRequestOverConnection(mConnectionId, mWindowId, mSourceNodeId)) {
             return null;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
@@ -1603,7 +1611,7 @@
      */
     public AccessibilityNodeInfo getParent() {
         enforceSealed();
-        return getNodeForAccessibilityId(mParentNodeId);
+        return getNodeForAccessibilityId(mConnectionId, mWindowId, mParentNodeId);
     }
 
     /**
@@ -2783,7 +2791,7 @@
      */
     public AccessibilityNodeInfo getLabelFor() {
         enforceSealed();
-        return getNodeForAccessibilityId(mLabelForId);
+        return getNodeForAccessibilityId(mConnectionId, mWindowId, mLabelForId);
     }
 
     /**
@@ -2835,7 +2843,7 @@
      */
     public AccessibilityNodeInfo getLabeledBy() {
         enforceSealed();
-        return getNodeForAccessibilityId(mLabeledById);
+        return getNodeForAccessibilityId(mConnectionId, mWindowId, mLabeledById);
     }
 
     /**
@@ -2975,6 +2983,43 @@
     }
 
     /**
+     * Get the {@link TouchDelegateInfo} for touch delegate behavior with the represented view.
+     * It is possible for the same node to be pointed to by several regions. Use
+     * {@link TouchDelegateInfo#getRegionAt(int)} to get touch delegate target {@link Region}, and
+     * {@link TouchDelegateInfo#getTargetForRegion(Region)} for {@link AccessibilityNodeInfo} from
+     * the given region.
+     *
+     * @return {@link TouchDelegateInfo} or {@code null} if there are no touch delegates.
+     */
+    @Nullable
+    public TouchDelegateInfo getTouchDelegateInfo() {
+        if (mTouchDelegateInfo != null) {
+            mTouchDelegateInfo.setConnectionId(mConnectionId);
+            mTouchDelegateInfo.setWindowId(mWindowId);
+        }
+        return mTouchDelegateInfo;
+    }
+
+    /**
+     * Set touch delegate info if the represented view has a {@link TouchDelegate}.
+     * <p>
+     *   <strong>Note:</strong> Cannot be called from an
+     *   {@link android.accessibilityservice.AccessibilityService}.
+     *   This class is made immutable before being delivered to an
+     *   AccessibilityService.
+     * </p>
+     *
+     * @param delegatedInfo {@link TouchDelegateInfo} returned from
+     *         {@link TouchDelegate#getTouchDelegateInfo()}.
+     *
+     * @throws IllegalStateException If called from an AccessibilityService.
+     */
+    public void setTouchDelegateInfo(@NonNull TouchDelegateInfo delegatedInfo) {
+        enforceNotSealed();
+        mTouchDelegateInfo = delegatedInfo;
+    }
+
+    /**
      * Gets the value of a boolean property.
      *
      * @param property The property.
@@ -3340,6 +3385,10 @@
         if (!Objects.equals(mCollectionItemInfo, DEFAULT.mCollectionItemInfo)) {
             nonDefaultFields |= bitAt(fieldIndex);
         }
+        fieldIndex++;
+        if (!Objects.equals(mTouchDelegateInfo, DEFAULT.mTouchDelegateInfo)) {
+            nonDefaultFields |= bitAt(fieldIndex);
+        }
         int totalFields = fieldIndex;
         parcel.writeLong(nonDefaultFields);
 
@@ -3462,6 +3511,10 @@
             parcel.writeInt(mCollectionItemInfo.isSelected() ? 1 : 0);
         }
 
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mTouchDelegateInfo.writeToParcel(parcel, flags);
+        }
+
         if (DEBUG) {
             fieldIndex--;
             if (totalFields != fieldIndex) {
@@ -3543,6 +3596,10 @@
         if (mCollectionItemInfo != null) mCollectionItemInfo.recycle();
         mCollectionItemInfo =  (other.mCollectionItemInfo != null)
                 ? CollectionItemInfo.obtain(other.mCollectionItemInfo) : null;
+
+        final TouchDelegateInfo otherInfo = other.mTouchDelegateInfo;
+        mTouchDelegateInfo = (otherInfo != null)
+                ? new TouchDelegateInfo(otherInfo.mTargetMap, true) : null;
     }
 
     /**
@@ -3665,6 +3722,10 @@
                         parcel.readInt() == 1)
                 : null;
 
+        if (isBitSet(nonDefaultFields, fieldIndex++)) {
+            mTouchDelegateInfo = TouchDelegateInfo.CREATOR.createFromParcel(parcel);
+        }
+
         mSealed = sealed;
     }
 
@@ -3813,10 +3874,11 @@
         }
     }
 
-    private boolean canPerformRequestOverConnection(long accessibilityNodeId) {
-        return ((mWindowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID)
+    private static boolean canPerformRequestOverConnection(int connectionId,
+            int windowId, long accessibilityNodeId) {
+        return ((windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID)
                 && (getAccessibilityViewId(accessibilityNodeId) != UNDEFINED_ITEM_ID)
-                && (mConnectionId != UNDEFINED_CONNECTION_ID));
+                && (connectionId != UNDEFINED_CONNECTION_ID));
     }
 
     @Override
@@ -3919,13 +3981,14 @@
         return builder.toString();
     }
 
-    private AccessibilityNodeInfo getNodeForAccessibilityId(long accessibilityId) {
-        if (!canPerformRequestOverConnection(accessibilityId)) {
+    private static AccessibilityNodeInfo getNodeForAccessibilityId(int connectionId,
+            int windowId, long accessibilityId) {
+        if (!canPerformRequestOverConnection(connectionId, windowId, accessibilityId)) {
             return null;
         }
         AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
-        return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId,
-                mWindowId, accessibilityId, false, FLAG_PREFETCH_PREDECESSORS
+        return client.findAccessibilityNodeInfoByAccessibilityId(connectionId,
+                windowId, accessibilityId, false, FLAG_PREFETCH_PREDECESSORS
                         | FLAG_PREFETCH_DESCENDANTS | FLAG_PREFETCH_SIBLINGS, null);
     }
 
@@ -4896,6 +4959,176 @@
     }
 
     /**
+     * Class with information of touch delegated views and regions from {@link TouchDelegate} for
+     * the {@link AccessibilityNodeInfo}.
+     *
+     * @see AccessibilityNodeInfo#setTouchDelegateInfo(TouchDelegateInfo)
+     */
+    public static final class TouchDelegateInfo implements Parcelable {
+        private ArrayMap<Region, Long> mTargetMap;
+        // Two ids are initialized lazily in AccessibilityNodeInfo#getTouchDelegateInfo
+        private int mConnectionId;
+        private int mWindowId;
+
+        /**
+         * Create a new instance of {@link TouchDelegateInfo}.
+         *
+         * @param targetMap A map from regions (in view coordinates) to delegated views.
+         * @throws IllegalArgumentException if targetMap is empty or {@code null} in
+         * Regions or Views.
+         */
+        public TouchDelegateInfo(@NonNull Map<Region, View> targetMap) {
+            Preconditions.checkArgument(!targetMap.isEmpty()
+                    && !targetMap.containsKey(null) && !targetMap.containsValue(null));
+            mTargetMap = new ArrayMap<>(targetMap.size());
+            for (final Region region : targetMap.keySet()) {
+                final View view = targetMap.get(region);
+                mTargetMap.put(region, (long) view.getAccessibilityViewId());
+            }
+        }
+
+        /**
+         * Create a new instance from target map.
+         *
+         * @param targetMap A map from regions (in view coordinates) to delegated views'
+         *                  accessibility id.
+         * @param doCopy True if shallow copy targetMap.
+         * @throws IllegalArgumentException if targetMap is empty or {@code null} in
+         * Regions or Views.
+         */
+        TouchDelegateInfo(@NonNull ArrayMap<Region, Long> targetMap, boolean doCopy) {
+            Preconditions.checkArgument(!targetMap.isEmpty()
+                    && !targetMap.containsKey(null) && !targetMap.containsValue(null));
+            if (doCopy) {
+                mTargetMap = new ArrayMap<>(targetMap.size());
+                mTargetMap.putAll(targetMap);
+            } else {
+                mTargetMap = targetMap;
+            }
+        }
+
+        /**
+         * Set the connection ID.
+         *
+         * @param connectionId The connection id.
+         */
+        private void setConnectionId(int connectionId) {
+            mConnectionId = connectionId;
+        }
+
+        /**
+         * Set the window ID.
+         *
+         * @param windowId The window id.
+         */
+        private void setWindowId(int windowId) {
+            mWindowId = windowId;
+        }
+
+        /**
+         * Returns the number of touch delegate target region.
+         *
+         * @return Number of touch delegate target region.
+         */
+        public int getRegionCount() {
+            return mTargetMap.size();
+        }
+
+        /**
+         * Return the {@link Region} at the given index in the {@link TouchDelegateInfo}.
+         *
+         * @param index The desired index, must be between 0 and {@link #getRegionCount()}-1.
+         * @return Returns the {@link Region} stored at the given index.
+         */
+        @NonNull
+        public Region getRegionAt(int index) {
+            return mTargetMap.keyAt(index);
+        }
+
+        /**
+         * Return the target {@link AccessibilityNodeInfo} for the given {@link Region}.
+         * <p>
+         *   <strong>Note:</strong> This api can only be called from {@link AccessibilityService}.
+         * </p>
+         * <p>
+         *   <strong>Note:</strong> It is a client responsibility to recycle the
+         *     received info by calling {@link AccessibilityNodeInfo#recycle()}
+         *     to avoid creating of multiple instances.
+         * </p>
+         *
+         * @param region The region retrieved from {@link #getRegionAt(int)}.
+         * @return The target node associates with the given region.
+         */
+        @Nullable
+        public AccessibilityNodeInfo getTargetForRegion(@NonNull Region region) {
+            return getNodeForAccessibilityId(mConnectionId, mWindowId, mTargetMap.get(region));
+        }
+
+        /**
+         * Return the accessibility id of target node.
+         *
+         * @param region The region retrieved from {@link #getRegionAt(int)}.
+         * @return The accessibility id of target node.
+         *
+         * @hide
+         */
+        @TestApi
+        public long getAccessibilityIdForRegion(@NonNull Region region) {
+            return mTargetMap.get(region);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(mTargetMap.size());
+            for (int i = 0; i < mTargetMap.size(); i++) {
+                final Region region = mTargetMap.keyAt(i);
+                final Long accessibilityId = mTargetMap.valueAt(i);
+                region.writeToParcel(dest, flags);
+                dest.writeLong(accessibilityId);
+            }
+        }
+
+        /**
+         * @see android.os.Parcelable.Creator
+         */
+        public static final Parcelable.Creator<TouchDelegateInfo> CREATOR =
+                new Parcelable.Creator<TouchDelegateInfo>() {
+            @Override
+            public TouchDelegateInfo createFromParcel(Parcel parcel) {
+                final int size = parcel.readInt();
+                if (size == 0) {
+                    return null;
+                }
+                final ArrayMap<Region, Long> targetMap = new ArrayMap<>(size);
+                for (int i = 0; i < size; i++) {
+                    final Region region = Region.CREATOR.createFromParcel(parcel);
+                    final long accessibilityId = parcel.readLong();
+                    targetMap.put(region, accessibilityId);
+                }
+                final TouchDelegateInfo touchDelegateInfo = new TouchDelegateInfo(
+                        targetMap, false);
+                return touchDelegateInfo;
+            }
+
+            @Override
+            public TouchDelegateInfo[] newArray(int size) {
+                return new TouchDelegateInfo[size];
+            }
+        };
+    }
+
+    /**
      * @see android.os.Parcelable.Creator
      */
     public static final Parcelable.Creator<AccessibilityNodeInfo> CREATOR =
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 7abe19e79..d4c7069 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -803,10 +803,6 @@
                 return true;
             }
         }
-        if (sVerbose) {
-            Log.v(TAG, "not ignoring notifyViewEntered(flags=" + flags + ", view=" + id
-                    + ", state " + getStateAsStringLocked() + ", enteredIds=" + mEnteredIds);
-        }
         return false;
     }
 
@@ -845,6 +841,9 @@
         ensureServiceClientAddedIfNeededLocked();
 
         if (!mEnabled) {
+            if (sVerbose) {
+                Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled");
+            }
             if (mCallback != null) {
                 callback = mCallback;
             }
@@ -995,6 +994,9 @@
         ensureServiceClientAddedIfNeededLocked();
 
         if (!mEnabled) {
+            if (sVerbose) {
+                Log.v(TAG, "ignoring notifyViewEntered(" + id + "): disabled");
+            }
             if (mCallback != null) {
                 callback = mCallback;
             }
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index ca2ccaf..e9acdc3 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -48,6 +48,7 @@
 import android.util.PrintWriterPrinter;
 import android.util.Printer;
 import android.util.SparseArray;
+import android.view.Display;
 import android.view.InputChannel;
 import android.view.InputEvent;
 import android.view.InputEventSender;
@@ -58,7 +59,10 @@
 import android.view.autofill.AutofillManager;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.inputmethod.InputMethodDebug;
 import com.android.internal.inputmethod.InputMethodPrivilegedOperationsRegistry;
+import com.android.internal.inputmethod.StartInputReason;
+import com.android.internal.inputmethod.UnbindReason;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.view.IInputConnectionWrapper;
 import com.android.internal.view.IInputContext;
@@ -66,7 +70,6 @@
 import com.android.internal.view.IInputMethodManager;
 import com.android.internal.view.IInputMethodSession;
 import com.android.internal.view.InputBindResult;
-import com.android.internal.view.InputMethodClient;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -265,7 +268,7 @@
      * @hide
      */
     public static void ensureDefaultInstanceForDefaultDisplayIfNecessary() {
-        getInstanceInternal();
+        forContextInternal(Display.DEFAULT_DISPLAY, Looper.getMainLooper());
     }
 
     private static final Object sLock = new Object();
@@ -279,6 +282,17 @@
     static InputMethodManager sInstance;
 
     /**
+     * Global map between display to {@link InputMethodManager}.
+     *
+     * <p>Currently this map works like a so-called leaky singleton.  Once an instance is registered
+     * for the associated display ID, that instance will never be garbage collected.</p>
+     *
+     * <p>TODO(Bug 116699479): Implement instance clean up mechanism.</p>
+     */
+    @GuardedBy("sLock")
+    private static final SparseArray<InputMethodManager> sInstanceMap = new SparseArray<>();
+
+    /**
      * @hide Flag for IInputMethodManager.windowGainedFocus: a view in
      * the window has input focus.
      */
@@ -335,6 +349,8 @@
     // Our generic input connection if the current target does not have its own.
     final IInputContext mIInputContext;
 
+    private final int mDisplayId;
+
     /**
      * True if this input method client is active, initially false.
      */
@@ -452,6 +468,29 @@
         return afm != null && afm.isAutofillUiShowing();
     }
 
+    /**
+     * Checks the consistency between {@link InputMethodManager} state and {@link View} state.
+     *
+     * @param view {@link View} to be checked
+     * @return {@code true} if {@code view} is not {@code null} and there is a {@link Context}
+     *         mismatch between {@link InputMethodManager} and {@code view}
+     */
+    private boolean shouldDispatchToViewContext(@Nullable View view) {
+        if (view == null) {
+            return false;
+        }
+        final int viewDisplayId = view.getContext().getDisplayId();
+        if (viewDisplayId != mDisplayId) {
+            Log.w(TAG, "b/117267690: Context mismatch found. view=" + view + " belongs to"
+                    + " displayId=" + viewDisplayId
+                    + " but InputMethodManager belongs to displayId=" + mDisplayId
+                    + ". Use the right InputMethodManager instance to avoid performance overhead.",
+                    new Throwable());
+            return true;
+        }
+        return false;
+    }
+
     private static boolean canStartInput(View servedView) {
         // We can start input ether the servedView has window focus
         // or the activity is showing autofill ui.
@@ -503,17 +542,16 @@
                         mCurId = res.id;
                         mBindSequence = res.sequence;
                     }
-                    startInputInner(InputMethodClient.START_INPUT_REASON_BOUND_TO_IMMS,
-                            null, 0, 0, 0);
+                    startInputInner(StartInputReason.BOUND_TO_IMMS, null, 0, 0, 0);
                     return;
                 }
                 case MSG_UNBIND: {
                     final int sequence = msg.arg1;
-                    @InputMethodClient.UnbindReason
+                    @UnbindReason
                     final int reason = msg.arg2;
                     if (DEBUG) {
                         Log.i(TAG, "handleMessage: MSG_UNBIND " + sequence +
-                                " reason=" + InputMethodClient.getUnbindReason(reason));
+                                " reason=" + InputMethodDebug.unbindReasonToString(reason));
                     }
                     final boolean startInput;
                     synchronized (mH) {
@@ -530,8 +568,7 @@
                     }
                     if (startInput) {
                         startInputInner(
-                                InputMethodClient.START_INPUT_REASON_UNBOUND_FROM_IMMS, null, 0, 0,
-                                0);
+                                StartInputReason.UNBOUND_FROM_IMMS, null, 0, 0, 0);
                     }
                     return;
                 }
@@ -560,9 +597,8 @@
                         // handling this message.
                         if (mServedView != null && canStartInput(mServedView)) {
                             if (checkFocusNoStartInput(mRestartOnNextWindowFocus)) {
-                                final int reason = active ?
-                                        InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS :
-                                        InputMethodClient.START_INPUT_REASON_DEACTIVATED_BY_IMMS;
+                                final int reason = active ? StartInputReason.ACTIVATED_BY_IMMS
+                                        : StartInputReason.DEACTIVATED_BY_IMMS;
                                 startInputInner(reason, null, 0, 0, 0);
                             }
                         }
@@ -659,7 +695,7 @@
         }
 
         @Override
-        public void onUnbindMethod(int sequence, @InputMethodClient.UnbindReason int unbindReason) {
+        public void onUnbindMethod(int sequence, @UnbindReason int unbindReason) {
             mH.obtainMessage(MSG_UNBIND, sequence, unbindReason).sendToTarget();
         }
 
@@ -701,65 +737,101 @@
         return false;
     }
 
-    private static IInputMethodManager getIInputMethodManager() throws ServiceNotFoundException {
-        if (!isInEditMode()) {
-            return IInputMethodManager.Stub.asInterface(
-                    ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
-        }
-        // If InputMethodManager is running for layoutlib, stub out IPCs into IMMS.
-        final Class<IInputMethodManager> c = IInputMethodManager.class;
-        return (IInputMethodManager) Proxy.newProxyInstance(c.getClassLoader(),
-                new Class[]{c}, (proxy, method, args) -> {
-                    final Class<?> returnType = method.getReturnType();
-                    if (returnType == boolean.class) {
-                        return false;
-                    } else if (returnType == int.class) {
-                        return 0;
-                    } else if (returnType == long.class) {
-                        return 0L;
-                    } else if (returnType == short.class) {
-                        return 0;
-                    } else if (returnType == char.class) {
-                        return 0;
-                    } else if (returnType == byte.class) {
-                        return 0;
-                    } else if (returnType == float.class) {
-                        return 0f;
-                    } else if (returnType == double.class) {
-                        return 0.0;
-                    } else {
-                        return null;
-                    }
-                });
+    @NonNull
+    private static InputMethodManager createInstance(int displayId, Looper looper) {
+        return isInEditMode() ? createStubInstance(displayId, looper)
+                : createRealInstance(displayId, looper);
     }
 
-    InputMethodManager(Looper looper) throws ServiceNotFoundException {
-        mService = getIInputMethodManager();
+    @NonNull
+    private static InputMethodManager createRealInstance(int displayId, Looper looper) {
+        final IInputMethodManager service;
+        try {
+            service = IInputMethodManager.Stub.asInterface(
+                    ServiceManager.getServiceOrThrow(Context.INPUT_METHOD_SERVICE));
+        } catch (ServiceNotFoundException e) {
+            throw new IllegalStateException(e);
+        }
+        final InputMethodManager imm = new InputMethodManager(service, displayId, looper);
+        try {
+            service.addClient(imm.mClient, imm.mIInputContext, displayId);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+        return imm;
+    }
+
+    @NonNull
+    private static InputMethodManager createStubInstance(int displayId, Looper looper) {
+        // If InputMethodManager is running for layoutlib, stub out IPCs into IMMS.
+        final Class<IInputMethodManager> c = IInputMethodManager.class;
+        final IInputMethodManager stubInterface =
+                (IInputMethodManager) Proxy.newProxyInstance(c.getClassLoader(),
+                        new Class[]{c}, (proxy, method, args) -> {
+                            final Class<?> returnType = method.getReturnType();
+                            if (returnType == boolean.class) {
+                                return false;
+                            } else if (returnType == int.class) {
+                                return 0;
+                            } else if (returnType == long.class) {
+                                return 0L;
+                            } else if (returnType == short.class) {
+                                return 0;
+                            } else if (returnType == char.class) {
+                                return 0;
+                            } else if (returnType == byte.class) {
+                                return 0;
+                            } else if (returnType == float.class) {
+                                return 0f;
+                            } else if (returnType == double.class) {
+                                return 0.0;
+                            } else {
+                                return null;
+                            }
+                        });
+        return new InputMethodManager(stubInterface, displayId, looper);
+    }
+
+    private InputMethodManager(IInputMethodManager service, int displayId, Looper looper) {
+        mService = service;
         mMainLooper = looper;
         mH = new H(looper);
-        mIInputContext = new ControlledInputConnectionWrapper(looper,
-                mDummyInputConnection, this);
+        mDisplayId = displayId;
+        mIInputContext = new ControlledInputConnectionWrapper(looper, mDummyInputConnection, this);
     }
 
     /**
-     * Retrieve the global {@link InputMethodManager} instance, creating it if it doesn't already
-     * exist.
+     * Retrieve an instance for the given {@link Context}, creating it if it doesn't already exist.
      *
-     * @return global {@link InputMethodManager} instance
+     * @param context {@link Context} for which IME APIs need to work
+     * @return {@link InputMethodManager} instance
      * @hide
      */
-    public static InputMethodManager getInstanceInternal() {
+    @NonNull
+    public static InputMethodManager forContext(Context context) {
+        final int displayId = context.getDisplayId();
+        // For better backward compatibility, we always use Looper.getMainLooper() for the default
+        // display case.
+        final Looper looper = displayId == Display.DEFAULT_DISPLAY
+                ? Looper.getMainLooper() : context.getMainLooper();
+        return forContextInternal(displayId, looper);
+    }
+
+    @NonNull
+    private static InputMethodManager forContextInternal(int displayId, Looper looper) {
+        final boolean isDefaultDisplay = displayId == Display.DEFAULT_DISPLAY;
         synchronized (sLock) {
-            if (sInstance == null) {
-                try {
-                    final InputMethodManager imm = new InputMethodManager(Looper.getMainLooper());
-                    imm.mService.addClient(imm.mClient, imm.mIInputContext);
-                    sInstance = imm;
-                } catch (ServiceNotFoundException | RemoteException e) {
-                    throw new IllegalStateException(e);
-                }
+            InputMethodManager instance = sInstanceMap.get(displayId);
+            if (instance != null) {
+                return instance;
             }
-            return sInstance;
+            instance = createInstance(displayId, looper);
+            // For backward compatibility, store the instance also to sInstance for default display.
+            if (sInstance == null && isDefaultDisplay) {
+                sInstance = instance;
+            }
+            sInstanceMap.put(displayId, instance);
+            return instance;
         }
     }
 
@@ -916,6 +988,11 @@
      * input method.
      */
     public boolean isActive(View view) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            return view.getContext().getSystemService(InputMethodManager.class).isActive(view);
+        }
+
         checkFocus();
         synchronized (mH) {
             return (mServedView == view
@@ -991,13 +1068,6 @@
         mNextServedView = null;
         if (mServedView != null) {
             if (DEBUG) Log.v(TAG, "FINISH INPUT: mServedView=" + dumpViewInfo(mServedView));
-            if (mCurrentTextBoxAttribute != null) {
-                try {
-                    mService.finishInput(mClient);
-                } catch (RemoteException e) {
-                    throw e.rethrowFromSystemServer();
-                }
-            }
             mServedView = null;
             mCompletions = null;
             mServedConnecting = false;
@@ -1006,6 +1076,13 @@
     }
 
     public void displayCompletions(View view, CompletionInfo[] completions) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            view.getContext().getSystemService(InputMethodManager.class)
+                    .displayCompletions(view, completions);
+            return;
+        }
+
         checkFocus();
         synchronized (mH) {
             if (mServedView != view && (mServedView == null
@@ -1024,6 +1101,13 @@
     }
 
     public void updateExtractedText(View view, int token, ExtractedText text) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            view.getContext().getSystemService(InputMethodManager.class)
+                    .updateExtractedText(view, token, text);
+            return;
+        }
+
         checkFocus();
         synchronized (mH) {
             if (mServedView != view && (mServedView == null
@@ -1065,6 +1149,12 @@
      * 0 or have the {@link #SHOW_IMPLICIT} bit set.
      */
     public boolean showSoftInput(View view, int flags) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            return view.getContext().getSystemService(InputMethodManager.class)
+                    .showSoftInput(view, flags);
+        }
+
         return showSoftInput(view, flags, null);
     }
 
@@ -1127,6 +1217,12 @@
      * {@link #RESULT_HIDDEN}.
      */
     public boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            return view.getContext().getSystemService(InputMethodManager.class)
+                    .showSoftInput(view, flags, resultReceiver);
+        }
+
         checkFocus();
         synchronized (mH) {
             if (mServedView != view && (mServedView == null
@@ -1290,6 +1386,12 @@
      * @param view The view whose text has changed.
      */
     public void restartInput(View view) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            view.getContext().getSystemService(InputMethodManager.class).restartInput(view);
+            return;
+        }
+
         checkFocus();
         synchronized (mH) {
             if (mServedView != view && (mServedView == null
@@ -1300,11 +1402,10 @@
             mServedConnecting = true;
         }
 
-        startInputInner(InputMethodClient.START_INPUT_REASON_APP_CALLED_RESTART_INPUT_API, null, 0,
-                0, 0);
+        startInputInner(StartInputReason.APP_CALLED_RESTART_INPUT_API, null, 0, 0, 0);
     }
 
-    boolean startInputInner(@InputMethodClient.StartInputReason final int startInputReason,
+    boolean startInputInner(@StartInputReason int startInputReason,
             @Nullable IBinder windowGainingFocus, int controlFlags, int softInputMode,
             int windowFlags) {
         final View view;
@@ -1314,7 +1415,7 @@
             // Make sure we have a window token for the served view.
             if (DEBUG) {
                 Log.v(TAG, "Starting input: view=" + dumpViewInfo(view) +
-                        " reason=" + InputMethodClient.getStartInputReason(startInputReason));
+                        " reason=" + InputMethodDebug.startInputReasonToString(startInputReason));
             }
             if (view == null) {
                 if (DEBUG) Log.v(TAG, "ABORT input: no served view!");
@@ -1433,7 +1534,7 @@
                 if (res == null) {
                     Log.wtf(TAG, "startInputOrWindowGainedFocus must not return"
                             + " null. startInputReason="
-                            + InputMethodClient.getStartInputReason(startInputReason)
+                            + InputMethodDebug.startInputReasonToString(startInputReason)
                             + " editorInfo=" + tba
                             + " controlFlags=#" + Integer.toHexString(controlFlags));
                     return false;
@@ -1568,7 +1669,7 @@
     @UnsupportedAppUsage
     public void checkFocus() {
         if (checkFocusNoStartInput(false)) {
-            startInputInner(InputMethodClient.START_INPUT_REASON_CHECK_FOCUS, null, 0, 0, 0);
+            startInputInner(StartInputReason.CHECK_FOCUS, null, 0, 0, 0);
         }
     }
 
@@ -1631,7 +1732,7 @@
         boolean forceNewFocus = false;
         synchronized (mH) {
             if (DEBUG) Log.v(TAG, "onWindowFocus: " + focusedView
-                    + " softInputMode=" + InputMethodClient.softInputModeToString(softInputMode)
+                    + " softInputMode=" + InputMethodDebug.softInputModeToString(softInputMode)
                     + " first=" + first + " flags=#"
                     + Integer.toHexString(windowFlags));
             if (mRestartOnNextWindowFocus) {
@@ -1658,8 +1759,8 @@
             // should be done in conjunction with telling the system service
             // about the window gaining focus, to help make the transition
             // smooth.
-            if (startInputInner(InputMethodClient.START_INPUT_REASON_WINDOW_FOCUS_GAIN,
-                    rootView.getWindowToken(), controlFlags, softInputMode, windowFlags)) {
+            if (startInputInner(StartInputReason.WINDOW_FOCUS_GAIN, rootView.getWindowToken(),
+                    controlFlags, softInputMode, windowFlags)) {
                 return;
             }
         }
@@ -1670,7 +1771,7 @@
             try {
                 if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput");
                 mService.startInputOrWindowGainedFocus(
-                        InputMethodClient.START_INPUT_REASON_WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient,
+                        StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY, mClient,
                         rootView.getWindowToken(), controlFlags, softInputMode, windowFlags, null,
                         null, 0 /* missingMethodFlags */,
                         rootView.getContext().getApplicationInfo().targetSdkVersion);
@@ -1714,6 +1815,13 @@
      */
     public void updateSelection(View view, int selStart, int selEnd,
             int candidatesStart, int candidatesEnd) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            view.getContext().getSystemService(InputMethodManager.class)
+                    .updateSelection(view, selStart, selEnd, candidatesStart, candidatesEnd);
+            return;
+        }
+
         checkFocus();
         synchronized (mH) {
             if ((mServedView != view && (mServedView == null
@@ -1751,6 +1859,12 @@
      * Notify the event when the user tapped or clicked the text view.
      */
     public void viewClicked(View view) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            view.getContext().getSystemService(InputMethodManager.class).viewClicked(view);
+            return;
+        }
+
         final boolean focusChanged = mServedView != mNextServedView;
         checkFocus();
         synchronized (mH) {
@@ -1815,6 +1929,13 @@
      */
     @Deprecated
     public void updateCursor(View view, int left, int top, int right, int bottom) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            view.getContext().getSystemService(InputMethodManager.class)
+                    .updateCursor(view, left, top, right, bottom);
+            return;
+        }
+
         checkFocus();
         synchronized (mH) {
             if ((mServedView != view && (mServedView == null
@@ -1846,6 +1967,13 @@
         if (view == null || cursorAnchorInfo == null) {
             return;
         }
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            view.getContext().getSystemService(InputMethodManager.class)
+                    .updateCursorAnchorInfo(view, cursorAnchorInfo);
+            return;
+        }
+
         checkFocus();
         synchronized (mH) {
             if ((mServedView != view &&
@@ -1891,6 +2019,13 @@
      * @param data Any data to include with the command.
      */
     public void sendAppPrivateCommand(View view, String action, Bundle data) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(view)) {
+            view.getContext().getSystemService(InputMethodManager.class)
+                    .sendAppPrivateCommand(view, action, data);
+            return;
+        }
+
         checkFocus();
         synchronized (mH) {
             if ((mServedView != view && (mServedView == null
@@ -2062,6 +2197,13 @@
      */
     public void dispatchKeyEventFromInputMethod(@Nullable View targetView,
             @NonNull KeyEvent event) {
+        // Re-dispatch if there is a context mismatch.
+        if (shouldDispatchToViewContext(targetView)) {
+            targetView.getContext().getSystemService(InputMethodManager.class)
+                    .dispatchKeyEventFromInputMethod(targetView, event);
+            return;
+        }
+
         synchronized (mH) {
             ViewRootImpl viewRootImpl = targetView != null ? targetView.getViewRootImpl() : null;
             if (viewRootImpl == null) {
@@ -2551,6 +2693,7 @@
         sb.append(",windowFocus=" + view.hasWindowFocus());
         sb.append(",autofillUiShowing=" + isAutofillUIShowing(view));
         sb.append(",window=" + view.getWindowToken());
+        sb.append(",displayId=" + view.getContext().getDisplayId());
         sb.append(",temporaryDetach=" + view.isTemporarilyDetached());
         return sb.toString();
     }
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index 9692579..2e92f14 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -21,7 +21,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.StringDef;
-import android.annotation.UnsupportedAppUsage;
 import android.annotation.WorkerThread;
 import android.os.LocaleList;
 import android.os.Looper;
@@ -212,34 +211,13 @@
         return suggestSelection(request);
     }
 
-    // TODO: Remove once apps can build against the latest sdk.
-    /** @hide */
-    @UnsupportedAppUsage
-    default TextSelection suggestSelection(
-            @NonNull CharSequence text,
-            @IntRange(from = 0) int selectionStartIndex,
-            @IntRange(from = 0) int selectionEndIndex,
-            @Nullable TextSelection.Options options) {
-        if (options == null) {
-            return suggestSelection(new TextSelection.Request.Builder(
-                    text, selectionStartIndex, selectionEndIndex).build());
-        } else if (options.getRequest() != null) {
-            return suggestSelection(options.getRequest());
-        } else {
-            return suggestSelection(
-                    new TextSelection.Request.Builder(text, selectionStartIndex, selectionEndIndex)
-                            .setDefaultLocales(options.getDefaultLocales())
-                            .build());
-        }
-    }
-
     /**
      * Classifies the specified text and returns a {@link TextClassification} object that can be
      * used to generate a widget for handling the classified text.
      *
      * <p><strong>NOTE: </strong>Call on a worker thread.
      *
-     * <strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
+     * <p><strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
      * throw an {@link IllegalStateException}. See {@link #isDestroyed()}.
      *
      * @param request the text classification request
@@ -262,7 +240,7 @@
      * {@link #classifyText(TextClassification.Request)}. If that method calls this method,
      * a stack overflow error will happen.
      *
-     * <strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
+     * <p><strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
      * throw an {@link IllegalStateException}. See {@link #isDestroyed()}.
      *
      * @param text text providing context for the text to classify (which is specified
@@ -292,34 +270,13 @@
         return classifyText(request);
     }
 
-    // TODO: Remove once apps can build against the latest sdk.
-    /** @hide */
-    @UnsupportedAppUsage
-    default TextClassification classifyText(
-            @NonNull CharSequence text,
-            @IntRange(from = 0) int startIndex,
-            @IntRange(from = 0) int endIndex,
-            @Nullable TextClassification.Options options) {
-        if (options == null) {
-            return classifyText(
-                    new TextClassification.Request.Builder(text, startIndex, endIndex).build());
-        } else if (options.getRequest() != null) {
-            return classifyText(options.getRequest());
-        } else {
-            return classifyText(new TextClassification.Request.Builder(text, startIndex, endIndex)
-                    .setDefaultLocales(options.getDefaultLocales())
-                    .setReferenceTime(options.getReferenceTime())
-                    .build());
-        }
-    }
-
     /**
      * Generates and returns a {@link TextLinks} that may be applied to the text to annotate it with
      * links information.
      *
      * <p><strong>NOTE: </strong>Call on a worker thread.
      *
-     * <strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
+     * <p><strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
      * throw an {@link IllegalStateException}. See {@link #isDestroyed()}.
      *
      * @param request the text links request
@@ -334,27 +291,10 @@
         return new TextLinks.Builder(request.getText().toString()).build();
     }
 
-    // TODO: Remove once apps can build against the latest sdk.
-    /** @hide */
-    @UnsupportedAppUsage
-    default TextLinks generateLinks(
-            @NonNull CharSequence text, @Nullable TextLinks.Options options) {
-        if (options == null) {
-            return generateLinks(new TextLinks.Request.Builder(text).build());
-        } else if (options.getRequest() != null) {
-            return generateLinks(options.getRequest());
-        } else {
-            return generateLinks(new TextLinks.Request.Builder(text)
-                    .setDefaultLocales(options.getDefaultLocales())
-                    .setEntityConfig(options.getEntityConfig())
-                    .build());
-        }
-    }
-
     /**
      * Returns the maximal length of text that can be processed by generateLinks.
      *
-     * <strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
+     * <p><strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
      * throw an {@link IllegalStateException}. See {@link #isDestroyed()}.
      *
      * @see #generateLinks(TextLinks.Request)
@@ -365,9 +305,29 @@
     }
 
     /**
+     * Detects the language of the specified text.
+     *
+     * <p><strong>NOTE: </strong>Call on a worker thread.
+     *
+     *
+     * <p><strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
+     * throw an {@link IllegalStateException}. See {@link #isDestroyed()}.
+     *
+     * @param request the {@link TextLanguage} request.
+     * @return the {@link TextLanguage} result.
+     */
+    @WorkerThread
+    @NonNull
+    default TextLanguage detectLanguage(@NonNull TextLanguage.Request request) {
+        Preconditions.checkNotNull(request);
+        Utils.checkMainThread();
+        return TextLanguage.EMPTY;
+    }
+
+    /**
      * Reports a selection event.
      *
-     * <strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
+     * <p><strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to this method should
      * throw an {@link IllegalStateException}. See {@link #isDestroyed()}.
      */
     default void onSelectionEvent(@NonNull SelectionEvent event) {}
@@ -375,7 +335,7 @@
     /**
      * Destroys this TextClassifier.
      *
-     * <strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to its methods should
+     * <p><strong>NOTE: </strong>If a TextClassifier has been destroyed, calls to its methods should
      * throw an {@link IllegalStateException}. See {@link #isDestroyed()}.
      *
      * <p>Subsequent calls to this method are no-ops.
@@ -385,7 +345,7 @@
     /**
      * Returns whether or not this TextClassifier has been destroyed.
      *
-     * <strong>NOTE: </strong>If a TextClassifier has been destroyed, caller should not interact
+     * <p><strong>NOTE: </strong>If a TextClassifier has been destroyed, caller should not interact
      * with the classifier and an attempt to do so would throw an {@link IllegalStateException}.
      * However, this method should never throw an {@link IllegalStateException}.
      *
@@ -396,9 +356,7 @@
     }
 
     /** @hide **/
-    default void dump(@NonNull IndentingPrintWriter printWriter) {
-
-    }
+    default void dump(@NonNull IndentingPrintWriter printWriter) {}
 
     /**
      * Configuration object for specifying what entities to identify.
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index 3e240cf..7f1e443 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -31,6 +31,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.graphics.drawable.Icon;
+import android.icu.util.ULocale;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.LocaleList;
@@ -45,6 +46,7 @@
 import com.android.internal.util.Preconditions;
 
 import com.google.android.textclassifier.AnnotatorModel;
+import com.google.android.textclassifier.LangIdModel;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -83,6 +85,9 @@
     private static final String MODEL_FILE_REGEX = "textclassifier\\.(.*)\\.model";
     private static final String UPDATED_MODEL_FILE_PATH =
             "/data/misc/textclassifier/textclassifier.model";
+    private static final String LANG_ID_MODEL_FILE_PATH = "/etc/textclassifier/lang_id.model";
+    private static final String UPDATED_LANG_ID_MODEL_FILE_PATH =
+            "/data/misc/textclassifier/lang_id.model";
 
     private final Context mContext;
     private final TextClassifier mFallback;
@@ -94,7 +99,9 @@
     @GuardedBy("mLock") // Do not access outside this lock.
     private ModelFile mModel;
     @GuardedBy("mLock") // Do not access outside this lock.
-    private AnnotatorModel mNative;
+    private AnnotatorModel mAnnotatorImpl;
+    @GuardedBy("mLock") // Do not access outside this lock.
+    private LangIdModel mLangIdImpl;
 
     private final Object mLoggerLock = new Object();
     @GuardedBy("mLoggerLock") // Do not access outside this lock.
@@ -127,14 +134,15 @@
                     && rangeLength <= mSettings.getSuggestSelectionMaxRangeLength()) {
                 final String localesString = concatenateLocales(request.getDefaultLocales());
                 final ZonedDateTime refTime = ZonedDateTime.now();
-                final AnnotatorModel nativeImpl = getNative(request.getDefaultLocales());
+                final AnnotatorModel annotatorImpl =
+                        getAnnotatorImpl(request.getDefaultLocales());
                 final int start;
                 final int end;
                 if (mSettings.isModelDarkLaunchEnabled() && !request.isDarkLaunchAllowed()) {
                     start = request.getStartIndex();
                     end = request.getEndIndex();
                 } else {
-                    final int[] startEnd = nativeImpl.suggestSelection(
+                    final int[] startEnd = annotatorImpl.suggestSelection(
                             string, request.getStartIndex(), request.getEndIndex(),
                             new AnnotatorModel.SelectionOptions(localesString));
                     start = startEnd[0];
@@ -145,7 +153,7 @@
                         && start <= request.getStartIndex() && end >= request.getEndIndex()) {
                     final TextSelection.Builder tsBuilder = new TextSelection.Builder(start, end);
                     final AnnotatorModel.ClassificationResult[] results =
-                            nativeImpl.classifyText(
+                            annotatorImpl.classifyText(
                                     string, start, end,
                                     new AnnotatorModel.ClassificationOptions(
                                             refTime.toInstant().toEpochMilli(),
@@ -187,7 +195,7 @@
                 final ZonedDateTime refTime = request.getReferenceTime() != null
                         ? request.getReferenceTime() : ZonedDateTime.now();
                 final AnnotatorModel.ClassificationResult[] results =
-                        getNative(request.getDefaultLocales())
+                        getAnnotatorImpl(request.getDefaultLocales())
                                 .classifyText(
                                         string, request.getStartIndex(), request.getEndIndex(),
                                         new AnnotatorModel.ClassificationOptions(
@@ -230,10 +238,10 @@
                     ? request.getEntityConfig().resolveEntityListModifications(
                             getEntitiesForHints(request.getEntityConfig().getHints()))
                     : mSettings.getEntityListDefault();
-            final AnnotatorModel nativeImpl =
-                    getNative(request.getDefaultLocales());
+            final AnnotatorModel annotatorImpl =
+                    getAnnotatorImpl(request.getDefaultLocales());
             final AnnotatorModel.AnnotatedSpan[] annotations =
-                    nativeImpl.annotate(
+                    annotatorImpl.annotate(
                         textString,
                         new AnnotatorModel.AnnotationOptions(
                                 refTime.toInstant().toEpochMilli(),
@@ -288,6 +296,7 @@
         }
     }
 
+    /** @inheritDoc */
     @Override
     public void onSelectionEvent(SelectionEvent event) {
         Preconditions.checkNotNull(event);
@@ -299,7 +308,29 @@
         }
     }
 
-    private AnnotatorModel getNative(LocaleList localeList)
+    /** @inheritDoc */
+    @Override
+    public TextLanguage detectLanguage(@NonNull TextLanguage.Request request) {
+        Preconditions.checkNotNull(request);
+        Utils.checkMainThread();
+        try {
+            final TextLanguage.Builder builder = new TextLanguage.Builder();
+            final LangIdModel.LanguageResult[] langResults =
+                    getLangIdImpl().detectLanguages(request.getText().toString());
+            for (int i = 0; i < langResults.length; i++) {
+                builder.putLocale(
+                        ULocale.forLanguageTag(langResults[i].getLanguage()),
+                        langResults[i].getScore());
+            }
+            return builder.build();
+        } catch (Throwable t) {
+            // Avoid throwing from this method. Log the error.
+            Log.e(LOG_TAG, "Error detecting text language.", t);
+        }
+        return mFallback.detectLanguage(request);
+    }
+
+    private AnnotatorModel getAnnotatorImpl(LocaleList localeList)
             throws FileNotFoundException {
         synchronized (mLock) {
             localeList = localeList == null ? LocaleList.getEmptyLocaleList() : localeList;
@@ -307,16 +338,72 @@
             if (bestModel == null) {
                 throw new FileNotFoundException("No model for " + localeList.toLanguageTags());
             }
-            if (mNative == null || !Objects.equals(mModel, bestModel)) {
+            if (mAnnotatorImpl == null || !Objects.equals(mModel, bestModel)) {
                 Log.d(DEFAULT_LOG_TAG, "Loading " + bestModel);
-                destroyNativeIfExistsLocked();
+                destroyAnnotatorImplIfExistsLocked();
                 final ParcelFileDescriptor fd = ParcelFileDescriptor.open(
                         new File(bestModel.getPath()), ParcelFileDescriptor.MODE_READ_ONLY);
-                mNative = new AnnotatorModel(fd.getFd());
-                closeAndLogError(fd);
-                mModel = bestModel;
+                try {
+                    if (fd != null) {
+                        mAnnotatorImpl = new AnnotatorModel(fd.getFd());
+                        mModel = bestModel;
+                    }
+                } finally {
+                    maybeCloseAndLogError(fd);
+                }
             }
-            return mNative;
+            return mAnnotatorImpl;
+        }
+    }
+
+    @GuardedBy("mLock") // Do not call outside this lock.
+    private void destroyAnnotatorImplIfExistsLocked() {
+        if (mAnnotatorImpl != null) {
+            mAnnotatorImpl.close();
+            mAnnotatorImpl = null;
+        }
+    }
+
+    private LangIdModel getLangIdImpl() throws FileNotFoundException {
+        synchronized (mLock) {
+            if (mLangIdImpl == null) {
+                ParcelFileDescriptor factoryFd = null;
+                ParcelFileDescriptor updateFd = null;
+                try {
+                    int factoryVersion = -1;
+                    int updateVersion = factoryVersion;
+                    final File factoryFile = new File(LANG_ID_MODEL_FILE_PATH);
+                    if (factoryFile.exists()) {
+                        factoryFd = ParcelFileDescriptor.open(
+                                factoryFile, ParcelFileDescriptor.MODE_READ_ONLY);
+                        // TODO: Uncomment when method is implemented:
+                        // if (factoryFd != null) {
+                        //     factoryVersion = LangIdModel.getVersion(factoryFd.getFd());
+                        // }
+                    }
+                    final File updateFile = new File(UPDATED_LANG_ID_MODEL_FILE_PATH);
+                    if (updateFile.exists()) {
+                        updateFd = ParcelFileDescriptor.open(
+                                updateFile, ParcelFileDescriptor.MODE_READ_ONLY);
+                        // TODO: Uncomment when method is implemented:
+                        // if (updateFd != null) {
+                        //     updateVersion = LangIdModel.getVersion(updateFd.getFd());
+                        // }
+                    }
+
+                    if (updateVersion > factoryVersion) {
+                        mLangIdImpl = new LangIdModel(updateFd.getFd());
+                    } else if (factoryFd != null) {
+                        mLangIdImpl = new LangIdModel(factoryFd.getFd());
+                    } else {
+                        throw new FileNotFoundException("Language detection model not found");
+                    }
+                } finally {
+                    maybeCloseAndLogError(factoryFd);
+                    maybeCloseAndLogError(updateFd);
+                }
+            }
+            return mLangIdImpl;
         }
     }
 
@@ -327,14 +414,6 @@
         }
     }
 
-    @GuardedBy("mLock") // Do not call outside this lock.
-    private void destroyNativeIfExistsLocked() {
-        if (mNative != null) {
-            mNative.close();
-            mNative = null;
-        }
-    }
-
     private static String concatenateLocales(@Nullable LocaleList locales) {
         return (locales == null) ? "" : locales.toLanguageTags();
     }
@@ -407,20 +486,19 @@
                 .setText(classifiedText);
 
         final int size = classifications.length;
-        AnnotatorModel.ClassificationResult highestScoringResult = null;
-        float highestScore = Float.MIN_VALUE;
+        AnnotatorModel.ClassificationResult highestScoringResult =
+                size > 0 ? classifications[0] : null;
         for (int i = 0; i < size; i++) {
             builder.setEntityType(classifications[i].getCollection(),
                                   classifications[i].getScore());
-            if (classifications[i].getScore() > highestScore) {
+            if (classifications[i].getScore() > highestScoringResult.getScore()) {
                 highestScoringResult = classifications[i];
-                highestScore = classifications[i].getScore();
             }
         }
 
         boolean isPrimaryAction = true;
         for (LabeledIntent labeledIntent : IntentFactory.create(
-                mContext, referenceTime, highestScoringResult, classifiedText)) {
+                mContext, classifiedText, referenceTime, highestScoringResult)) {
             final RemoteAction action = labeledIntent.asRemoteAction(mContext);
             if (action == null) {
                 continue;
@@ -461,9 +539,13 @@
     }
 
     /**
-     * Closes the ParcelFileDescriptor and logs any errors that occur.
+     * Closes the ParcelFileDescriptor, if non-null, and logs any errors that occur.
      */
-    private static void closeAndLogError(ParcelFileDescriptor fd) {
+    private static void maybeCloseAndLogError(@Nullable ParcelFileDescriptor fd) {
+        if (fd == null) {
+            return;
+        }
+
         try {
             fd.close();
         } catch (IOException e) {
@@ -485,12 +567,17 @@
         /** Returns null if the path did not point to a compatible model. */
         static @Nullable ModelFile fromPath(String path) {
             final File file = new File(path);
+            if (!file.exists()) {
+                return null;
+            }
+            ParcelFileDescriptor modelFd = null;
             try {
-                final ParcelFileDescriptor modelFd = ParcelFileDescriptor.open(
-                        file, ParcelFileDescriptor.MODE_READ_ONLY);
+                modelFd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
+                if (modelFd == null) {
+                    return null;
+                }
                 final int version = AnnotatorModel.getVersion(modelFd.getFd());
-                final String supportedLocalesStr =
-                        AnnotatorModel.getLocales(modelFd.getFd());
+                final String supportedLocalesStr = AnnotatorModel.getLocales(modelFd.getFd());
                 if (supportedLocalesStr.isEmpty()) {
                     Log.d(DEFAULT_LOG_TAG, "Ignoring " + file.getAbsolutePath());
                     return null;
@@ -500,12 +587,13 @@
                 for (String langTag : supportedLocalesStr.split(",")) {
                     supportedLocales.add(Locale.forLanguageTag(langTag));
                 }
-                closeAndLogError(modelFd);
                 return new ModelFile(path, file.getName(), version, supportedLocales,
                                      languageIndependent);
             } catch (FileNotFoundException e) {
                 Log.e(DEFAULT_LOG_TAG, "Failed to peek " + file.getAbsolutePath(), e);
                 return null;
+            } finally {
+                maybeCloseAndLogError(modelFd);
             }
         }
 
@@ -557,12 +645,12 @@
         public boolean equals(Object other) {
             if (this == other) {
                 return true;
-            } else if (other == null || !ModelFile.class.isAssignableFrom(other.getClass())) {
-                return false;
-            } else {
+            }
+            if (other instanceof ModelFile) {
                 final ModelFile otherModel = (ModelFile) other;
                 return mPath.equals(otherModel.mPath);
             }
+            return false;
         }
 
         @Override
@@ -677,10 +765,12 @@
         @NonNull
         public static List<LabeledIntent> create(
                 Context context,
+                String text,
                 @Nullable Instant referenceTime,
-                AnnotatorModel.ClassificationResult classification,
-                String text) {
-            final String type = classification.getCollection().trim().toLowerCase(Locale.ENGLISH);
+                @Nullable AnnotatorModel.ClassificationResult classification) {
+            final String type = classification != null
+                    ? classification.getCollection().trim().toLowerCase(Locale.ENGLISH)
+                    : null;
             text = text.trim();
             switch (type) {
                 case TextClassifier.TYPE_EMAIL:
diff --git a/core/java/android/view/textclassifier/TextLanguage.java b/core/java/android/view/textclassifier/TextLanguage.java
new file mode 100644
index 0000000..d28459e
--- /dev/null
+++ b/core/java/android/view/textclassifier/TextLanguage.java
@@ -0,0 +1,307 @@
+/*
+ * 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.view.textclassifier;
+
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.icu.util.ULocale;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Represents the result of language detection of a piece of text.
+ * <p>
+ * This contains a list of locales, each paired with a confidence score, sorted in decreasing
+ * order of those scores. E.g., for a given input text, the model may return
+ * {@code [<"en", 0.85>, <"fr", 0.15>]}. This sample result means the model reports that it is
+ * 85% likely that the entire text is in English and 15% likely that the entire text is in French,
+ * etc. It does not mean that 85% of the input is in English and 15% is in French.
+ */
+public final class TextLanguage implements Parcelable {
+
+    public static final Creator<TextLanguage> CREATOR = new Creator<TextLanguage>() {
+        @Override
+        public TextLanguage createFromParcel(Parcel in) {
+            return readFromParcel(in);
+        }
+
+        @Override
+        public TextLanguage[] newArray(int size) {
+            return new TextLanguage[size];
+        }
+    };
+
+    static final TextLanguage EMPTY = new Builder().build();
+
+    @Nullable private final String mId;
+    private final EntityConfidence mEntityConfidence;
+    private final Bundle mBundle;
+
+    private TextLanguage(
+            @Nullable String id,
+            EntityConfidence entityConfidence,
+            Bundle bundle) {
+        mId = id;
+        mEntityConfidence = entityConfidence;
+        mBundle = bundle;
+    }
+
+    /**
+     * Returns the id, if one exists, for this object.
+     */
+    @Nullable
+    public String getId() {
+        return mId;
+    }
+
+    /**
+     * Returns the number of possible locales for the processed text.
+     */
+    @IntRange(from = 0)
+    public int getLocaleHypothesisCount() {
+        return mEntityConfidence.getEntities().size();
+    }
+
+    /**
+     * Returns the language locale at the specified index. Locales are ordered from high
+     * confidence to low confidence.
+     *
+     * @throws IndexOutOfBoundsException if the specified index is out of range.
+     * @see #getLocaleCount() for the number of locales available.
+     */
+    @NonNull
+    public ULocale getLocale(int index) {
+        return ULocale.forLanguageTag(mEntityConfidence.getEntities().get(index));
+    }
+
+    /**
+     * Returns the confidence score for the specified language locale. The value ranges from
+     * 0 (low confidence) to 1 (high confidence). 0 indicates that the locale was not found for
+     * the processed text.
+     */
+    @FloatRange(from = 0.0, to = 1.0)
+    public float getConfidenceScore(@NonNull ULocale locale) {
+        return mEntityConfidence.getConfidenceScore(locale.toLanguageTag());
+    }
+
+    /**
+     * Returns a bundle containing non-structured extra information about this result.
+     *
+     * <p><b>NOTE: </b>Each call to this method returns a new bundle copy so clients should prefer
+     * to hold a reference to the returned bundle rather than frequently calling this method.
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return mBundle.deepCopy();
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                Locale.US,
+                "TextLanguage {id=%s, locales=%s, bundle=%s}",
+                mId, mEntityConfidence, mBundle);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mId);
+        mEntityConfidence.writeToParcel(dest, flags);
+        dest.writeBundle(mBundle);
+    }
+
+    private static TextLanguage readFromParcel(Parcel in) {
+        return new TextLanguage(
+                in.readString(),
+                EntityConfidence.CREATOR.createFromParcel(in),
+                in.readBundle());
+    }
+
+    /**
+     * Builder used to build TextLanguage objects.
+     */
+    public static final class Builder {
+
+        @Nullable private String mId;
+        private final Map<String, Float> mEntityConfidenceMap = new ArrayMap<>();
+        @Nullable private Bundle mBundle;
+
+        /**
+         * Sets a language locale for the processed text and assigns a confidence score. If the
+         * locale has already been set, this updates it.
+         *
+         * @param confidenceScore a value from 0 (low confidence) to 1 (high confidence).
+         *      0 implies the locale does not exist for the processed text.
+         *      Values greater than 1 are clamped to 1.
+         */
+        @NonNull
+        public Builder putLocale(
+                @NonNull ULocale locale,
+                @FloatRange(from = 0.0, to = 1.0) float confidenceScore) {
+            Preconditions.checkNotNull(locale);
+            mEntityConfidenceMap.put(locale.toLanguageTag(), confidenceScore);
+            return this;
+        }
+
+        /**
+         * Sets an optional id for the TextLanguage object.
+         */
+        @NonNull
+        public Builder setId(@Nullable String id) {
+            mId = id;
+            return this;
+        }
+
+        /**
+         * Sets a bundle containing non-structured extra information about the TextLanguage object.
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle bundle) {
+            mBundle = Preconditions.checkNotNull(bundle);
+            return this;
+        }
+
+        /**
+         * Builds and returns a new TextLanguage object.
+         * <p>
+         * If necessary, this method will verify fields, clamp them, and make them immutable.
+         */
+        @NonNull
+        public TextLanguage build() {
+            mBundle = mBundle == null ? new Bundle() : mBundle.deepCopy();
+            return new TextLanguage(
+                    mId,
+                    new EntityConfidence(mEntityConfidenceMap),
+                    mBundle);
+        }
+    }
+
+    /**
+     * A request object for detecting the language of a piece of text.
+     */
+    public static final class Request implements Parcelable {
+
+        public static final Creator<Request> CREATOR = new Creator<Request>() {
+            @Override
+            public Request createFromParcel(Parcel in) {
+                return readFromParcel(in);
+            }
+
+            @Override
+            public Request[] newArray(int size) {
+                return new Request[size];
+            }
+        };
+
+        private final CharSequence mText;
+        private final Bundle mBundle;
+
+        private Request(CharSequence text, Bundle bundle) {
+            mText = text;
+            mBundle = bundle;
+        }
+
+        /**
+         * Returns the text to process.
+         */
+        @NonNull
+        public CharSequence getText() {
+            return mText;
+        }
+
+        /**
+         * Returns a bundle containing non-structured extra information about this request.
+         *
+         * <p><b>NOTE: </b>Each call to this method returns a new bundle copy so clients should
+         * prefer to hold a reference to the returned bundle rather than frequently calling this
+         * method.
+         */
+        @NonNull
+        public Bundle getExtras() {
+            return mBundle.deepCopy();
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeCharSequence(mText);
+            dest.writeBundle(mBundle);
+        }
+
+        private static Request readFromParcel(Parcel in) {
+            return new Request(
+                    in.readCharSequence(),
+                    in.readBundle());
+        }
+
+        /**
+         * A builder for building TextLanguage requests.
+         */
+        public static final class Builder {
+
+            private final CharSequence mText;
+            @Nullable private Bundle mBundle;
+
+            /**
+             * Creates a builder to build TextLanguage requests.
+             *
+             * @param text the text to process.
+             */
+            public Builder(@NonNull CharSequence text) {
+                mText = Preconditions.checkNotNull(text);
+            }
+
+            /**
+             * Sets a bundle containing non-structured extra information about the request.
+             */
+            @NonNull
+            public Builder setExtras(@NonNull Bundle bundle) {
+                mBundle = Preconditions.checkNotNull(bundle);
+                return this;
+            }
+
+            /**
+             * Builds and returns a new TextLanguage request object.
+             * <p>
+             * If necessary, this method will verify fields, clamp them, and make them immutable.
+             */
+            @NonNull
+            public Request build() {
+                mBundle = mBundle == null ? new Bundle() : mBundle.deepCopy();
+                return new Request(mText.toString(), mBundle);
+            }
+        }
+    }
+}
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index bdd7a09..300bb6f 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -282,19 +282,28 @@
             SAFE_BROWSING_THREAT_UNKNOWN,
             SAFE_BROWSING_THREAT_MALWARE,
             SAFE_BROWSING_THREAT_PHISHING,
-            SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE
+            SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE,
+            SAFE_BROWSING_THREAT_BILLING,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface SafeBrowsingThreat {}
 
-    /** The resource was blocked for an unknown reason */
+    /** The resource was blocked for an unknown reason. */
     public static final int SAFE_BROWSING_THREAT_UNKNOWN = 0;
-    /** The resource was blocked because it contains malware */
+    /** The resource was blocked because it contains malware. */
     public static final int SAFE_BROWSING_THREAT_MALWARE = 1;
-    /** The resource was blocked because it contains deceptive content */
+    /** The resource was blocked because it contains deceptive content. */
     public static final int SAFE_BROWSING_THREAT_PHISHING = 2;
-    /** The resource was blocked because it contains unwanted software */
+    /** The resource was blocked because it contains unwanted software. */
     public static final int SAFE_BROWSING_THREAT_UNWANTED_SOFTWARE = 3;
+    /**
+     * The resource was blocked because it may trick the user into a billing agreement.
+     *
+     * <p>This constant is only used when targetSdkVersion is at least {@link
+     * android.os.Build.VERSION_CODES#Q}. Otherwise, {@link #SAFE_BROWSING_THREAT_UNKNOWN} is used
+     * instead.
+     */
+    public static final int SAFE_BROWSING_THREAT_BILLING = 4;
 
     /**
      * Report an error to the host application. These errors are unrecoverable
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index ba66571..6ab7f66 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -27,11 +27,11 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.RecordingCanvas;
 import android.os.RemoteException;
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.util.SparseArray;
-import android.view.DisplayListCanvas;
 import android.view.View;
 import android.view.ViewRootImpl;
 
@@ -107,12 +107,12 @@
      * @throws IllegalArgumentException if the canvas is not hardware accelerated
      */
     public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) {
-        if (!(canvas instanceof DisplayListCanvas)) {
+        if (!(canvas instanceof RecordingCanvas)) {
             // Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
             throw new IllegalArgumentException(canvas.getClass().getName()
                     + " is not a DisplayList canvas");
         }
-        ((DisplayListCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, null);
+        ((RecordingCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, null);
     }
 
     /**
@@ -129,12 +129,12 @@
      */
     public void callDrawGlFunction(@NonNull Canvas canvas, long nativeDrawGLFunctor,
             @Nullable Runnable releasedRunnable) {
-        if (!(canvas instanceof DisplayListCanvas)) {
+        if (!(canvas instanceof RecordingCanvas)) {
             // Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
             throw new IllegalArgumentException(canvas.getClass().getName()
                     + " is not a DisplayList canvas");
         }
-        ((DisplayListCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, releasedRunnable);
+        ((RecordingCanvas) canvas).drawGLFunctor2(nativeDrawGLFunctor, releasedRunnable);
     }
 
     /**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 9d74c98..48c164f 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -42,8 +42,10 @@
 import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.graphics.RenderNode;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
@@ -83,7 +85,6 @@
 import android.view.ActionMode.Callback;
 import android.view.ContextMenu;
 import android.view.ContextThemeWrapper;
-import android.view.DisplayListCanvas;
 import android.view.DragAndDropPermissions;
 import android.view.DragEvent;
 import android.view.Gravity;
@@ -93,7 +94,6 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
-import android.view.RenderNode;
 import android.view.SubMenu;
 import android.view.View;
 import android.view.View.DragShadowBuilder;
@@ -101,6 +101,7 @@
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
+import android.view.ViewParent;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityNodeInfo;
@@ -1940,18 +1941,18 @@
 
             // Rebuild display list if it is invalid
             if (blockDisplayListIsInvalid) {
-                final DisplayListCanvas displayListCanvas = blockDisplayList.start(
+                final RecordingCanvas recordingCanvas = blockDisplayList.start(
                         right - left, bottom - top);
                 try {
                     // drawText is always relative to TextView's origin, this translation
                     // brings this range of text back to the top left corner of the viewport
-                    displayListCanvas.translate(-left, -top);
-                    layout.drawText(displayListCanvas, blockBeginLine, blockEndLine);
+                    recordingCanvas.translate(-left, -top);
+                    layout.drawText(recordingCanvas, blockBeginLine, blockEndLine);
                     mTextRenderNodes[blockIndex].isDirty = false;
                     // No need to untranslate, previous context is popped after
                     // drawDisplayList
                 } finally {
-                    blockDisplayList.end(displayListCanvas);
+                    blockDisplayList.end(recordingCanvas);
                     // Same as drawDisplayList below, handled by our TextView's parent
                     blockDisplayList.setClipToBounds(false);
                 }
@@ -1961,7 +1962,7 @@
             blockDisplayList.setLeftTopRightBottom(left, top, right, bottom);
             mTextRenderNodes[blockIndex].needsToBeShifted = false;
         }
-        ((DisplayListCanvas) canvas).drawRenderNode(blockDisplayList);
+        ((RecordingCanvas) canvas).drawRenderNode(blockDisplayList);
         return startIndexToFindAvailableRenderNode;
     }
 
@@ -4800,6 +4801,24 @@
             return glyphHeight > magnifierContentHeight;
         }
 
+        private boolean viewIsMatrixTransformed() {
+            if (mMagnifierAnimator.mMagnifierIsShowing) {
+                // Do not check again when the magnifier is currently showing.
+                return false;
+            }
+            if (!mTextView.hasIdentityMatrix()) {
+                return true;
+            }
+            ViewParent viewParent = mTextView.getParent();
+            while (viewParent != null) {
+                if (viewParent instanceof View && !((View) viewParent).hasIdentityMatrix()) {
+                    return true;
+                }
+                viewParent = viewParent.getParent();
+            }
+            return false;
+        }
+
         /**
          * Computes the position where the magnifier should be shown, relative to
          * {@code mTextView}, and writes them to {@code showPosInView}. Also decides
@@ -4928,6 +4947,7 @@
 
             final PointF showPosInView = new PointF();
             final boolean shouldShow = !tooLargeTextForMagnifier()
+                    && !viewIsMatrixTransformed()
                     && obtainMagnifierShowCoordinates(event, showPosInView);
             if (shouldShow) {
                 // Make the cursor visible and stop blinking.
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 16ddd0f..6a3fc0f 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -33,15 +33,15 @@
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.PointF;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.RenderNode;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
 import android.view.ContextThemeWrapper;
 import android.view.Display;
-import android.view.DisplayListCanvas;
 import android.view.PixelCopy;
-import android.view.RenderNode;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceHolder;
@@ -704,7 +704,7 @@
                     cornerRadius
             );
 
-            final DisplayListCanvas canvas = mRenderer.getRootNode().start(width, height);
+            final RecordingCanvas canvas = mRenderer.getRootNode().start(width, height);
             try {
                 canvas.insertReorderBarrier();
                 canvas.drawRenderNode(mBitmapRenderNode);
@@ -736,7 +736,7 @@
             bitmapRenderNode.setClipToOutline(true);
 
             // Create a dummy draw, which will be replaced later with real drawing.
-            final DisplayListCanvas canvas = bitmapRenderNode.start(mContentWidth, mContentHeight);
+            final RecordingCanvas canvas = bitmapRenderNode.start(mContentWidth, mContentHeight);
             try {
                 canvas.drawColor(0xFF00FF00);
             } finally {
@@ -817,7 +817,7 @@
                     return;
                 }
 
-                final DisplayListCanvas canvas =
+                final RecordingCanvas canvas =
                         mBitmapRenderNode.start(mContentWidth, mContentHeight);
                 try {
                     canvas.drawColor(Color.WHITE);
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 35ff6cc..4d03123 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -42,6 +42,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Icon;
+import android.graphics.drawable.RippleDrawable;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Binder;
@@ -152,6 +153,7 @@
     private static final int SET_REMOTE_INPUTS_ACTION_TAG = 18;
     private static final int LAYOUT_PARAM_ACTION_TAG = 19;
     private static final int OVERRIDE_TEXT_COLORS_TAG = 20;
+    private static final int SET_RIPPLE_DRAWABLE_COLOR_TAG = 21;
 
     /**
      * Application that hosts the remote views.
@@ -368,10 +370,12 @@
                 // TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
                 Context context = view.getContext();
                 ActivityOptions opts = getActivityOptions(context);
+                // The NEW_TASK flags are applied through the activity options and not as a part of
+                // the call to startIntentSender() to ensure that they are consistently applied to
+                // both mutable and immutable PendingIntents.
                 context.startIntentSender(
                         pendingIntent.getIntentSender(), fillInIntent,
-                        Intent.FLAG_ACTIVITY_NEW_TASK,
-                        Intent.FLAG_ACTIVITY_NEW_TASK, 0, opts.toBundle());
+                        0, 0, 0, opts.toBundle());
             } catch (IntentSender.SendIntentException e) {
                 android.util.Log.e(LOG_TAG, "Cannot send pending intent: ", e);
                 return false;
@@ -399,10 +403,15 @@
                 windowAnimationStyle.recycle();
 
                 if (enterAnimationId != 0) {
-                    return ActivityOptions.makeCustomAnimation(context, enterAnimationId, 0);
+                    final ActivityOptions opts = ActivityOptions.makeCustomAnimation(context,
+                            enterAnimationId, 0);
+                    opts.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                    return opts;
                 }
             }
-            return ActivityOptions.makeBasic();
+            final ActivityOptions opts = ActivityOptions.makeBasic();
+            opts.setPendingIntentLaunchFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            return opts;
         }
     }
 
@@ -1122,6 +1131,53 @@
         PorterDuff.Mode filterMode;
     }
 
+    /**
+     * Equivalent to calling
+     * {@link RippleDrawable#setColor(ColorStateList)},
+     * on the {@link Drawable} of a given view.
+     * <p>
+     * The operation will be performed on the {@link Drawable} returned by the
+     * target {@link View#getBackground()}.
+     * <p>
+     */
+    private class SetRippleDrawableColor extends Action {
+
+        ColorStateList mColorStateList;
+
+        SetRippleDrawableColor(int id, ColorStateList colorStateList) {
+            this.viewId = id;
+            this.mColorStateList = colorStateList;
+        }
+
+        SetRippleDrawableColor(Parcel parcel) {
+            viewId = parcel.readInt();
+            mColorStateList = parcel.readParcelable(null);
+        }
+
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(viewId);
+            dest.writeParcelable(mColorStateList, 0);
+        }
+
+        @Override
+        public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
+            final View target = root.findViewById(viewId);
+            if (target == null) return;
+
+            // Pick the correct drawable to modify for this view
+            Drawable targetDrawable = target.getBackground();
+
+            if (targetDrawable instanceof RippleDrawable) {
+                ((RippleDrawable) targetDrawable.mutate()).setColor(mColorStateList);
+            }
+        }
+
+        @Override
+        public int getActionTag() {
+            return SET_RIPPLE_DRAWABLE_COLOR_TAG;
+        }
+    }
+
     private final class ViewContentNavigation extends Action {
         final boolean mNext;
 
@@ -2394,6 +2450,8 @@
                 return new LayoutParamAction(parcel);
             case OVERRIDE_TEXT_COLORS_TAG:
                 return new OverrideTextColorsAction(parcel);
+            case SET_RIPPLE_DRAWABLE_COLOR_TAG:
+                return new SetRippleDrawableColor(parcel);
             default:
                 throw new ActionException("Tag " + tag + " not found");
         }
@@ -2855,6 +2913,22 @@
 
     /**
      * @hide
+     * Equivalent to calling
+     * {@link RippleDrawable#setColor(ColorStateList)} on the {@link Drawable} of a given view,
+     * assuming it's a {@link RippleDrawable}.
+     * <p>
+     *
+     * @param viewId The id of the view that contains the target
+     *            {@link RippleDrawable}
+     * @param colorStateList Specify a color for a
+     *            {@link ColorStateList} for this drawable.
+     */
+    public void setRippleDrawableColor(int viewId, ColorStateList colorStateList) {
+        addAction(new SetRippleDrawableColor(viewId, colorStateList));
+    }
+
+    /**
+     * @hide
      * Equivalent to calling {@link android.widget.ProgressBar#setProgressTintList}.
      *
      * @param viewId The id of the view whose tint should change
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9d06680..66809db 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -63,7 +63,7 @@
 import android.graphics.RectF;
 import android.graphics.Typeface;
 import android.graphics.drawable.Drawable;
-import android.graphics.fonts.Font;
+import android.graphics.fonts.FontStyle;
 import android.graphics.fonts.FontVariationAxis;
 import android.icu.text.DecimalFormatSymbols;
 import android.os.AsyncTask;
@@ -2073,7 +2073,7 @@
      */
     private void setTypefaceFromAttrs(@Nullable Typeface typeface, @Nullable String familyName,
             @XMLTypefaceAttr int typefaceIndex, @Typeface.Style int style,
-            @IntRange(from = -1, to = Font.FONT_WEIGHT_MAX) int weight) {
+            @IntRange(from = -1, to = FontStyle.FONT_WEIGHT_MAX) int weight) {
         if (typeface == null && familyName != null) {
             // Lookup normal Typeface from system font map.
             final Typeface normalTypeface = Typeface.create(familyName, Typeface.NORMAL);
@@ -2100,9 +2100,9 @@
     }
 
     private void resolveStyleAndSetTypeface(@NonNull Typeface typeface, @Typeface.Style int style,
-            @IntRange(from = -1, to = Font.FONT_WEIGHT_MAX) int weight) {
+            @IntRange(from = -1, to = FontStyle.FONT_WEIGHT_MAX) int weight) {
         if (weight >= 0) {
-            weight = Math.min(Font.FONT_WEIGHT_MAX, weight);
+            weight = Math.min(FontStyle.FONT_WEIGHT_MAX, weight);
             final boolean italic = (style & Typeface.ITALIC) != 0;
             setTypeface(Typeface.create(typeface, weight, italic));
         } else {
@@ -3517,11 +3517,12 @@
         ColorStateList mTextColorHint = null;
         ColorStateList mTextColorLink = null;
         int mTextSize = -1;
+        LocaleList mTextLocales = null;
         String mFontFamily = null;
         Typeface mFontTypeface = null;
         boolean mFontFamilyExplicit = false;
         int mTypefaceIndex = -1;
-        int mStyleIndex = -1;
+        int mTextStyle = 0;
         int mFontWeight = -1;
         boolean mAllCaps = false;
         int mShadowColor = 0;
@@ -3543,11 +3544,12 @@
                     + "    mTextColorHint:" + mTextColorHint + "\n"
                     + "    mTextColorLink:" + mTextColorLink + "\n"
                     + "    mTextSize:" + mTextSize + "\n"
+                    + "    mTextLocales:" + mTextLocales + "\n"
                     + "    mFontFamily:" + mFontFamily + "\n"
                     + "    mFontTypeface:" + mFontTypeface + "\n"
                     + "    mFontFamilyExplicit:" + mFontFamilyExplicit + "\n"
                     + "    mTypefaceIndex:" + mTypefaceIndex + "\n"
-                    + "    mStyleIndex:" + mStyleIndex + "\n"
+                    + "    mTextStyle:" + mTextStyle + "\n"
                     + "    mFontWeight:" + mFontWeight + "\n"
                     + "    mAllCaps:" + mAllCaps + "\n"
                     + "    mShadowColor:" + mShadowColor + "\n"
@@ -3579,6 +3581,8 @@
                 com.android.internal.R.styleable.TextAppearance_textColorLink);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_textSize,
                 com.android.internal.R.styleable.TextAppearance_textSize);
+        sAppearanceValues.put(com.android.internal.R.styleable.TextView_textLocale,
+                com.android.internal.R.styleable.TextAppearance_textLocale);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_typeface,
                 com.android.internal.R.styleable.TextAppearance_typeface);
         sAppearanceValues.put(com.android.internal.R.styleable.TextView_fontFamily,
@@ -3652,6 +3656,15 @@
                     attributes.mTextSize =
                             appearance.getDimensionPixelSize(attr, attributes.mTextSize);
                     break;
+                case com.android.internal.R.styleable.TextAppearance_textLocale:
+                    final String localeString = appearance.getString(attr);
+                    if (localeString != null) {
+                        final LocaleList localeList = LocaleList.forLanguageTags(localeString);
+                        if (!localeList.isEmpty()) {
+                            attributes.mTextLocales = localeList;
+                        }
+                    }
+                    break;
                 case com.android.internal.R.styleable.TextAppearance_typeface:
                     attributes.mTypefaceIndex = appearance.getInt(attr, attributes.mTypefaceIndex);
                     if (attributes.mTypefaceIndex != -1 && !attributes.mFontFamilyExplicit) {
@@ -3672,7 +3685,7 @@
                     attributes.mFontFamilyExplicit = true;
                     break;
                 case com.android.internal.R.styleable.TextAppearance_textStyle:
-                    attributes.mStyleIndex = appearance.getInt(attr, attributes.mStyleIndex);
+                    attributes.mTextStyle = appearance.getInt(attr, attributes.mTextStyle);
                     break;
                 case com.android.internal.R.styleable.TextAppearance_textFontWeight:
                     attributes.mFontWeight = appearance.getInt(attr, attributes.mFontWeight);
@@ -3738,11 +3751,15 @@
             setRawTextSize(attributes.mTextSize, true /* shouldRequestLayout */);
         }
 
+        if (attributes.mTextLocales != null) {
+            setTextLocales(attributes.mTextLocales);
+        }
+
         if (attributes.mTypefaceIndex != -1 && !attributes.mFontFamilyExplicit) {
             attributes.mFontFamily = null;
         }
         setTypefaceFromAttrs(attributes.mFontTypeface, attributes.mFontFamily,
-                attributes.mTypefaceIndex, attributes.mStyleIndex, attributes.mFontWeight);
+                attributes.mTypefaceIndex, attributes.mTextStyle, attributes.mFontWeight);
 
         if (attributes.mShadowColor != 0) {
             setShadowLayer(attributes.mShadowRadius, attributes.mShadowDx, attributes.mShadowDy,
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 10cf702..c256d57 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -137,7 +137,7 @@
         String pkg = mContext.getOpPackageName();
         TN tn = mTN;
         tn.mNextView = mNextView;
-        final int displayId = mContext.getDisplay().getDisplayId();
+        final int displayId = mContext.getDisplayId();
 
         try {
             service.enqueueToast(pkg, tn, mDuration, displayId);
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index 0f8295a..7c371cb 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -31,6 +31,8 @@
 import android.provider.Settings;
 import android.util.Log;
 
+import com.android.internal.R;
+
 import java.util.ArrayList;
 import java.util.Set;
 
@@ -42,6 +44,14 @@
 
     private static final String TAG = "AssistUtils";
 
+    /**
+     * Sentinel value for "no default assistant specified."
+     *
+     * Empty string is already used to represent an explicit setting of No Assistant. null cannot
+     * be used because we can't represent a null value in XML.
+     */
+    private static final String UNSET = "#+UNSET";
+
     private final Context mContext;
     private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
 
@@ -178,10 +188,21 @@
             return ComponentName.unflattenFromString(setting);
         }
 
+        final String defaultSetting = mContext.getResources().getString(
+                R.string.config_defaultAssistantComponentName);
+        if (defaultSetting != null && !defaultSetting.equals(UNSET)) {
+            return ComponentName.unflattenFromString(defaultSetting);
+        }
+
         // Fallback to keep backward compatible behavior when there is no user setting.
         if (activeServiceSupportsAssistGesture()) {
             return getActiveServiceComponentName();
         }
+
+        if (UNSET.equals(defaultSetting)) {
+            return null;
+        }
+
         final SearchManager searchManager =
                 (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
         if (searchManager == null) {
diff --git a/core/java/com/android/internal/app/ISoundTriggerService.aidl b/core/java/com/android/internal/app/ISoundTriggerService.aidl
index b8a2dff..c0c689c 100644
--- a/core/java/com/android/internal/app/ISoundTriggerService.aidl
+++ b/core/java/com/android/internal/app/ISoundTriggerService.aidl
@@ -52,4 +52,6 @@
 
     /** For both ...Intent and ...Service based usage */
     boolean isRecognitionActive(in ParcelUuid parcelUuid);
+
+    SoundTrigger.RecognitionEvent getModelState(in ParcelUuid parcelUuid);
 }
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 0a812c6..fd38917 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.app;
 
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.annotation.UiThread;
@@ -66,6 +68,7 @@
 import android.widget.ListView;
 import android.widget.TextView;
 import android.widget.Toast;
+
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
@@ -81,8 +84,6 @@
 import java.util.Objects;
 import java.util.Set;
 
-import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-
 /**
  * This activity is displayed when the system attempts to start an Intent for
  * which there is more than one matching activity, allowing the user to decide
@@ -288,6 +289,7 @@
         mTitle = title;
         mDefaultTitleResId = defaultTitleRes;
 
+        mIconFactory = IconDrawableFactory.newInstance(this, true);
         if (configureContentView(mIntents, initialIntents, rList)) {
             return;
         }
@@ -335,7 +337,6 @@
                 : MetricsProto.MetricsEvent.ACTION_SHOW_APP_DISAMBIG_NONE_FEATURED,
                 intent.getAction() + ":" + intent.getType() + ":"
                         + (categories != null ? Arrays.toString(categories.toArray()) : ""));
-        mIconFactory = IconDrawableFactory.newInstance(this, true);
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index a8edfb6..498de53 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -16,12 +16,17 @@
 
 package com.android.internal.app;
 
+import static android.content.res.ResourceId.ID_NULL;
+
 import android.Manifest;
 import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.pm.SuspendDialogInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.util.Slog;
@@ -31,16 +36,19 @@
 
 public class SuspendedAppActivity extends AlertActivity
         implements DialogInterface.OnClickListener {
-    private static final String TAG = "SuspendedAppActivity";
-    public static final String EXTRA_SUSPENDED_PACKAGE =
-            "SuspendedAppActivity.extra.SUSPENDED_PACKAGE";
+    private static final String TAG = SuspendedAppActivity.class.getSimpleName();
+    private static final String PACKAGE_NAME = "com.android.internal.app";
+
+    public static final String EXTRA_SUSPENDED_PACKAGE = PACKAGE_NAME + ".extra.SUSPENDED_PACKAGE";
     public static final String EXTRA_SUSPENDING_PACKAGE =
-            "SuspendedAppActivity.extra.SUSPENDING_PACKAGE";
-    public static final String EXTRA_DIALOG_MESSAGE = "SuspendedAppActivity.extra.DIALOG_MESSAGE";
+            PACKAGE_NAME + ".extra.SUSPENDING_PACKAGE";
+    public static final String EXTRA_DIALOG_INFO = PACKAGE_NAME + ".extra.DIALOG_INFO";
 
     private Intent mMoreDetailsIntent;
     private int mUserId;
     private PackageManager mPm;
+    private Resources mSuspendingAppResources;
+    private SuspendDialogInfo mSuppliedDialogInfo;
 
     private CharSequence getAppLabel(String packageName) {
         try {
@@ -66,6 +74,65 @@
         return null;
     }
 
+    private Drawable resolveIcon() {
+        final int iconId = (mSuppliedDialogInfo != null) ? mSuppliedDialogInfo.getIconResId()
+                : ID_NULL;
+        if (iconId != ID_NULL && mSuspendingAppResources != null) {
+            try {
+                return mSuspendingAppResources.getDrawable(iconId, null);
+            } catch (Resources.NotFoundException nfe) {
+                Slog.e(TAG, "Could not resolve drawable resource id " + iconId);
+            }
+        }
+        return null;
+    }
+
+    private String resolveTitle() {
+        final int titleId = (mSuppliedDialogInfo != null) ? mSuppliedDialogInfo.getTitleResId()
+                : ID_NULL;
+        if (titleId != ID_NULL && mSuspendingAppResources != null) {
+            try {
+                return mSuspendingAppResources.getString(titleId);
+            } catch (Resources.NotFoundException nfe) {
+                Slog.e(TAG, "Could not resolve string resource id " + titleId);
+            }
+        }
+        return getString(R.string.app_suspended_title);
+    }
+
+    private String resolveDialogMessage(String suspendingPkg, String suspendedPkg) {
+        final CharSequence suspendedAppLabel = getAppLabel(suspendedPkg);
+        if (mSuppliedDialogInfo != null) {
+            final int messageId = mSuppliedDialogInfo.getDialogMessageResId();
+            final String message = mSuppliedDialogInfo.getDialogMessage();
+            if (messageId != ID_NULL && mSuspendingAppResources != null) {
+                try {
+                    return mSuspendingAppResources.getString(messageId, suspendedAppLabel);
+                } catch (Resources.NotFoundException nfe) {
+                    Slog.e(TAG, "Could not resolve string resource id " + messageId);
+                }
+            } else if (message != null) {
+                return String.format(getResources().getConfiguration().getLocales().get(0), message,
+                        suspendedAppLabel);
+            }
+        }
+        return getString(R.string.app_suspended_default_message, suspendedAppLabel,
+                getAppLabel(suspendingPkg));
+    }
+
+    private String resolveNeutralButtonText() {
+        final int buttonTextId = (mSuppliedDialogInfo != null)
+                ? mSuppliedDialogInfo.getNeutralButtonTextResId() : ID_NULL;
+        if (buttonTextId != ID_NULL && mSuspendingAppResources != null) {
+            try {
+                return mSuspendingAppResources.getString(buttonTextId);
+            } catch (Resources.NotFoundException nfe) {
+                Slog.e(TAG, "Could not resolve string resource id " + buttonTextId);
+            }
+        }
+        return getString(R.string.app_suspended_more_details);
+    }
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -79,26 +146,26 @@
             finish();
             return;
         }
-        final String suppliedMessage = intent.getStringExtra(EXTRA_DIALOG_MESSAGE);
         final String suspendedPackage = intent.getStringExtra(EXTRA_SUSPENDED_PACKAGE);
         final String suspendingPackage = intent.getStringExtra(EXTRA_SUSPENDING_PACKAGE);
-        final CharSequence suspendedAppLabel = getAppLabel(suspendedPackage);
-        final CharSequence dialogMessage;
-        if (suppliedMessage == null) {
-            dialogMessage = getString(R.string.app_suspended_default_message, suspendedAppLabel,
-                    getAppLabel(suspendingPackage));
-        } else {
-            dialogMessage = String.format(getResources().getConfiguration().getLocales().get(0),
-                    suppliedMessage, suspendedAppLabel);
+        mSuppliedDialogInfo = intent.getParcelableExtra(EXTRA_DIALOG_INFO);
+        if (mSuppliedDialogInfo != null) {
+            try {
+                mSuspendingAppResources = mPm.getResourcesForApplicationAsUser(suspendingPackage,
+                        mUserId);
+            } catch (PackageManager.NameNotFoundException ne) {
+                Slog.e(TAG, "Could not find resources for " + suspendingPackage, ne);
+            }
         }
 
         final AlertController.AlertParams ap = mAlertParams;
-        ap.mTitle = getString(R.string.app_suspended_title);
-        ap.mMessage = dialogMessage;
+        ap.mIcon = resolveIcon();
+        ap.mTitle = resolveTitle();
+        ap.mMessage = resolveDialogMessage(suspendingPackage, suspendedPackage);
         ap.mPositiveButtonText = getString(android.R.string.ok);
         mMoreDetailsIntent = getMoreDetailsActivity(suspendingPackage, suspendedPackage, mUserId);
         if (mMoreDetailsIntent != null) {
-            ap.mNeutralButtonText = getString(R.string.app_suspended_more_details);
+            ap.mNeutralButtonText = resolveNeutralButtonText();
         }
         ap.mPositiveButtonListener = ap.mNeutralButtonListener = this;
         setupAlert();
@@ -116,11 +183,11 @@
     }
 
     public static Intent createSuspendedAppInterceptIntent(String suspendedPackage,
-            String suspendingPackage, String dialogMessage, int userId) {
+            String suspendingPackage, SuspendDialogInfo dialogInfo, int userId) {
         return new Intent()
                 .setClassName("android", SuspendedAppActivity.class.getName())
                 .putExtra(EXTRA_SUSPENDED_PACKAGE, suspendedPackage)
-                .putExtra(EXTRA_DIALOG_MESSAGE, dialogMessage)
+                .putExtra(EXTRA_DIALOG_INFO, dialogInfo)
                 .putExtra(EXTRA_SUSPENDING_PACKAGE, suspendingPackage)
                 .putExtra(Intent.EXTRA_USER_ID, userId)
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index c388148..fee8345 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -171,8 +171,7 @@
             boolean debuggable);
 
     private native static int nativeCopyNativeBinaries(long handle, String sharedLibraryPath,
-            String abiToCopy, boolean extractNativeLibs, boolean hasNativeBridge,
-            boolean debuggable);
+            String abiToCopy, boolean extractNativeLibs, boolean debuggable);
 
     private static long sumNativeBinaries(Handle handle, String abi) {
         long sum = 0;
@@ -193,7 +192,7 @@
     public static int copyNativeBinaries(Handle handle, File sharedLibraryDir, String abi) {
         for (long apkHandle : handle.apkHandles) {
             int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi,
-                    handle.extractNativeLibs, HAS_NATIVE_BRIDGE, handle.debuggable);
+                    handle.extractNativeLibs, handle.debuggable);
             if (res != INSTALL_SUCCEEDED) {
                 return res;
             }
@@ -448,9 +447,6 @@
     // We don't care about the other return values for now.
     private static final int BITCODE_PRESENT = 1;
 
-    private static final boolean HAS_NATIVE_BRIDGE =
-            !"0".equals(SystemProperties.get("ro.dalvik.vm.native.bridge", "0"));
-
     private static native int hasRenderscriptBitcode(long apkHandle);
 
     public static boolean hasRenderscriptBitcode(Handle handle) throws IOException {
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
index 0080ace..d4c451e 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -72,7 +72,8 @@
     }
 
     public boolean wakeLockScreenGestureAvailable() {
-        return !TextUtils.isEmpty(wakeLockScreenSensorType());
+        return mContext.getResources()
+                .getBoolean(R.bool.config_dozeWakeLockScreenSensorAvailable);
     }
 
     public boolean wakeScreenGestureEnabled(int user) {
@@ -92,10 +93,6 @@
         return mContext.getResources().getString(R.string.config_dozeLongPressSensorType);
     }
 
-    public String wakeLockScreenSensorType() {
-        return mContext.getResources().getString(R.string.config_dozeWakeLockScreenSensorType);
-    }
-
     public String wakeScreenSensorType() {
         return mContext.getResources().getString(R.string.config_dozeWakeScreenSensorType);
     }
diff --git a/core/java/com/android/internal/inputmethod/InputMethodDebug.java b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
new file mode 100644
index 0000000..a5dc3d1
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/InputMethodDebug.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.inputmethod;
+
+import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
+
+/**
+ * Provides useful methods for debugging.
+ */
+public final class InputMethodDebug {
+    /**
+     * Not intended to be instantiated.
+     */
+    private InputMethodDebug() {
+    }
+
+    /**
+     * Converts {@link StartInputReason} to {@link String} for debug logging.
+     *
+     * @param reason integer constant for {@link StartInputReason}.
+     * @return {@link String} message corresponds for the given {@code reason}.
+     */
+    public static String startInputReasonToString(@StartInputReason int reason) {
+        switch (reason) {
+            case StartInputReason.UNSPECIFIED:
+                return "UNSPECIFIED";
+            case StartInputReason.WINDOW_FOCUS_GAIN:
+                return "WINDOW_FOCUS_GAIN";
+            case StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY:
+                return "WINDOW_FOCUS_GAIN_REPORT_ONLY";
+            case StartInputReason.APP_CALLED_RESTART_INPUT_API:
+                return "APP_CALLED_RESTART_INPUT_API";
+            case StartInputReason.CHECK_FOCUS:
+                return "CHECK_FOCUS";
+            case StartInputReason.BOUND_TO_IMMS:
+                return "BOUND_TO_IMMS";
+            case StartInputReason.UNBOUND_FROM_IMMS:
+                return "UNBOUND_FROM_IMMS";
+            case StartInputReason.ACTIVATED_BY_IMMS:
+                return "ACTIVATED_BY_IMMS";
+            case StartInputReason.DEACTIVATED_BY_IMMS:
+                return "DEACTIVATED_BY_IMMS";
+            case StartInputReason.SESSION_CREATED_BY_IME:
+                return "SESSION_CREATED_BY_IME";
+            default:
+                return "Unknown=" + reason;
+        }
+    }
+
+    /**
+     * Converts {@link UnbindReason} to {@link String} for debug logging.
+     *
+     * @param reason integer constant for {@link UnbindReason}.
+     * @return {@link String} message corresponds for the given {@code reason}.
+     */
+    public static String unbindReasonToString(@UnbindReason int reason) {
+        switch (reason) {
+            case UnbindReason.UNSPECIFIED:
+                return "UNSPECIFIED";
+            case UnbindReason.SWITCH_CLIENT:
+                return "SWITCH_CLIENT";
+            case UnbindReason.SWITCH_IME:
+                return "SWITCH_IME";
+            case UnbindReason.DISCONNECT_IME:
+                return "DISCONNECT_IME";
+            case UnbindReason.NO_IME:
+                return "NO_IME";
+            case UnbindReason.SWITCH_IME_FAILED:
+                return "SWITCH_IME_FAILED";
+            case UnbindReason.SWITCH_USER:
+                return "SWITCH_USER";
+            default:
+                return "Unknown=" + reason;
+        }
+    }
+
+    /**
+     * Converts {@link SoftInputModeFlags} to {@link String} for debug logging.
+     *
+     * @param softInputMode integer constant for {@link SoftInputModeFlags}.
+     * @return {@link String} message corresponds for the given {@code softInputMode}.
+     */
+    public static String softInputModeToString(@SoftInputModeFlags int softInputMode) {
+        final StringBuilder sb = new StringBuilder();
+        final int state = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE;
+        final int adjust = softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+        final boolean isForwardNav =
+                (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0;
+
+        switch (state) {
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
+                sb.append("STATE_UNSPECIFIED");
+                break;
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
+                sb.append("STATE_UNCHANGED");
+                break;
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
+                sb.append("STATE_HIDDEN");
+                break;
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
+                sb.append("STATE_ALWAYS_HIDDEN");
+                break;
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
+                sb.append("STATE_VISIBLE");
+                break;
+            case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
+                sb.append("STATE_ALWAYS_VISIBLE");
+                break;
+            default:
+                sb.append("STATE_UNKNOWN(");
+                sb.append(state);
+                sb.append(")");
+                break;
+        }
+
+        switch (adjust) {
+            case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED:
+                sb.append("|ADJUST_UNSPECIFIED");
+                break;
+            case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE:
+                sb.append("|ADJUST_RESIZE");
+                break;
+            case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN:
+                sb.append("|ADJUST_PAN");
+                break;
+            case WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING:
+                sb.append("|ADJUST_NOTHING");
+                break;
+            default:
+                sb.append("|ADJUST_UNKNOWN(");
+                sb.append(adjust);
+                sb.append(")");
+                break;
+        }
+
+        if (isForwardNav) {
+            // This is a special bit that is set by the system only during the window navigation.
+            sb.append("|IS_FORWARD_NAVIGATION");
+        }
+
+        return sb.toString();
+    }
+}
diff --git a/core/java/com/android/internal/inputmethod/StartInputReason.java b/core/java/com/android/internal/inputmethod/StartInputReason.java
new file mode 100644
index 0000000..a01c459
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/StartInputReason.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.inputmethod;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Describes the reason why {@link android.view.inputmethod.InputMethodManager} is calling
+ * {@link com.android.internal.view.IInputMethodManager#startInputOrWindowGainedFocus}.
+ */
+@Retention(SOURCE)
+@IntDef(value = {
+        StartInputReason.UNSPECIFIED,
+        StartInputReason.WINDOW_FOCUS_GAIN,
+        StartInputReason.WINDOW_FOCUS_GAIN_REPORT_ONLY,
+        StartInputReason.APP_CALLED_RESTART_INPUT_API,
+        StartInputReason.CHECK_FOCUS,
+        StartInputReason.BOUND_TO_IMMS,
+        StartInputReason.UNBOUND_FROM_IMMS,
+        StartInputReason.ACTIVATED_BY_IMMS,
+        StartInputReason.DEACTIVATED_BY_IMMS,
+        StartInputReason.SESSION_CREATED_BY_IME})
+public @interface StartInputReason {
+    /**
+     * Reason is not specified.
+     */
+    int UNSPECIFIED = 0;
+    /**
+     * {@link android.view.Window} gained focus and it made the focused {@link android.view.View}
+     * to (re)start a new connection.
+     */
+    int WINDOW_FOCUS_GAIN = 1;
+    /**
+     * {@link android.view.Window} gained focus but there is no {@link android.view.View} that is
+     * eligible to have IME focus. {@link android.view.inputmethod.InputMethodManager} just reports
+     * this window focus change event.
+     */
+    int WINDOW_FOCUS_GAIN_REPORT_ONLY = 2;
+    /**
+     * {@link android.view.inputmethod.InputMethodManager#restartInput(android.view.View)} is
+     * either explicitly called by the application or indirectly called by some Framework class
+     * (e.g. {@link android.widget.EditText}).
+     */
+    int APP_CALLED_RESTART_INPUT_API = 3;
+    /**
+     * {@link android.view.View} requested a new connection because of view focus change.
+     */
+    int CHECK_FOCUS = 4;
+    /**
+     * {@link android.view.inputmethod.InputMethodManager} is responding to
+     * {@link com.android.internal.view.IInputMethodClient#onBindMethod}.
+     */
+    int BOUND_TO_IMMS = 5;
+    /**
+     * {@link android.view.inputmethod.InputMethodManager} is responding to
+     * {@link com.android.internal.view.IInputMethodClient#onUnbindMethod}.
+     */
+    int UNBOUND_FROM_IMMS = 6;
+    /**
+     * {@link android.view.inputmethod.InputMethodManager} is responding to
+     * {@link com.android.internal.view.IInputMethodClient#setActive}.
+     */
+    int ACTIVATED_BY_IMMS = 7;
+    /**
+     * {@link android.view.inputmethod.InputMethodManager} is responding to
+     * {@link com.android.internal.view.IInputMethodClient#setActive}.
+     */
+    int DEACTIVATED_BY_IMMS = 8;
+    /**
+     * {@link com.android.server.inputmethod.InputMethodManagerService} is responding to
+     * {@link com.android.internal.view.IInputSessionCallback#sessionCreated}.
+     */
+    int SESSION_CREATED_BY_IME = 9;
+}
diff --git a/core/java/com/android/internal/inputmethod/UnbindReason.java b/core/java/com/android/internal/inputmethod/UnbindReason.java
new file mode 100644
index 0000000..f0f18f1
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/UnbindReason.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.inputmethod;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Describes the reason why {@link com.android.server.inputmethod.InputMethodManagerService} is
+ * calling {@link com.android.internal.view.IInputMethodClient#onUnbindMethod}.
+ */
+@Retention(SOURCE)
+@IntDef(value = {
+        UnbindReason.UNSPECIFIED,
+        UnbindReason.SWITCH_CLIENT,
+        UnbindReason.SWITCH_IME,
+        UnbindReason.DISCONNECT_IME,
+        UnbindReason.NO_IME,
+        UnbindReason.SWITCH_IME_FAILED,
+        UnbindReason.SWITCH_USER})
+public @interface UnbindReason {
+    /**
+     * Reason is not specified.
+     */
+    int UNSPECIFIED = 0;
+    /**
+     * When a new IME client becomes active, the previous IME client will unbound from the current
+     * IME.
+     */
+    int SWITCH_CLIENT = 1;
+    /**
+     * Before a new IME becomes active, the current IME client be unbound from the previous IME.
+     */
+    int SWITCH_IME = 2;
+    /**
+     * When the current IME is disconnected, the current IME client will be unbound.
+     */
+    int DISCONNECT_IME = 3;
+    /**
+     * When the system loses the last enabled IME, the current IME client will be unbound.
+     */
+    int NO_IME = 4;
+    /**
+     * When the system failed to switch to another IME, the current IME client will be unbound.
+     */
+    int SWITCH_IME_FAILED = 5;
+    /**
+     * When a new user becomes foreground, the previous IME client will be unbound from the previous
+     * user's active IME.
+     */
+    int SWITCH_USER = 6;
+}
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index e99e39e..c4aa1d7 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.metrics.LogMaker;
 import android.os.Build;
+import android.util.StatsLog;
 import android.view.View;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -41,8 +42,11 @@
         return sMetricsLogger;
     }
 
-    protected void saveLog(Object[] rep) {
-        EventLogTags.writeSysuiMultiAction(rep);
+    protected void saveLog(LogMaker log) {
+        // TODO(b/116684537): Flag guard logging to event log and statsd socket.
+        EventLogTags.writeSysuiMultiAction(log.serialize());
+        StatsLog.write(StatsLog.KEY_VALUE_PAIRS_ATOM, /* UID is retrieved from statsd side */ 0,
+                log.getEntries());
     }
 
     public static final int VIEW_UNKNOWN = MetricsEvent.VIEW_UNKNOWN;
@@ -53,7 +57,7 @@
         if (content.getType() == MetricsEvent.TYPE_UNKNOWN) {
             content.setType(MetricsEvent.TYPE_ACTION);
         }
-        saveLog(content.serialize());
+        saveLog(content);
     }
 
     public void visible(int category) throws IllegalArgumentException {
@@ -61,9 +65,7 @@
             throw new IllegalArgumentException("Must define metric category");
         }
         EventLogTags.writeSysuiViewVisibility(category, 100);
-        saveLog(new LogMaker(category)
-                        .setType(MetricsEvent.TYPE_OPEN)
-                        .serialize());
+        saveLog(new LogMaker(category).setType(MetricsEvent.TYPE_OPEN));
     }
 
     public void hidden(int category) throws IllegalArgumentException {
@@ -71,9 +73,7 @@
             throw new IllegalArgumentException("Must define metric category");
         }
         EventLogTags.writeSysuiViewVisibility(category, 0);
-        saveLog(new LogMaker(category)
-                        .setType(MetricsEvent.TYPE_CLOSE)
-                        .serialize());
+        saveLog(new LogMaker(category).setType(MetricsEvent.TYPE_CLOSE));
     }
 
     public void visibility(int category, boolean visibile)
@@ -92,25 +92,17 @@
 
     public void action(int category) {
         EventLogTags.writeSysuiAction(category, "");
-        saveLog(new LogMaker(category)
-                        .setType(MetricsEvent.TYPE_ACTION)
-                        .serialize());
+        saveLog(new LogMaker(category).setType(MetricsEvent.TYPE_ACTION));
     }
 
     public void action(int category, int value) {
         EventLogTags.writeSysuiAction(category, Integer.toString(value));
-        saveLog(new LogMaker(category)
-                        .setType(MetricsEvent.TYPE_ACTION)
-                        .setSubtype(value)
-                        .serialize());
+        saveLog(new LogMaker(category).setType(MetricsEvent.TYPE_ACTION).setSubtype(value));
     }
 
     public void action(int category, boolean value) {
         EventLogTags.writeSysuiAction(category, Boolean.toString(value));
-        saveLog(new LogMaker(category)
-                        .setType(MetricsEvent.TYPE_ACTION)
-                        .setSubtype(value ? 1 : 0)
-                        .serialize());
+        saveLog(new LogMaker(category).setType(MetricsEvent.TYPE_ACTION).setSubtype(value ? 1 : 0));
     }
 
     public void action(int category, String pkg) {
@@ -118,19 +110,15 @@
             throw new IllegalArgumentException("Must define metric category");
         }
         EventLogTags.writeSysuiAction(category, pkg);
-        saveLog(new LogMaker(category)
-                .setType(MetricsEvent.TYPE_ACTION)
-                .setPackageName(pkg)
-                .serialize());
+        saveLog(new LogMaker(category).setType(MetricsEvent.TYPE_ACTION).setPackageName(pkg));
     }
 
     /** Add an integer value to the monotonically increasing counter with the given name. */
     public void count(String name, int value) {
         EventLogTags.writeSysuiCount(name, value);
         saveLog(new LogMaker(MetricsEvent.RESERVED_FOR_LOGBUILDER_COUNTER)
-                        .setCounterName(name)
-                        .setCounterValue(value)
-                        .serialize());
+                    .setCounterName(name)
+                    .setCounterValue(value));
     }
 
     /** Increment the bucket with the integer label on the histogram with the given name. */
@@ -138,10 +126,9 @@
         // see LogHistogram in system/core/libmetricslogger/metrics_logger.cpp
         EventLogTags.writeSysuiHistogram(name, bucket);
         saveLog(new LogMaker(MetricsEvent.RESERVED_FOR_LOGBUILDER_HISTOGRAM)
-                        .setCounterName(name)
-                        .setCounterBucket(bucket)
-                        .setCounterValue(1)
-                        .serialize());
+                    .setCounterName(name)
+                    .setCounterBucket(bucket)
+                    .setCounterValue(1));
     }
 
     /** @deprecated use {@link #visible(int)} */
diff --git a/core/java/com/android/internal/logging/testing/FakeMetricsLogger.java b/core/java/com/android/internal/logging/testing/FakeMetricsLogger.java
index fbaf87a..6786427 100644
--- a/core/java/com/android/internal/logging/testing/FakeMetricsLogger.java
+++ b/core/java/com/android/internal/logging/testing/FakeMetricsLogger.java
@@ -16,8 +16,8 @@
     private Queue<LogMaker> logs = new LinkedList<>();
 
     @Override
-    protected void saveLog(Object[] rep) {
-        logs.offer(new LogMaker(rep));
+    protected void saveLog(LogMaker log) {
+        logs.offer(log);
     }
 
     public Queue<LogMaker> getLogs() {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 33b9ff7..017da55 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -5330,6 +5330,7 @@
                 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
                         + Integer.toHexString(mHistoryCur.states));
                 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
+                StatsLog.write(StatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin);
             }
         }
 
@@ -5341,6 +5342,7 @@
                         + Integer.toHexString(mHistoryCur.states));
                 newHistory = true;
                 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
+                StatsLog.write(StatsLog.PHONE_SERVICE_STATE_CHANGED, state, simState, strengthBin);
             }
         }
 
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 46667d1..2442d0b 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -158,7 +158,7 @@
                                          PROC_WAKELOCKS_FORMAT,
                         nameStringArray, wlData, null);
 
-                name = nameStringArray[0];
+                name = nameStringArray[0].trim();
                 count = (int) wlData[1];
 
                 if (wakeup_sources) {
diff --git a/core/java/com/android/internal/os/LooperStats.java b/core/java/com/android/internal/os/LooperStats.java
index e4724ff..2b661c2 100644
--- a/core/java/com/android/internal/os/LooperStats.java
+++ b/core/java/com/android/internal/os/LooperStats.java
@@ -49,6 +49,7 @@
     private final int mEntriesSizeCap;
     private int mSamplingInterval;
     private CachedDeviceState.Readonly mDeviceState;
+    private long mStartTime = System.currentTimeMillis();
 
     public LooperStats(int samplingInterval, int entriesSizeCap) {
         this.mSamplingInterval = samplingInterval;
@@ -66,6 +67,7 @@
             session = session == null ? new DispatchSession() : session;
             session.startTimeMicro = getElapsedRealtimeMicro();
             session.cpuStartMicro = getThreadTimeMicro();
+            session.systemUptimeMillis = getSystemUptimeMillis();
             return session;
         }
 
@@ -85,12 +87,18 @@
                 entry.messageCount++;
                 if (session != DispatchSession.NOT_SAMPLED) {
                     entry.recordedMessageCount++;
-                    long latency = getElapsedRealtimeMicro() - session.startTimeMicro;
-                    long cpuUsage = getThreadTimeMicro() - session.cpuStartMicro;
+                    final long latency = getElapsedRealtimeMicro() - session.startTimeMicro;
+                    final long cpuUsage = getThreadTimeMicro() - session.cpuStartMicro;
                     entry.totalLatencyMicro += latency;
                     entry.maxLatencyMicro = Math.max(entry.maxLatencyMicro, latency);
                     entry.cpuUsageMicro += cpuUsage;
                     entry.maxCpuUsageMicro = Math.max(entry.maxCpuUsageMicro, cpuUsage);
+                    if (msg.getWhen() > 0) {
+                        final long delay = Math.max(0L, session.systemUptimeMillis - msg.getWhen());
+                        entry.delayMillis += delay;
+                        entry.maxDelayMillis = Math.max(entry.maxDelayMillis, delay);
+                        entry.recordedDelayMessageCount++;
+                    }
                 }
             }
         }
@@ -137,6 +145,11 @@
         return exportedEntries;
     }
 
+    /** Returns a timestamp indicating when the statistics were last reset. */
+    public long getStartTimeMillis() {
+        return mStartTime;
+    }
+
     private void maybeAddSpecialEntry(List<ExportedEntry> exportedEntries, Entry specialEntry) {
         synchronized (specialEntry) {
             if (specialEntry.messageCount > 0 || specialEntry.exceptionCount > 0) {
@@ -156,6 +169,7 @@
         synchronized (mOverflowEntry) {
             mOverflowEntry.reset();
         }
+        mStartTime = System.currentTimeMillis();
     }
 
     public void setSamplingInterval(int samplingInterval) {
@@ -206,6 +220,10 @@
         return SystemClock.elapsedRealtimeNanos() / 1000;
     }
 
+    protected long getSystemUptimeMillis() {
+        return SystemClock.uptimeMillis();
+    }
+
     protected boolean shouldCollectDetailedData() {
         return ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0;
     }
@@ -214,6 +232,7 @@
         static final DispatchSession NOT_SAMPLED = new DispatchSession();
         public long startTimeMicro;
         public long cpuStartMicro;
+        public long systemUptimeMillis;
     }
 
     private static class Entry {
@@ -228,6 +247,9 @@
         public long maxLatencyMicro;
         public long cpuUsageMicro;
         public long maxCpuUsageMicro;
+        public long recordedDelayMessageCount;
+        public long delayMillis;
+        public long maxDelayMillis;
 
         Entry(Message msg, boolean isInteractive) {
             this.workSourceUid = msg.workSourceUid;
@@ -251,6 +273,9 @@
             maxLatencyMicro = 0;
             cpuUsageMicro = 0;
             maxCpuUsageMicro = 0;
+            delayMillis = 0;
+            maxDelayMillis = 0;
+            recordedDelayMessageCount = 0;
         }
 
         static int idFor(Message msg, boolean isInteractive) {
@@ -281,6 +306,9 @@
         public final long maxLatencyMicros;
         public final long cpuUsageMicros;
         public final long maxCpuUsageMicros;
+        public final long maxDelayMillis;
+        public final long delayMillis;
+        public final long recordedDelayMessageCount;
 
         ExportedEntry(Entry entry) {
             this.workSourceUid = entry.workSourceUid;
@@ -301,6 +329,9 @@
             this.maxLatencyMicros = entry.maxLatencyMicro;
             this.cpuUsageMicros = entry.cpuUsageMicro;
             this.maxCpuUsageMicros = entry.maxCpuUsageMicro;
+            this.delayMillis = entry.delayMillis;
+            this.maxDelayMillis = entry.maxDelayMillis;
+            this.recordedDelayMessageCount = entry.recordedDelayMessageCount;
         }
     }
 }
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 997b722..8338d78 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.XmlUtils;
@@ -501,4 +502,181 @@
     public double getBatteryCapacity() {
         return getAveragePower(POWER_BATTERY_CAPACITY);
     }
+
+    /**
+     * Dump power constants into PowerProfileProto
+     */
+    public void writeToProto(ProtoOutputStream proto) {
+        // cpu.suspend
+        writePowerConstantToProto(proto, POWER_CPU_SUSPEND, PowerProfileProto.CPU_SUSPEND);
+
+        // cpu.idle
+        writePowerConstantToProto(proto, POWER_CPU_IDLE, PowerProfileProto.CPU_IDLE);
+
+        // cpu.active
+        writePowerConstantToProto(proto, POWER_CPU_ACTIVE, PowerProfileProto.CPU_ACTIVE);
+
+        // cpu.clusters.cores
+        // cpu.cluster_power.cluster
+        // cpu.core_speeds.cluster
+        // cpu.core_power.cluster
+        for (int cluster = 0; cluster < mCpuClusters.length; cluster++) {
+            final long token = proto.start(PowerProfileProto.CPU_CLUSTER);
+            proto.write(PowerProfileProto.CpuCluster.ID, cluster);
+            proto.write(PowerProfileProto.CpuCluster.CLUSTER_POWER,
+                    sPowerItemMap.get(mCpuClusters[cluster].clusterPowerKey));
+            proto.write(PowerProfileProto.CpuCluster.CORES, mCpuClusters[cluster].numCpus);
+            for (Double speed : sPowerArrayMap.get(mCpuClusters[cluster].freqKey)) {
+                proto.write(PowerProfileProto.CpuCluster.SPEED, speed);
+            }
+            for (Double corePower : sPowerArrayMap.get(mCpuClusters[cluster].corePowerKey)) {
+                proto.write(PowerProfileProto.CpuCluster.CORE_POWER, corePower);
+            }
+            proto.end(token);
+        }
+
+        // wifi.scan
+        writePowerConstantToProto(proto, POWER_WIFI_SCAN, PowerProfileProto.WIFI_SCAN);
+
+        // wifi.on
+        writePowerConstantToProto(proto, POWER_WIFI_ON, PowerProfileProto.WIFI_ON);
+
+        // wifi.active
+        writePowerConstantToProto(proto, POWER_WIFI_ACTIVE, PowerProfileProto.WIFI_ACTIVE);
+
+        // wifi.controller.idle
+        writePowerConstantToProto(proto, POWER_WIFI_CONTROLLER_IDLE,
+                PowerProfileProto.WIFI_CONTROLLER_IDLE);
+
+        // wifi.controller.rx
+        writePowerConstantToProto(proto, POWER_WIFI_CONTROLLER_RX,
+                PowerProfileProto.WIFI_CONTROLLER_RX);
+
+        // wifi.controller.tx
+        writePowerConstantToProto(proto, POWER_WIFI_CONTROLLER_TX,
+                PowerProfileProto.WIFI_CONTROLLER_TX);
+
+        // wifi.controller.tx_levels
+        writePowerConstantArrayToProto(proto, POWER_WIFI_CONTROLLER_TX_LEVELS,
+                PowerProfileProto.WIFI_CONTROLLER_TX_LEVELS);
+
+        // wifi.controller.voltage
+        writePowerConstantToProto(proto, POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE,
+                PowerProfileProto.WIFI_CONTROLLER_OPERATING_VOLTAGE);
+
+        // bluetooth.controller.idle
+        writePowerConstantToProto(proto, POWER_BLUETOOTH_CONTROLLER_IDLE,
+                PowerProfileProto.BLUETOOTH_CONTROLLER_IDLE);
+
+        // bluetooth.controller.rx
+        writePowerConstantToProto(proto, POWER_BLUETOOTH_CONTROLLER_RX,
+                PowerProfileProto.BLUETOOTH_CONTROLLER_RX);
+
+        // bluetooth.controller.tx
+        writePowerConstantToProto(proto, POWER_BLUETOOTH_CONTROLLER_TX,
+                PowerProfileProto.BLUETOOTH_CONTROLLER_TX);
+
+        // bluetooth.controller.voltage
+        writePowerConstantToProto(proto, POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE,
+                PowerProfileProto.BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE);
+
+        // modem.controller.sleep
+        writePowerConstantToProto(proto, POWER_MODEM_CONTROLLER_SLEEP,
+                PowerProfileProto.MODEM_CONTROLLER_SLEEP);
+
+        // modem.controller.idle
+        writePowerConstantToProto(proto, POWER_MODEM_CONTROLLER_IDLE,
+                PowerProfileProto.MODEM_CONTROLLER_IDLE);
+
+        // modem.controller.rx
+        writePowerConstantToProto(proto, POWER_MODEM_CONTROLLER_RX,
+                PowerProfileProto.MODEM_CONTROLLER_RX);
+
+        // modem.controller.tx
+        writePowerConstantArrayToProto(proto, POWER_MODEM_CONTROLLER_TX,
+                PowerProfileProto.MODEM_CONTROLLER_TX);
+
+        // modem.controller.voltage
+        writePowerConstantToProto(proto, POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE,
+                PowerProfileProto.MODEM_CONTROLLER_OPERATING_VOLTAGE);
+
+        // gps.on
+        writePowerConstantToProto(proto, POWER_GPS_ON, PowerProfileProto.GPS_ON);
+
+        // gps.signalqualitybased
+        writePowerConstantArrayToProto(proto, POWER_GPS_SIGNAL_QUALITY_BASED,
+                PowerProfileProto.GPS_SIGNAL_QUALITY_BASED);
+
+        // gps.voltage
+        writePowerConstantToProto(proto, POWER_GPS_OPERATING_VOLTAGE,
+                PowerProfileProto.GPS_OPERATING_VOLTAGE);
+
+        // bluetooth.on
+        writePowerConstantToProto(proto, POWER_BLUETOOTH_ON, PowerProfileProto.BLUETOOTH_ON);
+
+        // bluetooth.active
+        writePowerConstantToProto(proto, POWER_BLUETOOTH_ACTIVE,
+                PowerProfileProto.BLUETOOTH_ACTIVE);
+
+        // bluetooth.at
+        writePowerConstantToProto(proto, POWER_BLUETOOTH_AT_CMD,
+                PowerProfileProto.BLUETOOTH_AT_CMD);
+
+        // ambient.on
+        writePowerConstantToProto(proto, POWER_AMBIENT_DISPLAY, PowerProfileProto.AMBIENT_DISPLAY);
+
+        // screen.on
+        writePowerConstantToProto(proto, POWER_SCREEN_ON, PowerProfileProto.SCREEN_ON);
+
+        // radio.on
+        writePowerConstantToProto(proto, POWER_RADIO_ON, PowerProfileProto.RADIO_ON);
+
+        // radio.scanning
+        writePowerConstantToProto(proto, POWER_RADIO_SCANNING, PowerProfileProto.RADIO_SCANNING);
+
+        // radio.active
+        writePowerConstantToProto(proto, POWER_RADIO_ACTIVE, PowerProfileProto.RADIO_ACTIVE);
+
+        // screen.full
+        writePowerConstantToProto(proto, POWER_SCREEN_FULL, PowerProfileProto.SCREEN_FULL);
+
+        // audio
+        writePowerConstantToProto(proto, POWER_AUDIO, PowerProfileProto.AUDIO);
+
+        // video
+        writePowerConstantToProto(proto, POWER_VIDEO, PowerProfileProto.VIDEO);
+
+        // camera.flashlight
+        writePowerConstantToProto(proto, POWER_FLASHLIGHT, PowerProfileProto.FLASHLIGHT);
+
+        // memory.bandwidths
+        writePowerConstantToProto(proto, POWER_MEMORY, PowerProfileProto.MEMORY);
+
+        // camera.avg
+        writePowerConstantToProto(proto, POWER_CAMERA, PowerProfileProto.CAMERA);
+
+        // wifi.batchedscan
+        writePowerConstantToProto(proto, POWER_WIFI_BATCHED_SCAN,
+                PowerProfileProto.WIFI_BATCHED_SCAN);
+
+        // battery.capacity
+        writePowerConstantToProto(proto, POWER_BATTERY_CAPACITY,
+                PowerProfileProto.BATTERY_CAPACITY);
+    }
+
+    // Writes items in sPowerItemMap to proto if exists.
+    private void writePowerConstantToProto(ProtoOutputStream proto, String key, long fieldId) {
+        if (sPowerItemMap.containsKey(key)) {
+            proto.write(fieldId, sPowerItemMap.get(key));
+        }
+    }
+
+    // Writes items in sPowerArrayMap to proto if exists.
+    private void writePowerConstantArrayToProto(ProtoOutputStream proto, String key, long fieldId) {
+        if (sPowerArrayMap.containsKey(key)) {
+            for (Double d : sPowerArrayMap.get(key)) {
+                proto.write(fieldId, d);
+            }
+        }
+    }
 }
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index bf31c7d..1ee4269 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -29,7 +29,6 @@
 import com.android.internal.util.FastPrintWriter;
 
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.File;
 import java.io.FileInputStream;
diff --git a/core/java/com/android/internal/policy/BackdropFrameRenderer.java b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
index a70209c..f14007b 100644
--- a/core/java/com/android/internal/policy/BackdropFrameRenderer.java
+++ b/core/java/com/android/internal/policy/BackdropFrameRenderer.java
@@ -16,13 +16,13 @@
 
 package com.android.internal.policy;
 
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.RenderNode;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Looper;
 import android.view.Choreographer;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 import android.view.ThreadedRenderer;
 
 /**
@@ -339,7 +339,7 @@
         mFrameAndBackdropNode.setLeftTopRightBottom(left, top, left + width, top + height);
 
         // Draw the caption and content backdrops in to our render node.
-        DisplayListCanvas canvas = mFrameAndBackdropNode.start(width, height);
+        RecordingCanvas canvas = mFrameAndBackdropNode.start(width, height);
         final Drawable drawable = mUserCaptionBackgroundDrawable != null
                 ? mUserCaptionBackgroundDrawable : mCaptionBackgroundDrawable;
 
@@ -368,7 +368,7 @@
         if (mSystemBarBackgroundNode == null) {
             return;
         }
-        DisplayListCanvas canvas = mSystemBarBackgroundNode.start(width, height);
+        RecordingCanvas canvas = mSystemBarBackgroundNode.start(width, height);
         mSystemBarBackgroundNode.setLeftTopRightBottom(left, top, left + width, top + height);
         final int topInset = DecorView.getColorViewTopInset(mStableInsets.top, mSystemInsets.top);
         if (mStatusBarColor != null) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 4697266..94140ab 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -16,76 +16,6 @@
 
 package com.android.internal.policy;
 
-import android.annotation.Nullable;
-import android.annotation.TestApi;
-import android.app.WindowConfiguration;
-import android.graphics.Outline;
-import android.graphics.drawable.InsetDrawable;
-import android.graphics.drawable.LayerDrawable;
-import android.util.Pair;
-import android.view.ViewOutlineProvider;
-import android.view.accessibility.AccessibilityNodeInfo;
-import com.android.internal.R;
-import com.android.internal.policy.PhoneWindow.PanelFeatureState;
-import com.android.internal.policy.PhoneWindow.PhoneWindowMenuCallback;
-import com.android.internal.view.FloatingActionMode;
-import com.android.internal.view.RootViewSurfaceTaker;
-import com.android.internal.view.StandaloneActionMode;
-import com.android.internal.view.menu.ContextMenuBuilder;
-import com.android.internal.view.menu.MenuHelper;
-import com.android.internal.widget.ActionBarContextView;
-import com.android.internal.widget.BackgroundFallback;
-import com.android.internal.widget.DecorCaptionView;
-import com.android.internal.widget.FloatingToolbar;
-
-import java.util.List;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.LinearGradient;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.Region;
-import android.graphics.Shader;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.TypedValue;
-import android.view.ActionMode;
-import android.view.ContextThemeWrapper;
-import android.view.DisplayListCanvas;
-import android.view.Gravity;
-import android.view.InputQueue;
-import android.view.KeyEvent;
-import android.view.KeyboardShortcutGroup;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.MotionEvent;
-import android.view.ThreadedRenderer;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewStub;
-import android.view.ViewTreeObserver;
-import android.view.Window;
-import android.view.WindowCallbacks;
-import android.view.WindowInsets;
-import android.view.WindowManager;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-import android.widget.FrameLayout;
-import android.widget.PopupWindow;
-
 import static android.app.WindowConfiguration.PINNED_WINDOWING_MODE_ELEVATION_IN_DIP;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
@@ -108,8 +38,79 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_DRAWN_APPLICATION;
+
 import static com.android.internal.policy.PhoneWindow.FEATURE_OPTIONS_PANEL;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.app.WindowConfiguration;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.LinearGradient;
+import android.graphics.Outline;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.RecordingCanvas;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.graphics.Shader;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.InsetDrawable;
+import android.graphics.drawable.LayerDrawable;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Pair;
+import android.util.TypedValue;
+import android.view.ActionMode;
+import android.view.ContextThemeWrapper;
+import android.view.Gravity;
+import android.view.InputQueue;
+import android.view.KeyEvent;
+import android.view.KeyboardShortcutGroup;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MotionEvent;
+import android.view.ThreadedRenderer;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
+import android.view.ViewStub;
+import android.view.ViewTreeObserver;
+import android.view.Window;
+import android.view.WindowCallbacks;
+import android.view.WindowInsets;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import android.widget.FrameLayout;
+import android.widget.PopupWindow;
+
+import com.android.internal.R;
+import com.android.internal.policy.PhoneWindow.PanelFeatureState;
+import com.android.internal.policy.PhoneWindow.PhoneWindowMenuCallback;
+import com.android.internal.view.FloatingActionMode;
+import com.android.internal.view.RootViewSurfaceTaker;
+import com.android.internal.view.StandaloneActionMode;
+import com.android.internal.view.menu.ContextMenuBuilder;
+import com.android.internal.view.menu.MenuHelper;
+import com.android.internal.widget.ActionBarContextView;
+import com.android.internal.widget.BackgroundFallback;
+import com.android.internal.widget.DecorCaptionView;
+import com.android.internal.widget.FloatingToolbar;
+
+import java.util.List;
+
 /** @hide */
 public class DecorView extends FrameLayout implements RootViewSurfaceTaker, WindowCallbacks {
     private static final String TAG = "DecorView";
@@ -2134,7 +2135,7 @@
     }
 
     @Override
-    public void onPostDraw(DisplayListCanvas canvas) {
+    public void onPostDraw(RecordingCanvas canvas) {
         drawResizingShadowIfNeeded(canvas);
     }
 
@@ -2152,7 +2153,7 @@
                 new float[] { 0f, 0.3f, 1f }, Shader.TileMode.CLAMP));
     }
 
-    private void drawResizingShadowIfNeeded(DisplayListCanvas canvas) {
+    private void drawResizingShadowIfNeeded(RecordingCanvas canvas) {
         if (mResizeMode != RESIZE_MODE_DOCKED_DIVIDER || mWindow.mIsFloating
                 || mWindow.isTranslucent()
                 || mWindow.isShowingWallpaper()) {
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 8751517..3b7ce0a 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -1387,7 +1387,7 @@
     private int getOptionsPanelGravity() {
         try {
             return WindowManagerHolder.sWindowManager.getPreferredOptionsPanelGravity(
-                    getContext().getDisplay().getDisplayId());
+                    getContext().getDisplayId());
         } catch (RemoteException ex) {
             Log.e(TAG, "Couldn't getOptionsPanelGravity; using default", ex);
             return Gravity.CENTER | Gravity.BOTTOM;
@@ -3642,7 +3642,7 @@
                 if (!mIsWatching) {
                     try {
                         WindowManagerHolder.sWindowManager.watchRotation(this,
-                                phoneWindow.getContext().getDisplay().getDisplayId());
+                                phoneWindow.getContext().getDisplayId());
                         mHandler = new Handler();
                         mIsWatching = true;
                     } catch (RemoteException ex) {
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 989c58b..27c2478 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -101,7 +101,7 @@
 
     public static LatencyTracker getInstance(Context context) {
         if (sLatencyTracker == null) {
-            sLatencyTracker = new LatencyTracker(context);
+            sLatencyTracker = new LatencyTracker(context.getApplicationContext());
         }
         return sLatencyTracker;
     }
diff --git a/core/java/com/android/internal/view/IInputMethodClient.aidl b/core/java/com/android/internal/view/IInputMethodClient.aidl
index 2618356..17b2bc4 100644
--- a/core/java/com/android/internal/view/IInputMethodClient.aidl
+++ b/core/java/com/android/internal/view/IInputMethodClient.aidl
@@ -24,7 +24,6 @@
  */
 oneway interface IInputMethodClient {
     void onBindMethod(in InputBindResult res);
-    // unbindReason corresponds to InputMethodClient.UnbindReason.
     void onUnbindMethod(int sequence, int unbindReason);
     void setActive(boolean active, boolean fullscreen);
     void reportFullscreenMode(boolean fullscreen);
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index 5f1243f..29c55c2 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -31,7 +31,8 @@
  * applications.
  */
 interface IInputMethodManager {
-    void addClient(in IInputMethodClient client, in IInputContext inputContext);
+    void addClient(in IInputMethodClient client, in IInputContext inputContext,
+            int untrustedDisplayId);
 
     // TODO: Use ParceledListSlice instead
     List<InputMethodInfo> getInputMethodList();
@@ -45,7 +46,6 @@
     // Currently there is a bug that aidl doesn't accept List<Parcelable>
     List getShortcutInputMethodsAndSubtypes();
 
-    void finishInput(in IInputMethodClient client);
     boolean showSoftInput(in IInputMethodClient client, int flags,
             in ResultReceiver resultReceiver);
     boolean hideSoftInput(in IInputMethodClient client, int flags,
@@ -54,7 +54,7 @@
     // has gained focus, and if 'attribute' is non-null then also does startInput.
     // @NonNull
     InputBindResult startInputOrWindowGainedFocus(
-            /* @InputMethodClient.StartInputReason */ int startInputReason,
+            /* @StartInputReason */ int startInputReason,
             in IInputMethodClient client, in IBinder windowToken, int controlFlags,
             /* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
             int windowFlags, in EditorInfo attribute, IInputContext inputContext,
diff --git a/core/java/com/android/internal/view/IInputMethodSession.aidl b/core/java/com/android/internal/view/IInputMethodSession.aidl
index 367b713..794238a 100644
--- a/core/java/com/android/internal/view/IInputMethodSession.aidl
+++ b/core/java/com/android/internal/view/IInputMethodSession.aidl
@@ -29,10 +29,8 @@
  * {@hide}
  */
 oneway interface IInputMethodSession {
-    void finishInput();
-
     void updateExtractedText(int token, in ExtractedText text);
-    
+
     void updateSelection(int oldSelStart, int oldSelEnd,
             int newSelStart, int newSelEnd,
             int candidatesStart, int candidatesEnd);
diff --git a/core/java/com/android/internal/view/InputBindResult.java b/core/java/com/android/internal/view/InputBindResult.java
index 101fd41..ec8e8da 100644
--- a/core/java/com/android/internal/view/InputBindResult.java
+++ b/core/java/com/android/internal/view/InputBindResult.java
@@ -51,6 +51,9 @@
             ResultCode.ERROR_INVALID_USER,
             ResultCode.ERROR_NULL_EDITOR_INFO,
             ResultCode.ERROR_NOT_IME_TARGET_WINDOW,
+            ResultCode.ERROR_NO_EDITOR,
+            ResultCode.ERROR_DISPLAY_ID_MISMATCH,
+            ResultCode.ERROR_INVALID_DISPLAY_ID,
     })
     public @interface ResultCode {
         /**
@@ -139,13 +142,22 @@
          * The client should try to restart input when its {@link android.view.Window} is focused
          * again.</p>
          *
-         * @see com.android.server.wm.WindowManagerInternal#isInputMethodClientFocus(int, int)
+         * @see com.android.server.wm.WindowManagerInternal#isInputMethodClientFocus(int, int, int)
          */
         int ERROR_NOT_IME_TARGET_WINDOW = 11;
         /**
          * Indicates that focused view in the current window is not an editor.
          */
         int ERROR_NO_EDITOR = 12;
+        /**
+         * Indicates that there is a mismatch in display ID between IME client and focused Window.
+         */
+        int ERROR_DISPLAY_ID_MISMATCH = 13;
+        /**
+         * Indicates that current IME client is no longer allowed to access to the associated
+         * display.
+         */
+        int ERROR_INVALID_DISPLAY_ID = 14;
     }
 
     @ResultCode
@@ -271,6 +283,10 @@
                 return "ERROR_NULL_EDITOR_INFO";
             case ResultCode.ERROR_NOT_IME_TARGET_WINDOW:
                 return "ERROR_NOT_IME_TARGET_WINDOW";
+            case ResultCode.ERROR_DISPLAY_ID_MISMATCH:
+                return "ERROR_DISPLAY_ID_MISMATCH";
+            case ResultCode.ERROR_INVALID_DISPLAY_ID:
+                return "ERROR_INVALID_DISPLAY_ID";
             default:
                 return "Unknown(" + result + ")";
         }
@@ -316,4 +332,15 @@
      */
     public static final InputBindResult INVALID_USER = error(ResultCode.ERROR_INVALID_USER);
 
+    /**
+     * Predefined error object for {@link ResultCode#ERROR_DISPLAY_ID_MISMATCH}.
+     */
+    public static final InputBindResult DISPLAY_ID_MISMATCH =
+            error(ResultCode.ERROR_DISPLAY_ID_MISMATCH);
+
+    /**
+     * Predefined error object for {@link ResultCode#ERROR_INVALID_DISPLAY_ID}.
+     */
+    public static final InputBindResult INVALID_DISPLAY_ID =
+            error(ResultCode.ERROR_INVALID_DISPLAY_ID);
 }
diff --git a/core/java/com/android/internal/view/InputMethodClient.java b/core/java/com/android/internal/view/InputMethodClient.java
deleted file mode 100644
index bbd33a2..0000000
--- a/core/java/com/android/internal/view/InputMethodClient.java
+++ /dev/null
@@ -1,169 +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.internal.view;
-
-import android.annotation.IntDef;
-import android.view.WindowManager.LayoutParams;
-import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
-
-import java.lang.annotation.Retention;
-
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-public final class InputMethodClient {
-    public static final int START_INPUT_REASON_UNSPECIFIED = 0;
-    public static final int START_INPUT_REASON_WINDOW_FOCUS_GAIN = 1;
-    public static final int START_INPUT_REASON_WINDOW_FOCUS_GAIN_REPORT_ONLY = 2;
-    public static final int START_INPUT_REASON_APP_CALLED_RESTART_INPUT_API = 3;
-    public static final int START_INPUT_REASON_CHECK_FOCUS = 4;
-    public static final int START_INPUT_REASON_BOUND_TO_IMMS = 5;
-    public static final int START_INPUT_REASON_UNBOUND_FROM_IMMS = 6;
-    public static final int START_INPUT_REASON_ACTIVATED_BY_IMMS = 7;
-    public static final int START_INPUT_REASON_DEACTIVATED_BY_IMMS = 8;
-    public static final int START_INPUT_REASON_SESSION_CREATED_BY_IME = 9;
-
-    @Retention(SOURCE)
-    @IntDef({START_INPUT_REASON_UNSPECIFIED, START_INPUT_REASON_WINDOW_FOCUS_GAIN,
-            START_INPUT_REASON_WINDOW_FOCUS_GAIN_REPORT_ONLY,
-            START_INPUT_REASON_APP_CALLED_RESTART_INPUT_API, START_INPUT_REASON_CHECK_FOCUS,
-            START_INPUT_REASON_BOUND_TO_IMMS, START_INPUT_REASON_ACTIVATED_BY_IMMS,
-            START_INPUT_REASON_DEACTIVATED_BY_IMMS, START_INPUT_REASON_SESSION_CREATED_BY_IME})
-    public @interface StartInputReason {}
-
-    public static String getStartInputReason(@StartInputReason final int reason) {
-        switch (reason) {
-            case START_INPUT_REASON_UNSPECIFIED:
-                return "UNSPECIFIED";
-            case START_INPUT_REASON_WINDOW_FOCUS_GAIN:
-                return "WINDOW_FOCUS_GAIN";
-            case START_INPUT_REASON_WINDOW_FOCUS_GAIN_REPORT_ONLY:
-                return "WINDOW_FOCUS_GAIN_REPORT_ONLY";
-            case START_INPUT_REASON_APP_CALLED_RESTART_INPUT_API:
-                return "APP_CALLED_RESTART_INPUT_API";
-            case START_INPUT_REASON_CHECK_FOCUS:
-                return "CHECK_FOCUS";
-            case START_INPUT_REASON_BOUND_TO_IMMS:
-                return "BOUND_TO_IMMS";
-            case START_INPUT_REASON_UNBOUND_FROM_IMMS:
-                return "UNBOUND_FROM_IMMS";
-            case START_INPUT_REASON_ACTIVATED_BY_IMMS:
-                return "ACTIVATED_BY_IMMS";
-            case START_INPUT_REASON_DEACTIVATED_BY_IMMS:
-                return "DEACTIVATED_BY_IMMS";
-            case START_INPUT_REASON_SESSION_CREATED_BY_IME:
-                return "SESSION_CREATED_BY_IME";
-            default:
-                return "Unknown=" + reason;
-        }
-    }
-
-    public static final int UNBIND_REASON_UNSPECIFIED = 0;
-    public static final int UNBIND_REASON_SWITCH_CLIENT = 1;
-    public static final int UNBIND_REASON_SWITCH_IME = 2;
-    public static final int UNBIND_REASON_DISCONNECT_IME = 3;
-    public static final int UNBIND_REASON_NO_IME = 4;
-    public static final int UNBIND_REASON_SWITCH_IME_FAILED = 5;
-    public static final int UNBIND_REASON_SWITCH_USER = 6;
-
-    @Retention(SOURCE)
-    @IntDef({UNBIND_REASON_UNSPECIFIED, UNBIND_REASON_SWITCH_CLIENT, UNBIND_REASON_SWITCH_IME,
-            UNBIND_REASON_DISCONNECT_IME, UNBIND_REASON_NO_IME, UNBIND_REASON_SWITCH_IME_FAILED,
-            UNBIND_REASON_SWITCH_USER})
-    public @interface UnbindReason {}
-
-    public static String getUnbindReason(@UnbindReason final int reason) {
-        switch (reason) {
-            case UNBIND_REASON_UNSPECIFIED:
-                return "UNSPECIFIED";
-            case UNBIND_REASON_SWITCH_CLIENT:
-                return "SWITCH_CLIENT";
-            case UNBIND_REASON_SWITCH_IME:
-                return "SWITCH_IME";
-            case UNBIND_REASON_DISCONNECT_IME:
-                return "DISCONNECT_IME";
-            case UNBIND_REASON_NO_IME:
-                return "NO_IME";
-            case UNBIND_REASON_SWITCH_IME_FAILED:
-                return "SWITCH_IME_FAILED";
-            case UNBIND_REASON_SWITCH_USER:
-                return "SWITCH_USER";
-            default:
-                return "Unknown=" + reason;
-        }
-    }
-
-    public static String softInputModeToString(@SoftInputModeFlags final int softInputMode) {
-        final StringBuilder sb = new StringBuilder();
-        final int state = softInputMode & LayoutParams.SOFT_INPUT_MASK_STATE;
-        final int adjust = softInputMode & LayoutParams.SOFT_INPUT_MASK_ADJUST;
-        final boolean isForwardNav =
-                (softInputMode & LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0;
-
-        switch (state) {
-            case LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
-                sb.append("STATE_UNSPECIFIED");
-                break;
-            case LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
-                sb.append("STATE_UNCHANGED");
-                break;
-            case LayoutParams.SOFT_INPUT_STATE_HIDDEN:
-                sb.append("STATE_HIDDEN");
-                break;
-            case LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
-                sb.append("STATE_ALWAYS_HIDDEN");
-                break;
-            case LayoutParams.SOFT_INPUT_STATE_VISIBLE:
-                sb.append("STATE_VISIBLE");
-                break;
-            case LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
-                sb.append("STATE_ALWAYS_VISIBLE");
-                break;
-            default:
-                sb.append("STATE_UNKNOWN(");
-                sb.append(state);
-                sb.append(")");
-                break;
-        }
-
-        switch (adjust) {
-            case LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED:
-                sb.append("|ADJUST_UNSPECIFIED");
-                break;
-            case LayoutParams.SOFT_INPUT_ADJUST_RESIZE:
-                sb.append("|ADJUST_RESIZE");
-                break;
-            case LayoutParams.SOFT_INPUT_ADJUST_PAN:
-                sb.append("|ADJUST_PAN");
-                break;
-            case LayoutParams.SOFT_INPUT_ADJUST_NOTHING:
-                sb.append("|ADJUST_NOTHING");
-                break;
-            default:
-                sb.append("|ADJUST_UNKNOWN(");
-                sb.append(adjust);
-                sb.append(")");
-                break;
-        }
-
-        if (isForwardNav) {
-            // This is a special bit that is set by the system only during the window navigation.
-            sb.append("|IS_FORWARD_NAVIGATION");
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/core/java/com/android/internal/widget/AlertDialogLayout.java b/core/java/com/android/internal/widget/AlertDialogLayout.java
index 9bf0948..7a01749 100644
--- a/core/java/com/android/internal/widget/AlertDialogLayout.java
+++ b/core/java/com/android/internal/widget/AlertDialogLayout.java
@@ -18,6 +18,7 @@
 
 import android.annotation.AttrRes;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.annotation.StyleRes;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
@@ -50,6 +51,7 @@
         super(context);
     }
 
+    @UnsupportedAppUsage
     public AlertDialogLayout(@Nullable Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
     }
diff --git a/core/java/com/android/internal/widget/ButtonBarLayout.java b/core/java/com/android/internal/widget/ButtonBarLayout.java
index ab8be33..0ca6743 100644
--- a/core/java/com/android/internal/widget/ButtonBarLayout.java
+++ b/core/java/com/android/internal/widget/ButtonBarLayout.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.util.AttributeSet;
@@ -40,6 +41,7 @@
 
     private int mMinimumHeight = 0;
 
+    @UnsupportedAppUsage
     public ButtonBarLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
 
diff --git a/core/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java
index 7ea3d6b..405436c 100644
--- a/core/java/com/android/internal/widget/DialogTitle.java
+++ b/core/java/com/android/internal/widget/DialogTitle.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.text.Layout;
@@ -37,6 +38,7 @@
         super(context, attrs, defStyleAttr);
     }
 
+    @UnsupportedAppUsage
     public DialogTitle(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 9263b57..b799728 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -24,23 +24,21 @@
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.CanvasProperty;
-import android.graphics.drawable.Drawable;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.media.AudioManager;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
 import android.util.AttributeSet;
 import android.util.IntArray;
 import android.util.Log;
 import android.util.SparseArray;
-import android.view.DisplayListCanvas;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.RenderNodeAnimator;
@@ -71,6 +69,7 @@
     private static final int ASPECT_LOCK_HEIGHT = 2; // Fixed height; width will be minimum of (w,h)
 
     private static final boolean PROFILE_DRAWING = false;
+    private static final float LINE_FADE_ALPHA_MULTIPLIER = 3.5f;
     private final CellState[][] mCellStates;
 
     private final int mDotSize;
@@ -1131,8 +1130,8 @@
                     drawCellDrawable(canvas, i, j, cellState.radius, drawLookup[i][j]);
                 } else {
                     if (isHardwareAccelerated() && cellState.hwAnimating) {
-                        DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
-                        displayListCanvas.drawCircle(cellState.hwCenterX, cellState.hwCenterY,
+                        RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
+                        recordingCanvas.drawCircle(cellState.hwCenterX, cellState.hwCenterY,
                                 cellState.hwRadius, cellState.hwPaint);
                     } else {
                         drawCircle(canvas, (int) centerX, (int) centerY + translationY,
@@ -1172,9 +1171,9 @@
                 float centerX = getCenterXForColumn(cell.column);
                 float centerY = getCenterYForRow(cell.row);
                 if (i != 0) {
-                   // Set this line segment to slowly fade over the next second.
+                   // Set this line segment to fade away animated.
                    int lineFadeVal = (int) Math.min((elapsedRealtime -
-                           mLineFadeStart[i])/2f, 255f);
+                           mLineFadeStart[i]) * LINE_FADE_ALPHA_MULTIPLIER, 255f);
 
                     CellState state = mCellStates[cell.row][cell.column];
                     currentPath.rewind();
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 0a787b9..d68e8f8 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -331,13 +331,11 @@
         readPermissions(Environment.buildPath(
                 Environment.getOemDirectory(), "etc", "permissions"), oemPermissionFlag);
 
-        // Allow Product to customize system configs around libs, features, permissions and apps
-        int productPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PERMISSIONS |
-                ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS;
+        // Allow Product to customize all system configs
         readPermissions(Environment.buildPath(
-                Environment.getProductDirectory(), "etc", "sysconfig"), productPermissionFlag);
+                Environment.getProductDirectory(), "etc", "sysconfig"), ALLOW_ALL);
         readPermissions(Environment.buildPath(
-                Environment.getProductDirectory(), "etc", "permissions"), productPermissionFlag);
+                Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL);
 
         // Allow /product_services to customize system configs around libs, features, permissions
         // and apps.
diff --git a/core/java/com/google/android/collect/Lists.java b/core/java/com/google/android/collect/Lists.java
index c029bb2..3ea873b 100644
--- a/core/java/com/google/android/collect/Lists.java
+++ b/core/java/com/google/android/collect/Lists.java
@@ -16,6 +16,7 @@
 
 package com.google.android.collect;
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.ArrayList;
 import java.util.Collections;
 
@@ -33,6 +34,7 @@
      *
      * @return a newly-created, initially-empty {@code ArrayList}
      */
+    @UnsupportedAppUsage
     public static <E> ArrayList<E> newArrayList() {
         return new ArrayList<E>();
     }
diff --git a/core/java/com/google/android/collect/Maps.java b/core/java/com/google/android/collect/Maps.java
index fc2c9fe..6ba3320 100644
--- a/core/java/com/google/android/collect/Maps.java
+++ b/core/java/com/google/android/collect/Maps.java
@@ -16,6 +16,7 @@
 
 package com.google.android.collect;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.ArrayMap;
 
 import java.util.HashMap;
@@ -29,6 +30,7 @@
      *
      * @return a newly-created, initially-empty {@code HashMap}
      */
+    @UnsupportedAppUsage
     public static <K, V> HashMap<K, V> newHashMap() {
         return new HashMap<K, V>();
     }
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 762b430..59c29e2 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -45,6 +45,7 @@
         "android_app_NativeActivity.cpp",
         "android_app_admin_SecurityLog.cpp",
         "android_opengl_EGL14.cpp",
+        "android_opengl_EGL15.cpp",
         "android_opengl_EGLExt.cpp",
         "android_opengl_GLES10.cpp",
         "android_opengl_GLES10Ext.cpp",
@@ -84,8 +85,6 @@
         "android_view_VelocityTracker.cpp",
         "android_text_AndroidCharacter.cpp",
         "android_text_Hyphenator.cpp",
-        "android_text_LineBreaker.cpp",
-        "android_text_MeasuredParagraph.cpp",
         "android_os_Debug.cpp",
         "android_os_GraphicsEnvironment.cpp",
         "android_os_HidlSupport.cpp",
@@ -161,6 +160,8 @@
         "android/graphics/pdf/PdfEditor.cpp",
         "android/graphics/pdf/PdfRenderer.cpp",
         "android/graphics/pdf/PdfUtils.cpp",
+        "android/graphics/text/LineBreaker.cpp",
+        "android/graphics/text/MeasuredText.cpp",
         "android_media_AudioRecord.cpp",
         "android_media_AudioSystem.cpp",
         "android_media_AudioTrack.cpp",
@@ -209,6 +210,8 @@
         "com_android_internal_view_animation_NativeInterpolatorFactoryHelper.cpp",
         "hwbinder/EphemeralStorage.cpp",
         "fd_utils.cpp",
+        "android_hardware_input_InputWindowHandle.cpp",
+        "android_hardware_input_InputApplicationHandle.cpp",
     ],
 
     include_dirs: [
@@ -232,10 +235,12 @@
         "libseccomp_policy",
         "libgrallocusage",
         "libscrypt_static",
+        "libstatssocket",
     ],
 
     shared_libs: [
         "libbpf",
+        "libnetdbpf",
         "libnetdutils",
         "libmemtrack",
         "libandroidfw",
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 6b55ed6..eada690 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -77,6 +77,7 @@
 extern int register_com_google_android_gles_jni_EGLImpl(JNIEnv* env);
 extern int register_com_google_android_gles_jni_GLImpl(JNIEnv* env);
 extern int register_android_opengl_jni_EGL14(JNIEnv* env);
+extern int register_android_opengl_jni_EGL15(JNIEnv* env);
 extern int register_android_opengl_jni_EGLExt(JNIEnv* env);
 extern int register_android_opengl_jni_GLES10(JNIEnv* env);
 extern int register_android_opengl_jni_GLES10Ext(JNIEnv* env);
@@ -145,6 +146,8 @@
 extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
 extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
+extern int register_android_graphics_text_MeasuredText(JNIEnv* env);
+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_TextureLayer(JNIEnv* env);
@@ -185,8 +188,6 @@
 extern int register_android_net_NetworkUtils(JNIEnv* env);
 extern int register_android_text_AndroidCharacter(JNIEnv *env);
 extern int register_android_text_Hyphenator(JNIEnv *env);
-extern int register_android_text_MeasuredParagraph(JNIEnv* env);
-extern int register_android_text_LineBreaker(JNIEnv *env);
 extern int register_android_opengl_classes(JNIEnv *env);
 extern int register_android_ddm_DdmHandleNativeHeap(JNIEnv *env);
 extern int register_android_server_NetworkManagementSocketTagger(JNIEnv* env);
@@ -1336,8 +1337,6 @@
     REG_JNI(register_android_content_res_ApkAssets),
     REG_JNI(register_android_text_AndroidCharacter),
     REG_JNI(register_android_text_Hyphenator),
-    REG_JNI(register_android_text_MeasuredParagraph),
-    REG_JNI(register_android_text_LineBreaker),
     REG_JNI(register_android_view_InputDevice),
     REG_JNI(register_android_view_KeyCharacterMap),
     REG_JNI(register_android_os_Process),
@@ -1369,6 +1368,7 @@
     REG_JNI(register_com_google_android_gles_jni_EGLImpl),
     REG_JNI(register_com_google_android_gles_jni_GLImpl),
     REG_JNI(register_android_opengl_jni_EGL14),
+    REG_JNI(register_android_opengl_jni_EGL15),
     REG_JNI(register_android_opengl_jni_EGLExt),
     REG_JNI(register_android_opengl_jni_GLES10),
     REG_JNI(register_android_opengl_jni_GLES10Ext),
@@ -1415,6 +1415,8 @@
     REG_JNI(register_android_graphics_pdf_PdfDocument),
     REG_JNI(register_android_graphics_pdf_PdfEditor),
     REG_JNI(register_android_graphics_pdf_PdfRenderer),
+    REG_JNI(register_android_graphics_text_MeasuredText),
+    REG_JNI(register_android_graphics_text_LineBreaker),
 
     REG_JNI(register_android_database_CursorWindow),
     REG_JNI(register_android_database_SQLiteConnection),
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 897f6fa5..c32de0a 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -7,15 +7,9 @@
 #include "SkImageEncoder.h"
 #include "SkImageInfo.h"
 #include "SkColor.h"
-#include "SkColorPriv.h"
 #include "SkColorSpace.h"
-#include "SkColorSpaceXform.h"
-#include "SkHalf.h"
 #include "SkMatrix44.h"
-#include "SkPM4f.h"
-#include "SkPM4fPriv.h"
 #include "GraphicsJNI.h"
-#include "SkUnPreMultiply.h"
 #include "SkStream.h"
 
 #include <binder/Parcel.h>
@@ -27,6 +21,10 @@
 #include <hwui/Bitmap.h>
 #include <renderthread/RenderProxy.h>
 
+#include <android_runtime/android_hardware_HardwareBuffer.h>
+
+#include <private/android/AHardwareBufferHelpers.h>
+
 #include "core_jni_helpers.h"
 
 #include <jni.h>
@@ -559,13 +557,10 @@
         if (!p3.tryAllocPixels(info)) {
             return JNI_FALSE;
         }
-        auto xform = SkColorSpaceXform::New(skbitmap.colorSpace(), info.colorSpace());
-        if (!xform) {
-            return JNI_FALSE;
-        }
-        if (!xform->apply(SkColorSpaceXform::kRGBA_8888_ColorFormat, p3.getPixels(),
-                          SkColorSpaceXform::kRGBA_F16_ColorFormat, skbitmap.getPixels(),
-                          info.width() * info.height(), kUnpremul_SkAlphaType)) {
+
+        SkPixmap pm;
+        SkAssertResult(p3.peekPixels(&pm));  // should always work if tryAllocPixels() did.
+        if (!skbitmap.readPixels(pm)) {
             return JNI_FALSE;
         }
         skbitmap = p3;
@@ -1113,8 +1108,7 @@
 
 static jobject Bitmap_createHardwareBitmap(JNIEnv* env, jobject, jobject graphicBuffer) {
     sp<GraphicBuffer> buffer(graphicBufferForJavaObject(env, graphicBuffer));
-    // Bitmap::createFrom currently can only attach to a GraphicBuffer with PIXEL_FORMAT_RGBA_8888
-    // format and SRGB color space.
+    // Bitmap::createFrom currently assumes SRGB color space for RGBA images.
     // To support any color space, we need to pass an additional ColorSpace argument to
     // java Bitmap.createHardwareBitmap.
     sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer);
@@ -1125,6 +1119,22 @@
     return bitmap::createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(false));
 }
 
+static jobject Bitmap_wrapHardwareBufferBitmap(JNIEnv* env, jobject, jobject hardwareBuffer,
+                                               jfloatArray xyzD50, jobject transferParameters) {
+    SkColorSpaceTransferFn p = GraphicsJNI::getNativeTransferParameters(env, transferParameters);
+    SkMatrix44 xyzMatrix = GraphicsJNI::getNativeXYZMatrix(env, xyzD50);
+    sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeRGB(p, xyzMatrix);
+    AHardwareBuffer* hwBuf = android_hardware_HardwareBuffer_getNativeHardwareBuffer(env,
+        hardwareBuffer);
+    sp<GraphicBuffer> buffer(AHardwareBuffer_to_GraphicBuffer(hwBuf));
+    sk_sp<Bitmap> bitmap = Bitmap::createFrom(buffer, colorSpace);
+    if (!bitmap.get()) {
+        ALOGW("failed to create hardware bitmap from hardware buffer");
+        return NULL;
+    }
+    return bitmap::createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(false));
+}
+
 static jobject Bitmap_createGraphicBufferHandle(JNIEnv* env, jobject, jlong bitmapPtr) {
     LocalScopedBitmap bitmapHandle(bitmapPtr);
     LOG_ALWAYS_FATAL_IF(!bitmapHandle->isHardware(),
@@ -1204,6 +1214,8 @@
         (void*)Bitmap_copyPreserveInternalConfig },
     {   "nativeCreateHardwareBitmap", "(Landroid/graphics/GraphicBuffer;)Landroid/graphics/Bitmap;",
         (void*) Bitmap_createHardwareBitmap },
+    {   "nativeWrapHardwareBufferBitmap", "(Landroid/hardware/HardwareBuffer;[FLandroid/graphics/ColorSpace$Rgb$TransferParameters;)Landroid/graphics/Bitmap;",
+        (void*) Bitmap_wrapHardwareBufferBitmap },
     {   "nativeCreateGraphicBufferHandle", "(J)Landroid/graphics/GraphicBuffer;",
         (void*) Bitmap_createGraphicBufferHandle },
     {   "nativeGetColorSpace",      "(J[F[F)Z", (void*)Bitmap_getColorSpace },
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index 2619107..bb291e7 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -23,8 +23,6 @@
 #include <hwui/Paint.h>
 #include <utils/Log.h>
 
-#include <ResourceCache.h>
-
 #include "SkCanvas.h"
 #include "SkLatticeIter.h"
 #include "SkRegion.h"
@@ -83,12 +81,7 @@
 
     static void finalize(JNIEnv* env, jobject, jlong patchHandle) {
         int8_t* patch = reinterpret_cast<int8_t*>(patchHandle);
-        if (android::uirenderer::ResourceCache::hasInstance()) {
-            Res_png_9patch* p = (Res_png_9patch*) patch;
-            android::uirenderer::ResourceCache::getInstance().destructor(p);
-        } else {
-            delete[] patch;
-        }
+        delete[] patch;
     }
 
     static jlong getTransparentRegion(JNIEnv* env, jobject, jobject jbitmap,
diff --git a/core/jni/android_text_LineBreaker.cpp b/core/jni/android/graphics/text/LineBreaker.cpp
similarity index 96%
rename from core/jni/android_text_LineBreaker.cpp
rename to core/jni/android/graphics/text/LineBreaker.cpp
index 5439107..e1f2f2b 100644
--- a/core/jni/android_text_LineBreaker.cpp
+++ b/core/jni/android/graphics/text/LineBreaker.cpp
@@ -168,8 +168,9 @@
     {"nGetReleaseResultFunc", "()J", (void*)nGetReleaseResultFunc},
 };
 
-int register_android_text_LineBreaker(JNIEnv* env) {
-    return RegisterMethodsOrDie(env, "android/text/NativeLineBreaker", gMethods, NELEM(gMethods));
+int register_android_graphics_text_LineBreaker(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, "android/graphics/text/LineBreaker", gMethods,
+                                NELEM(gMethods));
 }
 
 }
diff --git a/core/jni/android_text_MeasuredParagraph.cpp b/core/jni/android/graphics/text/MeasuredText.cpp
similarity index 91%
rename from core/jni/android_text_MeasuredParagraph.cpp
rename to core/jni/android/graphics/text/MeasuredText.cpp
index 18f509c..0bfadb4 100644
--- a/core/jni/android_text_MeasuredParagraph.cpp
+++ b/core/jni/android/graphics/text/MeasuredText.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "MeasuredParagraph"
+#define LOG_TAG "MeasuredText"
 
 #include "GraphicsJNI.h"
 #include "unicode/locid.h"
@@ -83,7 +83,7 @@
 }
 
 // Regular JNI
-static jlong nBuildNativeMeasuredParagraph(JNIEnv* env, jclass /* unused */, jlong builderPtr,
+static jlong nBuildMeasuredText(JNIEnv* env, jclass /* unused */, jlong builderPtr,
                                       jcharArray javaText, jboolean computeHyphenation,
                                       jboolean computeLayout) {
     ScopedCharArrayRO text(env, javaText);
@@ -147,7 +147,7 @@
     {"nInitBuilder", "()J", (void*) nInitBuilder},
     {"nAddStyleRun", "(JJIIZ)V", (void*) nAddStyleRun},
     {"nAddReplacementRun", "(JJIIF)V", (void*) nAddReplacementRun},
-    {"nBuildNativeMeasuredParagraph", "(J[CZZ)J", (void*) nBuildNativeMeasuredParagraph},
+    {"nBuildMeasuredText", "(J[CZZ)J", (void*) nBuildMeasuredText},
     {"nFreeBuilder", "(J)V", (void*) nFreeBuilder},
 };
 
@@ -160,10 +160,10 @@
     {"nGetCharWidthAt", "(JI)F", (void*) nGetCharWidthAt},  // Critical Native
 };
 
-int register_android_text_MeasuredParagraph(JNIEnv* env) {
-    return RegisterMethodsOrDie(env, "android/text/NativeMeasuredParagraph",
+int register_android_graphics_text_MeasuredText(JNIEnv* env) {
+    return RegisterMethodsOrDie(env, "android/graphics/text/MeasuredText",
             gMTMethods, NELEM(gMTMethods))
-        + RegisterMethodsOrDie(env, "android/text/NativeMeasuredParagraph$Builder",
+        + RegisterMethodsOrDie(env, "android/graphics/text/MeasuredText$Builder",
             gMTBuilderMethods, NELEM(gMTBuilderMethods));
 }
 
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 343aef2..dca2da3 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -273,6 +273,32 @@
     get_canvas(canvasHandle)->drawRect(left, top, right, bottom, *paint);
 }
 
+static void drawDoubleRoundRectXY(JNIEnv* env, jobject, jlong canvasHandle, jfloat outerLeft,
+                    jfloat outerTop, jfloat outerRight, jfloat outerBottom, jfloat outerRx,
+                    jfloat outerRy, jfloat innerLeft, jfloat innerTop, jfloat innerRight,
+                    jfloat innerBottom, jfloat innerRx, jfloat innerRy, jlong paintHandle) {
+    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+    get_canvas(canvasHandle)->drawDoubleRoundRectXY(
+                    outerLeft, outerTop, outerRight, outerBottom, outerRx, outerRy,
+                    innerLeft, innerTop, innerRight, innerBottom, innerRx, innerRy, *paint);
+}
+
+static void drawDoubleRoundRectRadii(JNIEnv* env, jobject, jlong canvasHandle, jfloat outerLeft,
+                     jfloat outerTop, jfloat outerRight, jfloat outerBottom, jfloatArray jouterRadii,
+                     jfloat innerLeft, jfloat innerTop, jfloat innerRight,
+                     jfloat innerBottom, jfloatArray jinnerRadii, jlong paintHandle) {
+    const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
+
+    float outerRadii[8];
+    float innerRadii[8];
+    env->GetFloatArrayRegion(jouterRadii, 0, 8, outerRadii);
+    env->GetFloatArrayRegion(jinnerRadii, 0, 8, innerRadii);
+    get_canvas(canvasHandle)->drawDoubleRoundRectRadii(
+                    outerLeft, outerTop, outerRight, outerBottom, outerRadii,
+                    innerLeft, innerTop, innerRight, innerBottom, innerRadii, *paint);
+
+}
+
 static void drawRegion(JNIEnv* env, jobject, jlong canvasHandle, jlong regionHandle,
                        jlong paintHandle) {
     const SkRegion* region = reinterpret_cast<SkRegion*>(regionHandle);
@@ -651,6 +677,8 @@
     {"nDrawRect","(JFFFFJ)V", (void*) CanvasJNI::drawRect},
     {"nDrawRegion", "(JJJ)V", (void*) CanvasJNI::drawRegion },
     {"nDrawRoundRect","(JFFFFFFJ)V", (void*) CanvasJNI::drawRoundRect},
+    {"nDrawDoubleRoundRect", "(JFFFFFFFFFFFFJ)V", (void*) CanvasJNI::drawDoubleRoundRectXY},
+    {"nDrawDoubleRoundRect", "(JFFFF[FFFFF[FJ)V", (void*) CanvasJNI::drawDoubleRoundRectRadii},
     {"nDrawCircle","(JFFFJ)V", (void*) CanvasJNI::drawCircle},
     {"nDrawOval","(JFFFFJ)V", (void*) CanvasJNI::drawOval},
     {"nDrawArc","(JFFFFFFZJ)V", (void*) CanvasJNI::drawArc},
diff --git a/core/jni/android_hardware_SoundTrigger.cpp b/core/jni/android_hardware_SoundTrigger.cpp
index 9dbb8d7..b417a56 100644
--- a/core/jni/android_hardware_SoundTrigger.cpp
+++ b/core/jni/android_hardware_SoundTrigger.cpp
@@ -788,6 +788,63 @@
     return status;
 }
 
+static jobject
+android_hardware_SoundTrigger_getModelState(JNIEnv *env, jobject thiz,
+                                            jint jHandle)
+{
+    ALOGV("getModelState");
+    sp<SoundTrigger> module = getSoundTrigger(env, thiz);
+    if (module == NULL) {
+        return NULL;
+    }
+    sp<IMemory> memory;
+    jint status = module->getModelState(jHandle, memory);
+    if (status != 0 || memory == NULL) {
+        ALOGW("getModelState, failed to get model state, status: %d", status);
+        return NULL;
+    }
+    struct sound_trigger_recognition_event* event =
+        (struct sound_trigger_recognition_event *)memory->pointer();
+    if (event == NULL) {
+        return NULL;
+    }
+    if (event->type != SOUND_MODEL_TYPE_GENERIC) {
+        ALOGW("getModelState, unsupported model type: %d", event->type);
+        return NULL;
+    }
+
+    jbyteArray jData = NULL;
+    if (event->data_size) {
+        jData = env->NewByteArray(event->data_size);
+        jbyte *nData = env->GetByteArrayElements(jData, NULL);
+        memcpy(nData, (char *)event + event->data_offset, event->data_size);
+        env->ReleaseByteArrayElements(jData, nData, 0);
+    }
+
+    jobject jAudioFormat = NULL;
+    if (event->trigger_in_data || event->capture_available) {
+        jAudioFormat = env->NewObject(gAudioFormatClass,
+                                      gAudioFormatCstor,
+                                      audioFormatFromNative(event->audio_config.format),
+                                      event->audio_config.sample_rate,
+                                      inChannelMaskFromNative(event->audio_config.channel_mask));
+
+    }
+    jobject jEvent = NULL;
+    jEvent = env->NewObject(gGenericRecognitionEventClass, gGenericRecognitionEventCstor,
+                            event->status, event->model, event->capture_available,
+                            event->capture_session, event->capture_delay_ms,
+                            event->capture_preamble_ms, event->trigger_in_data,
+                            jAudioFormat, jData);
+    if (jAudioFormat != NULL) {
+        env->DeleteLocalRef(jAudioFormat);
+    }
+    if (jData != NULL) {
+        env->DeleteLocalRef(jData);
+    }
+    return jEvent;
+}
+
 static const JNINativeMethod gMethods[] = {
     {"listModules",
         "(Ljava/util/ArrayList;)I",
@@ -817,6 +874,9 @@
     {"stopRecognition",
         "(I)I",
         (void *)android_hardware_SoundTrigger_stopRecognition},
+    {"getModelState",
+        "(I)Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;",
+        (void *)android_hardware_SoundTrigger_getModelState},
 };
 
 int register_android_hardware_SoundTrigger(JNIEnv *env)
diff --git a/core/jni/android_hardware_display_DisplayViewport.cpp b/core/jni/android_hardware_display_DisplayViewport.cpp
index ab8e685..05f6556 100644
--- a/core/jni/android_hardware_display_DisplayViewport.cpp
+++ b/core/jni/android_hardware_display_DisplayViewport.cpp
@@ -40,6 +40,7 @@
     jfieldID deviceWidth;
     jfieldID deviceHeight;
     jfieldID uniqueId;
+    jfieldID type;
 } gDisplayViewportClassInfo;
 
 static struct {
@@ -64,6 +65,9 @@
         viewport->uniqueId = ScopedUtfChars(env, uniqueId).c_str();
     }
 
+    viewport->type = static_cast<ViewportType>(env->GetIntField(viewportObj,
+                gDisplayViewportClassInfo.type));
+
     jobject logicalFrameObj =
             env->GetObjectField(viewportObj, gDisplayViewportClassInfo.logicalFrame);
     viewport->logicalLeft = env->GetIntField(logicalFrameObj, gRectClassInfo.left);
@@ -108,6 +112,9 @@
     gDisplayViewportClassInfo.uniqueId = GetFieldIDOrDie(env,
             gDisplayViewportClassInfo.clazz, "uniqueId", "Ljava/lang/String;");
 
+    gDisplayViewportClassInfo.type = GetFieldIDOrDie(env,
+            gDisplayViewportClassInfo.clazz, "type", "I");
+
     clazz = FindClassOrDie(env, "android/graphics/Rect");
     gRectClassInfo.left = GetFieldIDOrDie(env, clazz, "left", "I");
     gRectClassInfo.top = GetFieldIDOrDie(env, clazz, "top", "I");
diff --git a/services/core/jni/com_android_server_input_InputApplicationHandle.cpp b/core/jni/android_hardware_input_InputApplicationHandle.cpp
similarity index 98%
rename from services/core/jni/com_android_server_input_InputApplicationHandle.cpp
rename to core/jni/android_hardware_input_InputApplicationHandle.cpp
index 514b6e1..8ace8da 100644
--- a/services/core/jni/com_android_server_input_InputApplicationHandle.cpp
+++ b/core/jni/android_hardware_input_InputApplicationHandle.cpp
@@ -21,7 +21,7 @@
 #include <android_runtime/AndroidRuntime.h>
 #include <utils/threads.h>
 
-#include "com_android_server_input_InputApplicationHandle.h"
+#include "android_hardware_input_InputApplicationHandle.h"
 
 namespace android {
 
diff --git a/services/core/jni/com_android_server_input_InputApplicationHandle.h b/core/jni/android_hardware_input_InputApplicationHandle.h
similarity index 95%
rename from services/core/jni/com_android_server_input_InputApplicationHandle.h
rename to core/jni/android_hardware_input_InputApplicationHandle.h
index c9af711..7115611 100644
--- a/services/core/jni/com_android_server_input_InputApplicationHandle.h
+++ b/core/jni/android_hardware_input_InputApplicationHandle.h
@@ -17,7 +17,9 @@
 #ifndef _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
 #define _ANDROID_SERVER_INPUT_APPLICATION_HANDLE_H
 
-#include <inputflinger/InputApplication.h>
+#include <string>
+
+#include <input/InputApplication.h>
 
 #include <nativehelper/JNIHelp.h>
 #include "jni.h"
diff --git a/services/core/jni/com_android_server_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
similarity index 98%
rename from services/core/jni/com_android_server_input_InputWindowHandle.cpp
rename to core/jni/android_hardware_input_InputWindowHandle.cpp
index c13aa38..f4829ad 100644
--- a/services/core/jni/com_android_server_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -25,8 +25,8 @@
 #include <android/graphics/Region.h>
 #include <ui/Region.h>
 
-#include "com_android_server_input_InputWindowHandle.h"
-#include "com_android_server_input_InputApplicationHandle.h"
+#include "android_hardware_input_InputWindowHandle.h"
+#include "android_hardware_input_InputApplicationHandle.h"
 
 namespace android {
 
diff --git a/services/core/jni/com_android_server_input_InputWindowHandle.h b/core/jni/android_hardware_input_InputWindowHandle.h
similarity index 96%
rename from services/core/jni/com_android_server_input_InputWindowHandle.h
rename to core/jni/android_hardware_input_InputWindowHandle.h
index 44d4620..2be267e 100644
--- a/services/core/jni/com_android_server_input_InputWindowHandle.h
+++ b/core/jni/android_hardware_input_InputWindowHandle.h
@@ -17,7 +17,7 @@
 #ifndef _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
 #define _ANDROID_SERVER_INPUT_WINDOW_HANDLE_H
 
-#include <inputflinger/InputWindow.h>
+#include <input/InputWindow.h>
 
 #include <nativehelper/JNIHelp.h>
 #include "jni.h"
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index da4cdb6..83a8c2e 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -127,10 +127,9 @@
     case AUDIO_FORMAT_DOLBY_TRUEHD:
         return ENCODING_DOLBY_TRUEHD;
     case AUDIO_FORMAT_AAC_ELD:
-            return ENCODING_AAC_ELD;
-    // FIXME needs addition of AUDIO_FORMAT_AAC_XHE
-    //case AUDIO_FORMAT_AAC_XHE:
-    //    return ENCODING_AAC_XHE;
+        return ENCODING_AAC_ELD;
+    case AUDIO_FORMAT_AAC_XHE:
+        return ENCODING_AAC_XHE;
     case AUDIO_FORMAT_AC4:
         return ENCODING_AC4;
     case AUDIO_FORMAT_E_AC3_JOC:
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 6456fe6..bf22dd2 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -29,6 +29,7 @@
 #include <media/AudioSystem.h>
 #include <media/AudioTrack.h>
 
+#include <android-base/macros.h>
 #include <binder/MemoryHeapBase.h>
 #include <binder/MemoryBase.h>
 
@@ -134,41 +135,53 @@
         callbackInfo->busy = true;
     }
 
+    // used as default argument when event callback doesn't have any, or number of
+    // frames for EVENT_CAN_WRITE_MORE_DATA
+    int arg = 0;
+    bool postEvent = false;
     switch (event) {
     // Offload only events
-    case AudioTrack::EVENT_STREAM_END:
-    case AudioTrack::EVENT_MORE_DATA:
-    // a.k.a. tear down
-    case AudioTrack::EVENT_NEW_IAUDIOTRACK:
+    case AudioTrack::EVENT_CAN_WRITE_MORE_DATA:
+        // this event will read the info return parameter of the callback:
+        // for JNI offload, use the returned size to indicate:
+        // 1/ no data is returned through callback, as it's all done through write()
+        // 2/ do not wait as AudioTrack does when it receives 0 bytes
         if (callbackInfo->isOffload) {
-            JNIEnv *env = AndroidRuntime::getJNIEnv();
-            if (user != NULL && env != NULL) {
-                env->CallStaticVoidMethod(
-                        callbackInfo->audioTrack_class,
-                        javaAudioTrackFields.postNativeEventInJava,
-                        callbackInfo->audioTrack_ref, event, 0,0, NULL);
-                if (env->ExceptionCheck()) {
-                    env->ExceptionDescribe();
-                    env->ExceptionClear();
-                }
-            }
-        } break;
+            AudioTrack::Buffer* pBuffer = (AudioTrack::Buffer*) info;
+            const size_t availableForWrite = pBuffer->size;
+            arg = availableForWrite > INT32_MAX ? INT32_MAX : (int) availableForWrite;
+            pBuffer->size = 0;
+        }
+        FALLTHROUGH_INTENDED;
+    case AudioTrack::EVENT_STREAM_END:
+    case AudioTrack::EVENT_NEW_IAUDIOTRACK: // a.k.a. tear down
+        if (callbackInfo->isOffload) {
+            postEvent = true;
+        }
+        break;
 
     // PCM and offload events
     case AudioTrack::EVENT_MARKER:
-    case AudioTrack::EVENT_NEW_POS: {
+    case AudioTrack::EVENT_NEW_POS:
+        postEvent = true;
+        break;
+    default:
+        // event will not be posted
+        break;
+    }
+
+    if (postEvent) {
         JNIEnv *env = AndroidRuntime::getJNIEnv();
-        if (user != NULL && env != NULL) {
+        if (env != NULL) {
             env->CallStaticVoidMethod(
                     callbackInfo->audioTrack_class,
                     javaAudioTrackFields.postNativeEventInJava,
-                    callbackInfo->audioTrack_ref, event, 0,0, NULL);
+                    callbackInfo->audioTrack_ref, event, arg, 0, NULL);
             if (env->ExceptionCheck()) {
                 env->ExceptionDescribe();
                 env->ExceptionClear();
             }
         }
-        } break;
     }
 
     {
@@ -215,10 +228,10 @@
         jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession,
         jlong nativeAudioTrack, jboolean offload) {
 
-    ALOGV("sampleRates=%p, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d"
-        "nativeAudioTrack=0x%" PRIX64,
+    ALOGV("sampleRates=%p, channel mask=%x, index mask=%x, audioFormat(Java)=%d, buffSize=%d,"
+        " nativeAudioTrack=0x%" PRIX64 ", offload=%d",
         jSampleRate, channelPositionMask, channelIndexMask, audioFormat, buffSizeInBytes,
-        nativeAudioTrack);
+        nativeAudioTrack, offload);
 
     sp<AudioTrack> lpTrack = 0;
 
@@ -318,7 +331,7 @@
         lpJniStorage->mCallbackData.busy = false;
 
         audio_offload_info_t offloadInfo;
-        if (offload) {
+        if (offload == JNI_TRUE) {
             offloadInfo = AUDIO_INFO_INITIALIZER;
             offloadInfo.format = format;
             offloadInfo.sample_rate = sampleRateInHertz;
@@ -331,23 +344,23 @@
         status_t status = NO_ERROR;
         switch (memoryMode) {
         case MODE_STREAM:
-
             status = lpTrack->set(
                     AUDIO_STREAM_DEFAULT,// stream type, but more info conveyed in paa (last argument)
                     sampleRateInHertz,
                     format,// word length, PCM
                     nativeChannelMask,
-                    frameCount,
-                    AUDIO_OUTPUT_FLAG_NONE,
+                    offload ? 0 : frameCount,
+                    offload ? AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD : AUDIO_OUTPUT_FLAG_NONE,
                     audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)
                     0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
                     0,// shared mem
                     true,// thread can call Java
                     sessionId,// audio session ID
-                    AudioTrack::TRANSFER_SYNC,
+                    offload ? AudioTrack::TRANSFER_SYNC_NOTIF_CALLBACK : AudioTrack::TRANSFER_SYNC,
                     offload ? &offloadInfo : NULL,
                     -1, -1,                       // default uid, pid values
                     paa);
+
             break;
 
         case MODE_STATIC:
diff --git a/core/jni/android_opengl_EGL15.cpp b/core/jni/android_opengl_EGL15.cpp
new file mode 100644
index 0000000..b52f137
--- /dev/null
+++ b/core/jni/android_opengl_EGL15.cpp
@@ -0,0 +1,566 @@
+/*
+** 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.
+*/
+
+#pragma GCC diagnostic ignored "-Wunused-variable"
+#pragma GCC diagnostic ignored "-Wunused-function"
+
+#include "jni.h"
+#include <nativehelper/JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/misc.h>
+
+#include <assert.h>
+#include <EGL/egl.h>
+
+#include <ui/ANativeObjectBase.h>
+
+static int initialized = 0;
+
+// classes from EGL 1.4
+static jclass egldisplayClass;
+static jclass eglsurfaceClass;
+static jclass eglconfigClass;
+static jclass eglcontextClass;
+static jclass bufferClass;
+static jclass nioAccessClass;
+
+static jfieldID positionID;
+static jfieldID limitID;
+static jfieldID elementSizeShiftID;
+
+static jmethodID getBasePointerID;
+static jmethodID getBaseArrayID;
+static jmethodID getBaseArrayOffsetID;
+
+static jmethodID egldisplayGetHandleID;
+static jmethodID eglconfigGetHandleID;
+static jmethodID eglcontextGetHandleID;
+static jmethodID eglsurfaceGetHandleID;
+
+static jmethodID egldisplayConstructor;
+static jmethodID eglcontextConstructor;
+static jmethodID eglsurfaceConstructor;
+static jmethodID eglconfigConstructor;
+
+static jobject eglNoContextObject;
+static jobject eglNoDisplayObject;
+static jobject eglNoSurfaceObject;
+
+// classes from EGL 1.5
+static jclass eglimageClass;
+static jclass eglsyncClass;
+
+static jmethodID eglimageGetHandleID;
+static jmethodID eglsyncGetHandleID;
+
+static jmethodID eglimageConstructor;
+static jmethodID eglsyncConstructor;
+
+static jobject eglNoImageObject;
+static jobject eglNoSyncObject;
+
+/* Cache method IDs each time the class is loaded. */
+
+static void
+nativeClassInit(JNIEnv *_env, jclass glImplClass)
+{
+    // EGL 1.4 Init
+    jclass eglconfigClassLocal = _env->FindClass("android/opengl/EGLConfig");
+    eglconfigClass = (jclass) _env->NewGlobalRef(eglconfigClassLocal);
+    jclass eglcontextClassLocal = _env->FindClass("android/opengl/EGLContext");
+    eglcontextClass = (jclass) _env->NewGlobalRef(eglcontextClassLocal);
+    jclass egldisplayClassLocal = _env->FindClass("android/opengl/EGLDisplay");
+    egldisplayClass = (jclass) _env->NewGlobalRef(egldisplayClassLocal);
+    jclass eglsurfaceClassLocal = _env->FindClass("android/opengl/EGLSurface");
+    eglsurfaceClass = (jclass) _env->NewGlobalRef(eglsurfaceClassLocal);
+
+    eglconfigGetHandleID = _env->GetMethodID(eglconfigClass, "getNativeHandle", "()J");
+    eglcontextGetHandleID = _env->GetMethodID(eglcontextClass, "getNativeHandle", "()J");
+    egldisplayGetHandleID = _env->GetMethodID(egldisplayClass, "getNativeHandle", "()J");
+    eglsurfaceGetHandleID = _env->GetMethodID(eglsurfaceClass, "getNativeHandle", "()J");
+
+
+    eglconfigConstructor = _env->GetMethodID(eglconfigClass, "<init>", "(J)V");
+    eglcontextConstructor = _env->GetMethodID(eglcontextClass, "<init>", "(J)V");
+    egldisplayConstructor = _env->GetMethodID(egldisplayClass, "<init>", "(J)V");
+    eglsurfaceConstructor = _env->GetMethodID(eglsurfaceClass, "<init>", "(J)V");
+
+    jobject localeglNoContextObject = _env->NewObject(eglcontextClass, eglcontextConstructor, reinterpret_cast<jlong>(EGL_NO_CONTEXT));
+    eglNoContextObject = _env->NewGlobalRef(localeglNoContextObject);
+    jobject localeglNoDisplayObject = _env->NewObject(egldisplayClass, egldisplayConstructor, reinterpret_cast<jlong>(EGL_NO_DISPLAY));
+    eglNoDisplayObject = _env->NewGlobalRef(localeglNoDisplayObject);
+    jobject localeglNoSurfaceObject = _env->NewObject(eglsurfaceClass, eglsurfaceConstructor, reinterpret_cast<jlong>(EGL_NO_SURFACE));
+    eglNoSurfaceObject = _env->NewGlobalRef(localeglNoSurfaceObject);
+
+
+    jclass eglClass = _env->FindClass("android/opengl/EGL15");
+    jfieldID noContextFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_CONTEXT", "Landroid/opengl/EGLContext;");
+    _env->SetStaticObjectField(eglClass, noContextFieldID, eglNoContextObject);
+
+    jfieldID noDisplayFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_DISPLAY", "Landroid/opengl/EGLDisplay;");
+    _env->SetStaticObjectField(eglClass, noDisplayFieldID, eglNoDisplayObject);
+
+    jfieldID noSurfaceFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_SURFACE", "Landroid/opengl/EGLSurface;");
+    _env->SetStaticObjectField(eglClass, noSurfaceFieldID, eglNoSurfaceObject);
+
+    // EGL 1.5 init
+    jclass nioAccessClassLocal = _env->FindClass("java/nio/NIOAccess");
+    nioAccessClass = (jclass) _env->NewGlobalRef(nioAccessClassLocal);
+
+    jclass bufferClassLocal = _env->FindClass("java/nio/Buffer");
+    bufferClass = (jclass) _env->NewGlobalRef(bufferClassLocal);
+
+    getBasePointerID = _env->GetStaticMethodID(nioAccessClass,
+            "getBasePointer", "(Ljava/nio/Buffer;)J");
+    getBaseArrayID = _env->GetStaticMethodID(nioAccessClass,
+            "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
+    getBaseArrayOffsetID = _env->GetStaticMethodID(nioAccessClass,
+            "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
+
+    positionID = _env->GetFieldID(bufferClass, "position", "I");
+    limitID = _env->GetFieldID(bufferClass, "limit", "I");
+    elementSizeShiftID =
+        _env->GetFieldID(bufferClass, "_elementSizeShift", "I");
+
+    jclass eglimageClassLocal = _env->FindClass("android/opengl/EGLImage");
+    eglimageClass = (jclass) _env->NewGlobalRef(eglimageClassLocal);
+    jclass eglsyncClassLocal = _env->FindClass("android/opengl/EGLSync");
+    eglsyncClass = (jclass) _env->NewGlobalRef(eglsyncClassLocal);
+
+    eglimageGetHandleID = _env->GetMethodID(eglimageClass, "getNativeHandle", "()J");
+    eglsyncGetHandleID = _env->GetMethodID(eglsyncClass, "getNativeHandle", "()J");
+
+    eglimageConstructor = _env->GetMethodID(eglimageClass, "<init>", "(J)V");
+    eglsyncConstructor = _env->GetMethodID(eglsyncClass, "<init>", "(J)V");
+
+    jfieldID noImageFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_IMAGE", "Landroid/opengl/EGLImage;");
+    _env->SetStaticObjectField(eglClass, noImageFieldID, eglNoImageObject);
+
+    jfieldID noSyncFieldID = _env->GetStaticFieldID(eglClass, "EGL_NO_SYNC", "Landroid/opengl/EGLSync;");
+    _env->SetStaticObjectField(eglClass, noSyncFieldID, eglNoSyncObject);
+}
+
+static void *
+getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *offset)
+{
+    jint position;
+    jint limit;
+    jint elementSizeShift;
+    jlong pointer;
+
+    position = _env->GetIntField(buffer, positionID);
+    limit = _env->GetIntField(buffer, limitID);
+    elementSizeShift = _env->GetIntField(buffer, elementSizeShiftID);
+    *remaining = (limit - position) << elementSizeShift;
+    pointer = _env->CallStaticLongMethod(nioAccessClass,
+            getBasePointerID, buffer);
+    if (pointer != 0L) {
+        *array = NULL;
+        return reinterpret_cast<void*>(pointer);
+    }
+    eglimageGetHandleID = _env->GetMethodID(eglimageClass, "getNativeHandle", "()J");
+    eglsyncGetHandleID = _env->GetMethodID(eglsyncClass, "getNativeHandle", "()J");
+
+    *array = (jarray) _env->CallStaticObjectMethod(nioAccessClass,
+            getBaseArrayID, buffer);
+    *offset = _env->CallStaticIntMethod(nioAccessClass,
+            getBaseArrayOffsetID, buffer);
+
+    return NULL;
+}
+
+static void
+releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
+{
+    _env->ReleasePrimitiveArrayCritical(array, data,
+                       commit ? 0 : JNI_ABORT);
+}
+
+static void *
+fromEGLHandle(JNIEnv *_env, jmethodID mid, jobject obj) {
+    if (obj == NULL){
+        jniThrowException(_env, "java/lang/IllegalArgumentException",
+                          "Object is set to null.");
+    }
+
+    jlong handle = _env->CallLongMethod(obj, mid);
+    return reinterpret_cast<void*>(handle);
+}
+
+static jobject
+toEGLHandle(JNIEnv *_env, jclass cls, jmethodID con, void * handle) {
+    if (cls == eglimageClass &&
+       (EGLImage)handle == EGL_NO_IMAGE) {
+           return eglNoImageObject;
+    }
+
+    return _env->NewObject(cls, con, reinterpret_cast<jlong>(handle));
+}
+
+// --------------------------------------------------------------------------
+/* EGLSync eglCreateSync ( EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list ) */
+static jobject
+android_eglCreateSync
+  (JNIEnv *_env, jobject _this, jobject dpy, jint type, jlongArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType = NULL;
+    const char * _exceptionMessage = NULL;
+    EGLSync _returnValue = (EGLSync) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLAttrib *attrib_list_base = (EGLAttrib *) 0;
+    jint _remaining;
+    EGLAttrib *attrib_list = (EGLAttrib *) 0;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLAttrib *)
+        _env->GetLongArrayElements(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+
+    _returnValue = eglCreateSync(
+        (EGLDisplay)dpy_native,
+        (EGLenum)type,
+        (EGLAttrib *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleaseLongArrayElements(attrib_list_ref, (jlong*)attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, eglsyncClass, eglsyncConstructor, _returnValue);
+}
+
+/* EGLBoolean eglDestroySync ( EGLDisplay dpy, EGLSync sync ) */
+static jboolean
+android_eglDestroySync
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject sync) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSync sync_native = (EGLSync) fromEGLHandle(_env, eglsyncGetHandleID, sync);
+
+    _returnValue = eglDestroySync(
+        (EGLDisplay)dpy_native,
+        (EGLSync)sync_native
+    );
+    return (jboolean)_returnValue;
+}
+
+/* EGLint eglClientWaitSync ( EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout ) */
+static jint
+android_eglClientWaitSync
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject sync, jint flags, jlong timeout) {
+    EGLint _returnValue = (EGLint) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSync sync_native = (EGLSync) fromEGLHandle(_env, eglsyncGetHandleID, sync);
+
+    _returnValue = eglClientWaitSync(
+        (EGLDisplay)dpy_native,
+        (EGLSync)sync_native,
+        (EGLint)flags,
+        (EGLTime)timeout
+    );
+    return (jint)_returnValue;
+}
+
+/* EGLBoolean eglGetSyncAttrib ( EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value ) */
+static jboolean
+android_eglGetSyncAttrib
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject sync, jint attribute, jlongArray value_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType = NULL;
+    const char * _exceptionMessage = NULL;
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSync sync_native = (EGLSync) fromEGLHandle(_env, eglsyncGetHandleID, sync);
+    EGLAttrib *value_base = (EGLAttrib *) 0;
+    jint _remaining;
+    EGLAttrib *value = (EGLAttrib *) 0;
+
+    if (!value_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "value == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(value_ref) - offset;
+    value_base = (EGLAttrib *)
+        _env->GetLongArrayElements(value_ref, (jboolean *)0);
+    value = value_base + offset;
+
+    _returnValue = eglGetSyncAttrib(
+        (EGLDisplay)dpy_native,
+        (EGLSync)sync_native,
+        (EGLint)attribute,
+        (EGLAttrib *)value
+    );
+
+exit:
+    if (value_base) {
+        _env->ReleaseLongArrayElements(value_ref, (jlong*)value_base,
+            _exception ? JNI_ABORT: 0);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return (jboolean)_returnValue;
+}
+
+/* EGLDisplay eglGetPlatformDisplay ( EGLenum platform, EGLAttrib native_display, const EGLAttrib *attrib_list ) */
+static jobject
+android_eglGetPlatformDisplay
+  (JNIEnv *_env, jobject _this, jint platform, jlong native_display, jlongArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType = NULL;
+    const char * _exceptionMessage = NULL;
+    EGLDisplay _returnValue = (EGLDisplay) 0;
+    EGLAttrib *attrib_list_base = (EGLAttrib *) 0;
+    jint _remaining;
+    EGLAttrib *attrib_list = (EGLAttrib *) 0;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLAttrib *)
+        _env->GetLongArrayElements(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+
+    _returnValue = eglGetPlatformDisplay(
+        (EGLenum)platform,
+        (void *)native_display,
+        (EGLAttrib *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleaseLongArrayElements(attrib_list_ref, (jlong*)attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, egldisplayClass, egldisplayConstructor, _returnValue);
+}
+
+/* EGLSurface eglCreatePlatformWindowSurface ( EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list ) */
+static jobject
+android_eglCreatePlatformWindowSurface
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject native_window_buf, jlongArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType = NULL;
+    const char * _exceptionMessage = NULL;
+    jarray _array = (jarray) 0;
+    jint _bufferOffset = (jint) 0;
+    EGLSurface _returnValue = (EGLSurface) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLConfig config_native = (EGLConfig) fromEGLHandle(_env, eglconfigGetHandleID, config);
+    jint _native_windowRemaining;
+    void *native_window = (void *) 0;
+    EGLAttrib *attrib_list_base = (EGLAttrib *) 0;
+    jint _attrib_listRemaining;
+    EGLAttrib *attrib_list = (EGLAttrib *) 0;
+
+    if (!native_window_buf) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "native_window == null";
+        goto exit;
+    }
+    native_window = (void *)getPointer(_env, native_window_buf, (jarray*)&_array, &_native_windowRemaining, &_bufferOffset);
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _attrib_listRemaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLAttrib *)
+        _env->GetLongArrayElements(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+
+    if (native_window == NULL) {
+        char * _native_windowBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
+        native_window = (void *) (_native_windowBase + _bufferOffset);
+    }
+    _returnValue = eglCreatePlatformWindowSurface(
+        (EGLDisplay)dpy_native,
+        (EGLConfig)config_native,
+        (void *)native_window,
+        (EGLAttrib *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleaseLongArrayElements(attrib_list_ref, (jlong*)attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_array) {
+        releasePointer(_env, _array, native_window, _exception ? JNI_FALSE : JNI_TRUE);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, _returnValue);
+}
+
+/* EGLSurface eglCreatePlatformPixmapSurface ( EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list ) */
+static jobject
+android_eglCreatePlatformPixmapSurface
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject config, jobject native_pixmap_buf, jlongArray attrib_list_ref, jint offset) {
+    jniThrowException(_env, "java/lang/UnsupportedOperationException",
+        "eglCreatePlatformPixmapSurface");
+    return toEGLHandle(_env, eglsurfaceClass, eglsurfaceConstructor, (EGLSurface) 0);
+}
+
+/* EGLBoolean eglWaitSync ( EGLDisplay dpy, EGLSync sync, EGLint flags ) */
+static jboolean
+android_eglWaitSync
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject sync, jint flags) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLSync sync_native = (EGLSync) fromEGLHandle(_env, eglsyncGetHandleID, sync);
+
+    _returnValue = eglWaitSync(
+        (EGLDisplay)dpy_native,
+        (EGLSync)sync_native,
+        (EGLint)flags
+    );
+    return (jboolean)_returnValue;
+}
+
+/* EGLImage eglCreateImage ( EGLDisplay dpy, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list ) */
+static jobject
+android_eglCreateImage
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject context, jint target, jlong buffer, jlongArray attrib_list_ref, jint offset) {
+    jint _exception = 0;
+    const char * _exceptionType = NULL;
+    const char * _exceptionMessage = NULL;
+    EGLImage _returnValue = (EGLImage) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLContext context_native = (EGLContext) fromEGLHandle(_env, eglcontextGetHandleID, context);
+    EGLAttrib *attrib_list_base = (EGLAttrib *) 0;
+    jint _remaining;
+    EGLAttrib *attrib_list = (EGLAttrib *) 0;
+
+    if (!attrib_list_ref) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "attrib_list == null";
+        goto exit;
+    }
+    if (offset < 0) {
+        _exception = 1;
+        _exceptionType = "java/lang/IllegalArgumentException";
+        _exceptionMessage = "offset < 0";
+        goto exit;
+    }
+    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
+    attrib_list_base = (EGLAttrib *)
+        _env->GetLongArrayElements(attrib_list_ref, (jboolean *)0);
+    attrib_list = attrib_list_base + offset;
+
+    _returnValue = eglCreateImage(
+        (EGLDisplay)dpy_native,
+        (EGLContext)context_native,
+        (EGLenum)target,
+        (EGLClientBuffer)buffer,
+        (EGLAttrib *)attrib_list
+    );
+
+exit:
+    if (attrib_list_base) {
+        _env->ReleaseLongArrayElements(attrib_list_ref, (jlong*)attrib_list_base,
+            JNI_ABORT);
+    }
+    if (_exception) {
+        jniThrowException(_env, _exceptionType, _exceptionMessage);
+    }
+    return toEGLHandle(_env, eglimageClass, eglimageConstructor, _returnValue);
+}
+
+/* EGLBoolean eglDestroyImage ( EGLDisplay dpy, EGLImage image ) */
+static jboolean
+android_eglDestroyImage
+  (JNIEnv *_env, jobject _this, jobject dpy, jobject image) {
+    EGLBoolean _returnValue = (EGLBoolean) 0;
+    EGLDisplay dpy_native = (EGLDisplay) fromEGLHandle(_env, egldisplayGetHandleID, dpy);
+    EGLImage image_native = (EGLImage) fromEGLHandle(_env, eglimageGetHandleID, image);
+
+    _returnValue = eglDestroyImage(
+        (EGLDisplay)dpy_native,
+        (EGLImage)image_native
+    );
+    return (jboolean)_returnValue;
+}
+
+static const char *classPathName = "android/opengl/EGL15";
+
+static const JNINativeMethod methods[] = {
+{"_nativeClassInit", "()V", (void*)nativeClassInit },
+{"eglCreateSync", "(Landroid/opengl/EGLDisplay;I[JI)Landroid/opengl/EGLSync;", (void *) android_eglCreateSync },
+{"eglDestroySync", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;)Z", (void *) android_eglDestroySync },
+{"eglClientWaitSync", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;IJ)I", (void *) android_eglClientWaitSync },
+{"eglGetSyncAttrib", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;I[JI)Z", (void *) android_eglGetSyncAttrib },
+{"eglGetPlatformDisplay", "(IJ[JI)Landroid/opengl/EGLDisplay;", (void *) android_eglGetPlatformDisplay },
+{"eglCreatePlatformWindowSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/nio/Buffer;[JI)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePlatformWindowSurface },
+{"eglCreatePlatformPixmapSurface", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLConfig;Ljava/nio/Buffer;[JI)Landroid/opengl/EGLSurface;", (void *) android_eglCreatePlatformPixmapSurface },
+{"eglWaitSync", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLSync;I)Z", (void *) android_eglWaitSync },
+{"eglCreateImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLContext;IJ[JI)Landroid/opengl/EGLImage;", (void *) android_eglCreateImage },
+{"eglDestroyImage", "(Landroid/opengl/EGLDisplay;Landroid/opengl/EGLImage;)Z", (void *) android_eglDestroyImage },
+};
+
+int register_android_opengl_jni_EGL15(JNIEnv *_env)
+{
+    int err;
+    err = android::AndroidRuntime::registerNativeMethods(_env, classPathName, methods, NELEM(methods));
+    return err;
+}
diff --git a/core/jni/android_os_GraphicsEnvironment.cpp b/core/jni/android_os_GraphicsEnvironment.cpp
index b70485d..e64da5c 100644
--- a/core/jni/android_os_GraphicsEnvironment.cpp
+++ b/core/jni/android_os_GraphicsEnvironment.cpp
@@ -23,17 +23,25 @@
 
 namespace {
 
+int getCanLoadSystemLibraries_native() {
+    return android::GraphicsEnv::getInstance().getCanLoadSystemLibraries();
+}
+
 void setDriverPath(JNIEnv* env, jobject clazz, jstring path) {
     ScopedUtfChars pathChars(env, path);
     android::GraphicsEnv::getInstance().setDriverPath(pathChars.c_str());
 }
 
-void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName, jstring appPref, jboolean devOptIn) {
+void setAngleInfo_native(JNIEnv* env, jobject clazz, jstring path, jstring appName, jstring appPref, jboolean devOptIn,
+                         jobject rulesFd, jlong rulesOffset, jlong rulesLength) {
     ScopedUtfChars pathChars(env, path);
     ScopedUtfChars appNameChars(env, appName);
     ScopedUtfChars appPrefChars(env, appPref);
+
+    int rulesFd_native = jniGetFDFromFileDescriptor(env, rulesFd);
+
     android::GraphicsEnv::getInstance().setAngleInfo(pathChars.c_str(), appNameChars.c_str(),
-            appPrefChars.c_str(), devOptIn);
+            appPrefChars.c_str(), devOptIn, rulesFd_native, rulesOffset, rulesLength);
 }
 
 void setLayerPaths_native(JNIEnv* env, jobject clazz, jobject classLoader, jstring layerPaths) {
@@ -51,8 +59,9 @@
 }
 
 const JNINativeMethod g_methods[] = {
+    { "getCanLoadSystemLibraries", "()I", reinterpret_cast<void*>(getCanLoadSystemLibraries_native) },
     { "setDriverPath", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDriverPath) },
-    { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", reinterpret_cast<void*>(setAngleInfo_native) },
+    { "setAngleInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/io/FileDescriptor;JJ)V", reinterpret_cast<void*>(setAngleInfo_native) },
     { "setLayerPaths", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V", reinterpret_cast<void*>(setLayerPaths_native) },
     { "setDebugLayers", "(Ljava/lang/String;)V", reinterpret_cast<void*>(setDebugLayers_native) },
 };
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index ecad6c0..ec98080 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -23,6 +23,7 @@
 #include <atomic>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <mutex>
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -69,6 +70,7 @@
     // Class state.
     jclass mClass;
     jmethodID mExecTransact;
+    jmethodID mGetInterfaceDescriptor;
 
     // Object state.
     jfieldID mObject;
@@ -326,8 +328,32 @@
         env->DeleteGlobalRef(mObject);
     }
 
-    virtual status_t onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
+    const String16& getInterfaceDescriptor() const override
+    {
+        call_once(mPopulateDescriptor, [this] {
+            JNIEnv* env = javavm_to_jnienv(mVM);
+
+            ALOGV("getInterfaceDescriptor() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
+
+            jstring descriptor = (jstring)env->CallObjectMethod(mObject, gBinderOffsets.mGetInterfaceDescriptor);
+
+            if (descriptor == nullptr) {
+                return;
+            }
+
+            static_assert(sizeof(jchar) == sizeof(char16_t), "");
+            const jchar* descriptorChars = env->GetStringChars(descriptor, nullptr);
+            const char16_t* rawDescriptor = reinterpret_cast<const char16_t*>(descriptorChars);
+            jsize rawDescriptorLen = env->GetStringLength(descriptor);
+            mDescriptor = String16(rawDescriptor, rawDescriptorLen);
+            env->ReleaseStringChars(descriptor, descriptorChars);
+        });
+
+        return mDescriptor;
+    }
+
+    status_t onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
     {
         JNIEnv* env = javavm_to_jnienv(mVM);
 
@@ -376,7 +402,7 @@
         return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
     }
 
-    virtual status_t dump(int fd, const Vector<String16>& args)
+    status_t dump(int fd, const Vector<String16>& args) override
     {
         return 0;
     }
@@ -384,6 +410,9 @@
 private:
     JavaVM* const   mVM;
     jobject const   mObject;  // GlobalRef to Java Binder
+
+    mutable std::once_flag mPopulateDescriptor;
+    mutable String16 mDescriptor;
 };
 
 // ----------------------------------------------------------------------------
@@ -875,6 +904,21 @@
     return IPCThreadState::self()->getStrictModePolicy();
 }
 
+static jint android_os_Binder_setThreadWorkSource(jint workSource)
+{
+    return IPCThreadState::self()->setWorkSource(workSource);
+}
+
+static jint android_os_Binder_getThreadWorkSource()
+{
+    return IPCThreadState::self()->getWorkSource();
+}
+
+static jint android_os_Binder_clearThreadWorkSource()
+{
+    return IPCThreadState::self()->clearWorkSource();
+}
+
 static void android_os_Binder_flushPendingCommands(JNIEnv* env, jobject clazz)
 {
     IPCThreadState::self()->flushCommands();
@@ -912,6 +956,12 @@
     { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
     { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
     { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
+    // @CriticalNative
+    { "setThreadWorkSource", "(I)I", (void*)android_os_Binder_setThreadWorkSource },
+    // @CriticalNative
+    { "getThreadWorkSource", "()I", (void*)android_os_Binder_getThreadWorkSource },
+    // @CriticalNative
+    { "clearThreadWorkSource", "()I", (void*)android_os_Binder_clearThreadWorkSource },
     { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
     { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
     { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
@@ -926,6 +976,8 @@
 
     gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
     gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
+    gBinderOffsets.mGetInterfaceDescriptor = GetMethodIDOrDie(env, clazz, "getInterfaceDescriptor",
+        "()Ljava/lang/String;");
     gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
 
     return RegisterMethodsOrDie(
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 62aa1f38..4c7defb 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -51,6 +51,8 @@
 
 static const bool kDebugPolicy = false;
 static const bool kDebugProc = false;
+// When reading `proc` files, how many bytes to read at a time
+static const int kReadSize = 4096;
 
 #if GUARD_THREAD_PRIORITY
 Mutex gKeyCreateMutex;
@@ -1034,21 +1036,35 @@
     }
     env->ReleaseStringUTFChars(file, file8);
 
-    char buffer[256];
-    const int len = read(fd, buffer, sizeof(buffer)-1);
+    std::vector<char> fileBuffer(kReadSize);
+    int numBytesRead = 0;
+    while (true) {
+        // Resize buffer to make space for contents. This might be more than we need, but once we've
+        // read we resize back down
+        fileBuffer.resize(numBytesRead + kReadSize, 0);
+        // Read in contents
+        int len = TEMP_FAILURE_RETRY(read(fd, fileBuffer.data() + numBytesRead, kReadSize));
+        numBytesRead += len;
+        if (len < 0) {
+            // If `len` is negative, an error occurred on read
+            if (kDebugProc) {
+                ALOGW("Unable to open process file: %s fd=%d\n", file8, fd);
+            }
+            close(fd);
+            return JNI_FALSE;
+        } else if (len == 0) {
+            // If nothing read, we're done
+            break;
+        }
+    }
+    // Resize back down to the amount we read
+    fileBuffer.resize(numBytesRead);
+    // Terminate buffer with null byte
+    fileBuffer.push_back('\0');
     close(fd);
 
-    if (len < 0) {
-        if (kDebugProc) {
-            ALOGW("Unable to open process file: %s fd=%d\n", file8, fd);
-        }
-        return JNI_FALSE;
-    }
-    buffer[len] = 0;
-
-    return android_os_Process_parseProcLineArray(env, clazz, buffer, 0, len,
+    return android_os_Process_parseProcLineArray(env, clazz, fileBuffer.data(), 0, numBytesRead,
             format, outStrings, outLongs, outFloats);
-
 }
 
 void android_os_Process_setApplicationObject(JNIEnv* env, jobject clazz,
diff --git a/core/jni/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp
index 4fdd2bc..8998cd7 100644
--- a/core/jni/android_view_DisplayListCanvas.cpp
+++ b/core/jni/android_view_DisplayListCanvas.cpp
@@ -183,7 +183,7 @@
 // JNI Glue
 // ----------------------------------------------------------------------------
 
-const char* const kClassPathName = "android/view/DisplayListCanvas";
+const char* const kClassPathName = "android/graphics/RecordingCanvas";
 
 static JNINativeMethod gMethods[] = {
 
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 0a90b97..2f17907 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -202,17 +202,9 @@
     if (parcel) {
         bool isInitialized = parcel->readInt32();
         if (isInitialized) {
-            String8 name = parcel->readString8();
-            int rawFd = parcel->readFileDescriptor();
-            int dupFd = dup(rawFd);
-            if (dupFd < 0) {
-                ALOGE("Error %d dup channel fd %d.", errno, rawFd);
-                jniThrowRuntimeException(env,
-                        "Could not read input channel file descriptors from parcel.");
-                return;
-            }
+            InputChannel* inputChannel = new InputChannel();
+            inputChannel->read(*parcel);
 
-            InputChannel* inputChannel = new InputChannel(name.string(), dupFd);
             NativeInputChannel* nativeInputChannel = new NativeInputChannel(inputChannel);
 
             android_view_InputChannel_setNativeInputChannel(env, obj, nativeInputChannel);
@@ -230,8 +222,7 @@
             sp<InputChannel> inputChannel = nativeInputChannel->getInputChannel();
 
             parcel->writeInt32(1);
-            parcel->writeString8(String8(inputChannel->getName().c_str()));
-            parcel->writeDupFileDescriptor(inputChannel->getFd());
+            inputChannel->write(*parcel);
         } else {
             parcel->writeInt32(0);
         }
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 63b0046..bb71a5d 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -576,7 +576,7 @@
 // JNI Glue
 // ----------------------------------------------------------------------------
 
-const char* const kClassPathName = "android/view/RenderNode";
+const char* const kClassPathName = "android/graphics/RenderNode";
 
 static const JNINativeMethod gMethods[] = {
 // ----------------------------------------------------------------------------
@@ -588,7 +588,7 @@
     { "nGetDebugSize",         "(J)I",    (void*) android_view_RenderNode_getDebugSize },
     { "nAddAnimator",              "(JJ)V", (void*) android_view_RenderNode_addAnimator },
     { "nEndAllAnimators",          "(J)V", (void*) android_view_RenderNode_endAllAnimators },
-    { "nRequestPositionUpdates",   "(JLandroid/view/RenderNode$PositionUpdateListener;)V", (void*) android_view_RenderNode_requestPositionUpdates },
+    { "nRequestPositionUpdates",   "(JLandroid/graphics/RenderNode$PositionUpdateListener;)V", (void*) android_view_RenderNode_requestPositionUpdates },
     { "nSetDisplayList",       "(JJ)V",   (void*) android_view_RenderNode_setDisplayList },
 
 
@@ -677,7 +677,7 @@
 };
 
 int register_android_view_RenderNode(JNIEnv* env) {
-    jclass clazz = FindClassOrDie(env, "android/view/RenderNode$PositionUpdateListener");
+    jclass clazz = FindClassOrDie(env, "android/graphics/RenderNode$PositionUpdateListener");
     gPositionListener_PositionChangedMethod = GetMethodIDOrDie(env, clazz,
             "positionChanged", "(JIIII)V");
     gPositionListener_PositionLostMethod = GetMethodIDOrDie(env, clazz,
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index b70177f..4eda3ab 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -166,8 +166,10 @@
     }
     Rect sourceCrop = rectFromObj(env, sourceCropObj);
     sp<GraphicBuffer> buffer;
-    status_t res = ScreenshotClient::capture(displayToken, sourceCrop, width, height,
-            useIdentityTransform, rotation, &buffer);
+    status_t res = ScreenshotClient::capture(displayToken, ui::Dataspace::V0_SRGB,
+                                             ui::PixelFormat::RGBA_8888,
+                                             sourceCrop, width, height,
+                                             useIdentityTransform, rotation, &buffer);
     if (res != NO_ERROR) {
         return NULL;
     }
@@ -195,7 +197,9 @@
     }
 
     sp<GraphicBuffer> buffer;
-    status_t res = ScreenshotClient::captureChildLayers(layerHandle, sourceCrop, frameScale, &buffer);
+    status_t res = ScreenshotClient::captureChildLayers(layerHandle, ui::Dataspace::V0_SRGB,
+                                                        ui::PixelFormat::RGBA_8888, sourceCrop,
+                                                        frameScale, &buffer);
     if (res != NO_ERROR) {
         return NULL;
     }
@@ -339,6 +343,17 @@
     transaction->setMatrix(ctrl, dsdx, dtdx, dtdy, dsdy);
 }
 
+static void nativeSetColorTransform(JNIEnv* env, jclass clazz, jlong transactionObj,
+        jlong nativeObject, jfloatArray fMatrix, jfloatArray fTranslation) {
+    auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+    SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
+    float* floatMatrix = env->GetFloatArrayElements(fMatrix, 0);
+    mat3 matrix(static_cast<float const*>(floatMatrix));
+    float* floatTranslation = env->GetFloatArrayElements(fTranslation, 0);
+    vec3 translation(floatTranslation[0], floatTranslation[1], floatTranslation[2]);
+    transaction->setColorTransform(surfaceControl, matrix, translation);
+}
+
 static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
         jlong nativeObject,
         jint l, jint t, jint r, jint b) {
@@ -849,6 +864,8 @@
             (void*)nativeSetColor },
     {"nativeSetMatrix", "(JJFFFF)V",
             (void*)nativeSetMatrix },
+    {"nativeSetColorTransform", "(JJ[F[F)V",
+            (void*)nativeSetColorTransform },
     {"nativeSetFlags", "(JJII)V",
             (void*)nativeSetFlags },
     {"nativeSetWindowCrop", "(JJIIII)V",
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index dc04269..5eefc81 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -176,7 +176,6 @@
     void** args = reinterpret_cast<void**>(arg);
     jstring* javaNativeLibPath = (jstring*) args[0];
     jboolean extractNativeLibs = *(jboolean*) args[1];
-    jboolean hasNativeBridge = *(jboolean*) args[2];
 
     ScopedUtfChars nativeLibPath(env, *javaNativeLibPath);
 
@@ -206,9 +205,7 @@
             return INSTALL_FAILED_INVALID_APK;
         }
 
-        if (!hasNativeBridge) {
-          return INSTALL_SUCCEEDED;
-        }
+        return INSTALL_SUCCEEDED;
     }
 
     // Build local file path
@@ -489,9 +486,9 @@
 static jint
 com_android_internal_content_NativeLibraryHelper_copyNativeBinaries(JNIEnv *env, jclass clazz,
         jlong apkHandle, jstring javaNativeLibPath, jstring javaCpuAbi,
-        jboolean extractNativeLibs, jboolean hasNativeBridge, jboolean debuggable)
+        jboolean extractNativeLibs, jboolean debuggable)
 {
-    void* args[] = { &javaNativeLibPath, &extractNativeLibs, &hasNativeBridge };
+    void* args[] = { &javaNativeLibPath, &extractNativeLibs };
     return (jint) iterateOverNativeFiles(env, apkHandle, javaCpuAbi, debuggable,
             copyFileIfChanged, reinterpret_cast<void*>(args));
 }
@@ -597,7 +594,7 @@
             "(J)V",
             (void *)com_android_internal_content_NativeLibraryHelper_close},
     {"nativeCopyNativeBinaries",
-            "(JLjava/lang/String;Ljava/lang/String;ZZZ)I",
+            "(JLjava/lang/String;Ljava/lang/String;ZZ)I",
             (void *)com_android_internal_content_NativeLibraryHelper_copyNativeBinaries},
     {"nativeSumNativeBinaries",
             "(JLjava/lang/String;Z)J",
diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
index 109e65c..b3ff4db 100644
--- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
+++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
@@ -32,8 +32,8 @@
 #include <utils/misc.h>
 
 #include "android-base/unique_fd.h"
-#include "bpf/BpfNetworkStats.h"
 #include "bpf/BpfUtils.h"
+#include "netdbpf/BpfNetworkStats.h"
 
 using android::bpf::hasBpfSupport;
 using android::bpf::parseBpfNetworkStatsDetail;
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 1f95862..3e04bb3 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -56,6 +56,7 @@
 #include <utils/String8.h>
 #include <selinux/android.h>
 #include <seccomp_policy.h>
+#include <stats_event_list.h>
 #include <processgroup/processgroup.h>
 
 #include "core_jni_helpers.h"
@@ -932,6 +933,7 @@
   // Close any logging related FDs before we start evaluating the list of
   // file descriptors.
   __android_log_close();
+  stats_log_close();
 
   std::string error_msg;
 
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index ed42e2e..30a9a01 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -7,6 +7,8 @@
 joeo@google.com
 kwekua@google.com
 singhtejinder@google.com
+yanglu@google.com
+yaochen@google.com
 
 # Frameworks
 ogunwale@google.com
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
new file mode 100644
index 0000000..2797550
--- /dev/null
+++ b/core/proto/android/app/settings_enums.proto
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+
+package android.app.settings;
+option java_multiple_files = true;
+
+/**
+ * The action performed in this event
+ */
+enum Action {
+    ACTION_UNKNOWN = 0;
+    PAGE_VISIBLE = 1;
+    PAGE_HIDE = 2;
+    PREF_CHANGE = 3;
+}
+
+/**
+ * Id for Settings pages. Each page must have its own unique Id.
+ */
+enum PageId {
+  // Unknown page. Should not be used in production code.
+  PAGE_UNKNOWN = 0;
+
+  // OPEN: Settings homepage
+  SETTINGS_HOMEPAGE = 1502;
+
+  // OPEN: Settings > System > Input & Gesture > Wake screen
+  SETTINGS_GESTURE_WAKE_SCREEN = 1570;
+
+  // OPEN: Settings > Network & internet > Mobile network
+  MOBILE_NETWORK = 1571;
+
+  // OPEN: Settings > Network & internet > Mobile network > Choose network
+  MOBILE_NETWORK_SELECT = 1581;
+
+  // OPEN: Settings > Network & internet > Mobile network > Mobile Data > Dialog
+  MOBILE_DATA_DIALOG = 1582;
+
+  // OPEN: Settings > Network & internet > Mobile network > Data roaming > Dialog
+  MOBILE_ROAMING_DIALOG = 1583;
+
+  // Settings > Display > Lock screen display > On lock screen
+  LOCK_SCREEN_NOTIFICATION_CONTENT = 1584;
+}
+
diff --git a/core/proto/android/internal/powerprofile.proto b/core/proto/android/internal/powerprofile.proto
new file mode 100644
index 0000000..b0c8b56
--- /dev/null
+++ b/core/proto/android/internal/powerprofile.proto
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+package com.android.internal.os;
+
+option java_multiple_files = true;
+
+// next: 41
+message PowerProfileProto {
+    optional double cpu_suspend = 1;
+
+    optional double cpu_idle = 2;
+
+    optional double cpu_active = 3;
+
+    message CpuCluster {
+        optional int32 id = 1;
+        optional double cluster_power = 2;
+        optional int32 cores = 3;
+        repeated int64 speed = 4;
+        repeated double core_power = 5;
+    }
+
+    repeated CpuCluster cpu_cluster = 40;
+
+    optional double wifi_scan = 4;
+
+    optional double wifi_on = 5;
+
+    optional double wifi_active = 6;
+
+    optional double wifi_controller_idle = 7;
+
+    optional double wifi_controller_rx = 8;
+
+    optional double wifi_controller_tx = 9;
+
+    repeated double wifi_controller_tx_levels = 10;
+
+    optional double wifi_controller_operating_voltage = 11;
+
+    optional double bluetooth_controller_idle = 12;
+
+    optional double bluetooth_controller_rx = 13;
+
+    optional double bluetooth_controller_tx = 14;
+
+    optional double bluetooth_controller_operating_voltage = 15;
+
+    optional double modem_controller_sleep = 16;
+
+    optional double modem_controller_idle = 17;
+
+    optional double modem_controller_rx = 18;
+
+    repeated double modem_controller_tx = 19;
+
+    optional double modem_controller_operating_voltage = 20;
+
+    optional double gps_on = 21;
+
+    repeated double gps_signal_quality_based = 22;
+
+    optional double gps_operating_voltage = 23;
+
+    optional double bluetooth_on = 24;
+
+    optional double bluetooth_active = 25;
+
+    optional double bluetooth_at_cmd = 26;
+
+    optional double ambient_display = 27;
+
+    optional double screen_on = 28;
+
+    optional double radio_on = 29;
+
+    optional double radio_scanning = 30;
+
+    optional double radio_active = 31;
+
+    optional double screen_full = 32;
+
+    optional double audio = 33;
+
+    optional double video = 34;
+
+    optional double flashlight = 35;
+
+    optional double memory = 36;
+
+    optional double camera = 37;
+
+    optional double wifi_batched_scan = 38;
+
+    optional double battery_capacity = 39;
+}
diff --git a/core/proto/android/os/system_properties.proto b/core/proto/android/os/system_properties.proto
index a41edf3..1f63be9 100644
--- a/core/proto/android/os/system_properties.proto
+++ b/core/proto/android/os/system_properties.proto
@@ -512,7 +512,9 @@
         optional int32  vts_coverage = 43;
         optional string zygote = 44;
 
-        // Next Tag: 45
+        optional string gfx_driver_whitelist_0 = 45;
+
+        // Next Tag: 46
     }
     optional Ro ro = 21;
 
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 14ed9e6..47dbc07 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -397,9 +397,10 @@
         // Ordered GPU debug layer list
         // i.e. <layer1>:<layer2>:...:<layerN>
         optional SettingProto debug_layers = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
-
         // App will load ANGLE instead of native GLES drivers.
         optional SettingProto angle_enabled_app = 3;
+        // App that can provide layer libraries.
+        optional SettingProto debug_layer_app = 4;
     }
     optional Gpu gpu = 59;
 
@@ -742,6 +743,7 @@
         optional SettingProto short_code_rule = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
         optional SettingProto short_codes_update_content_url = 5;
         optional SettingProto short_codes_update_metadata_url = 6;
+        optional SettingProto access_restriction_enabled = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
     }
     optional Sms sms = 109;
 
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index d33ea0c..c1c86f0 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -158,6 +158,7 @@
     optional ScreenRotationAnimationProto screen_rotation_animation = 12;
     optional DisplayFramesProto display_frames = 13;
     optional int32 surface_size = 14;
+    optional string focused_app = 15;
 }
 
 /* represents DisplayFrames */
diff --git a/proto/src/stats_enums.proto b/core/proto/android/stats/enums.proto
similarity index 91%
rename from proto/src/stats_enums.proto
rename to core/proto/android/stats/enums.proto
index 6c892cf..2320a01 100644
--- a/proto/src/stats_enums.proto
+++ b/core/proto/android/stats/enums.proto
@@ -16,8 +16,7 @@
 
 syntax = "proto2";
 
-package android.os.statsd;
-option java_package = "com.android.os";
+package android.stats;
 option java_outer_classname = "StatsEnums";
 
 enum EventType {
diff --git a/core/proto/android/telephony/enums.proto b/core/proto/android/telephony/enums.proto
index 32975a5..fba2e51 100644
--- a/core/proto/android/telephony/enums.proto
+++ b/core/proto/android/telephony/enums.proto
@@ -61,3 +61,64 @@
     SIGNAL_STRENGTH_GOOD = 3;
     SIGNAL_STRENGTH_GREAT = 4;
 }
+
+
+enum ServiceStateEnum {
+    /**
+     * Normal operation condition, the phone is registered
+     * with an operator either in home network or in roaming.
+     */
+    SERVICE_STATE_IN_SERVICE = 0;
+
+    /**
+     * Phone is not registered with any operator, the phone
+     * can be currently searching a new operator to register to, or not
+     * searching to registration at all, or registration is denied, or radio
+     * signal is not available.
+     */
+    SERVICE_STATE_OUT_OF_SERVICE = 1;
+
+    /**
+     * The phone is registered and locked.  Only emergency numbers are allowed. {@more}
+     */
+    SERVICE_STATE_EMERGENCY_ONLY = 2;
+
+    /**
+     * Radio of telephony is explicitly powered off.
+     */
+    SERVICE_STATE_POWER_OFF = 3;
+}
+
+enum SimStateEnum {
+    SIM_STATE_UNKNOWN = 0;
+    /** SIM card state: no SIM card is available in the device */
+    SIM_STATE_ABSENT = 1;
+    /** SIM card state: Locked: requires the user's SIM PIN to unlock */
+    SIM_STATE_PIN_REQUIRED = 2;
+    /** SIM card state: Locked: requires the user's SIM PUK to unlock */
+    SIM_STATE_PUK_REQUIRED = 3;
+    /** SIM card state: Locked: requires a network PIN to unlock */
+    SIM_STATE_NETWORK_LOCKED = 4;
+    /** SIM card state: Ready */
+    SIM_STATE_READY = 5;
+    /** SIM card state: SIM Card is NOT READY */
+    SIM_STATE_NOT_READY = 6;
+    /** SIM card state: SIM Card Error, permanently disabled */
+    SIM_STATE_PERM_DISABLED = 7;
+    /** SIM card state: SIM Card Error, present but faulty */
+    SIM_STATE_CARD_IO_ERROR = 8;
+    /** SIM card state: SIM Card restricted, present but not usable due to
+     * carrier restrictions.
+     */
+    SIM_STATE_CARD_RESTRICTED = 9;
+    /**
+     * SIM card state: Loaded: SIM card applications have been loaded
+     * @hide
+     */
+    SIM_STATE_LOADED = 10;
+    /**
+     * SIM card state: SIM Card is present
+     * @hide
+     */
+    SIM_STATE_PRESENT = 11;
+}
diff --git a/core/proto/android/view/displaycutout.proto b/core/proto/android/view/displaycutout.proto
index f4744da..0a33101 100644
--- a/core/proto/android/view/displaycutout.proto
+++ b/core/proto/android/view/displaycutout.proto
@@ -26,5 +26,9 @@
     option (.android.msg_privacy).dest = DEST_AUTOMATIC;
 
     optional .android.graphics.RectProto insets = 1;
-    optional .android.graphics.RectProto bounds = 2;
+    reserved 2;
+    optional .android.graphics.RectProto bound_left = 3;
+    optional .android.graphics.RectProto bound_top = 4;
+    optional .android.graphics.RectProto bound_right = 5;
+    optional .android.graphics.RectProto bound_bottom = 6;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f654ce2..374c7ea 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -138,7 +138,6 @@
     <protected-broadcast android:name="android.bluetooth.device.action.MAS_INSTANCE" />
     <protected-broadcast android:name="android.bluetooth.device.action.ALIAS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.FOUND" />
-    <protected-broadcast android:name="android.bluetooth.device.action.DISAPPEARED" />
     <protected-broadcast android:name="android.bluetooth.device.action.CLASS_CHANGED" />
     <protected-broadcast android:name="android.bluetooth.device.action.ACL_CONNECTED" />
     <protected-broadcast android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" />
@@ -1100,7 +1099,7 @@
 
     <!-- Allows a calling application which manages it own calls through the self-managed
          {@link android.telecom.ConnectionService} APIs.  See
-         {@link android.telecom.PhoneAccount#CAPABILITY_SELF_MANAGED for more information on the
+         {@link android.telecom.PhoneAccount#CAPABILITY_SELF_MANAGED} for more information on the
          self-managed ConnectionService APIs.
          <p>Protection level: normal
     -->
@@ -1151,6 +1150,28 @@
         android:protectionLevel="dangerous|instant"/>
 
     <!-- ====================================================================== -->
+    <!-- Permissions for activity recognition                        -->
+    <!-- ====================================================================== -->
+    <eat-comment />
+
+    <!-- Used for permissions that are associated with activity recognition.
+         TODO(zezeozue). STOPSHIP: Add icon -->
+    <permission-group android:name="android.permission-group.ACTIVITY_RECOGNITION"
+        android:label="@string/permgrouplab_activityRecognition"
+        android:description="@string/permgroupdesc_activityRecognition"
+        android:request="@string/permgrouprequest_activityRecognition"
+        android:priority="1000" />
+
+    <!-- Allows an application to recognize physical activity.
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.ACTIVITY_RECOGNITION"
+        android:permissionGroup="android.permission-group.ACTIVITY_RECOGNITION"
+        android:label="@string/permlab_activityRecognition"
+        android:description="@string/permdesc_activityRecognition"
+        android:protectionLevel="dangerous|instant" />
+
+    <!-- ====================================================================== -->
     <!-- Permissions for accessing the UCE Service                              -->
     <!-- ====================================================================== -->
 
@@ -1546,6 +1567,7 @@
 
     <!-- Allows SetupWizard to call methods in Networking services
          <p>Not for use by any other third-party or privileged applications.
+         @SystemApi
          @hide This should only be used by SetupWizard.
     -->
     <permission android:name="android.permission.NETWORK_SETUP_WIZARD"
@@ -1932,6 +1954,13 @@
     <permission android:name="android.permission.BIND_SCREENING_SERVICE"
         android:protectionLevel="signature|privileged" />
 
+    <!-- Must be required by a {@link android.telecom.CallRedirectionService},
+         to ensure that only the system can bind to it.
+         <p>Protection level: signature|privileged
+    -->
+    <permission android:name="android.permission.BIND_CALL_REDIRECTION_SERVICE"
+                android:protectionLevel="signature|privileged" />
+
     <!-- Must be required by a {@link android.telecom.ConnectionService},
          to ensure that only the system can bind to it.
          @deprecated {@link android.telecom.ConnectionService}s should require
@@ -2741,7 +2770,7 @@
         android:protectionLevel="signature" />
 
     <!-- @SystemApi Allows an application to use
-         {@link android.view.WindowManager.LayoutsParams#PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS}
+         {@link android.view.WindowManager.LayoutsParams#SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS}
          to hide non-system-overlay windows.
          <p>Not for use by third-party applications.
          @hide
@@ -4313,7 +4342,7 @@
         </activity>
 
         <activity android:name="com.android.internal.app.NetInitiatedActivity"
-                android:theme="@style/Theme.DeviceDefault.Light.Dialog.Alert"
+                android:theme="@style/Theme.Dialog.Confirmation"
                 android:excludeFromRecents="true"
                 android:process=":ui">
         </activity>
@@ -4334,7 +4363,7 @@
         <activity android:name="com.android.internal.app.ConfirmUserCreationActivity"
                 android:excludeFromRecents="true"
                 android:process=":ui"
-                android:theme="@style/Theme.DeviceDefault.Light.Dialog.Alert">
+                android:theme="@style/Theme.Dialog.Confirmation">
             <intent-filter android:priority="1000">
                 <action android:name="android.os.action.CREATE_USER" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -4342,24 +4371,24 @@
         </activity>
 
         <activity android:name="com.android.internal.app.SuspendedAppActivity"
-                  android:theme="@style/Theme.DeviceDefault.Light.Dialog.Alert"
+                  android:theme="@style/Theme.Dialog.Confirmation"
                   android:excludeFromRecents="true"
                   android:process=":ui">
         </activity>
 
         <activity android:name="com.android.internal.app.UnlaunchableAppActivity"
-                android:theme="@style/Theme.DeviceDefault.Light.Dialog.Alert"
+                android:theme="@style/Theme.Dialog.Confirmation"
                 android:excludeFromRecents="true"
                 android:process=":ui">
         </activity>
 
         <activity android:name="com.android.settings.notification.NotificationAccessConfirmationActivity"
-                  android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+                  android:theme="@style/Theme.Dialog.Confirmation"
                   android:excludeFromRecents="true">
         </activity>
 
         <activity android:name="com.android.internal.app.HarmfulAppWarningActivity"
-                  android:theme="@style/Theme.DeviceDefault.Light.Dialog.Alert"
+                  android:theme="@style/Theme.Dialog.Confirmation"
                   android:excludeFromRecents="true"
                   android:process=":ui"
                   android:label="@string/harmful_app_warning_title"
diff --git a/core/res/res/layout/harmful_app_warning_dialog.xml b/core/res/res/layout/harmful_app_warning_dialog.xml
index d41691f..62ca7a6 100644
--- a/core/res/res/layout/harmful_app_warning_dialog.xml
+++ b/core/res/res/layout/harmful_app_warning_dialog.xml
@@ -49,7 +49,7 @@
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
                     android:gravity="center_vertical"
-                    android:textColor="@color/primary_text_material_light"
+                    android:textColor="?attr/textColorPrimary"
                     android:textSize="@dimen/text_size_subhead_material"
                     android:paddingLeft="@dimen/harmful_app_icon_name_padding">
             </TextView>
@@ -65,4 +65,4 @@
                 android:lineSpacingMultiplier="@dimen/harmful_app_message_line_spacing_modifier"
                 android:textSize="@dimen/text_size_body_1_material"/>
     </LinearLayout>
-</ScrollView>
\ No newline at end of file
+</ScrollView>
diff --git a/core/res/res/layout/notification_material_media_action.xml b/core/res/res/layout/notification_material_media_action.xml
index 900ca2d..dd79a0b 100644
--- a/core/res/res/layout/notification_material_media_action.xml
+++ b/core/res/res/layout/notification_material_media_action.xml
@@ -18,7 +18,6 @@
 <ImageButton
     xmlns:android="http://schemas.android.com/apk/res/android"
     style="@android:style/Widget.Material.Button.Borderless.Small"
-    android:id="@+id/action0"
     android:layout_width="@dimen/media_notification_action_button_size"
     android:layout_height="@dimen/media_notification_action_button_size"
     android:paddingBottom="8dp"
@@ -28,4 +27,5 @@
     android:layout_marginEnd="2dp"
     android:gravity="center"
     android:background="@drawable/notification_material_media_action_background"
+    android:visibility="gone"
     />
diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml
index b4e26483..5cb93eb 100644
--- a/core/res/res/layout/notification_template_material_big_media.xml
+++ b/core/res/res/layout/notification_template_material_big_media.xml
@@ -59,7 +59,26 @@
             android:orientation="horizontal"
             android:layoutDirection="ltr"
             style="@style/NotificationMediaActionContainer" >
-            <!-- media buttons will be added here -->
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action0"
+            />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action1"
+            />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action2"
+            />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action3"
+            />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action4"
+            />
         </LinearLayout>
     </LinearLayout>
 </com.android.internal.widget.MediaNotificationView>
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 3a0912b..01b0866 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -65,7 +65,18 @@
             android:layoutDirection="ltr"
             android:orientation="horizontal"
             >
-            <!-- media buttons will be added here -->
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action0"
+            />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action1"
+            />
+            <include
+                layout="@layout/notification_material_media_action"
+                android:id="@+id/action2"
+            />
         </LinearLayout>
     </LinearLayout>
 </FrameLayout>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index e210d90e..e895ce0 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1519,7 +1519,7 @@
     <string name="activitychooserview_choose_application" msgid="2125168057199941199">"Odaberite aplikaciju"</string>
     <string name="activitychooserview_choose_application_error" msgid="8624618365481126668">"Aplikacija <xliff:g id="APPLICATION_NAME">%s</xliff:g> se ne može pokrenuti."</string>
     <string name="shareactionprovider_share_with" msgid="806688056141131819">"Podijeliti sa"</string>
-    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dijeli koristeći aplikaciju <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
+    <string name="shareactionprovider_share_with_application" msgid="5627411384638389738">"Dijeli pomoću aplikacije <xliff:g id="APPLICATION_NAME">%s</xliff:g>"</string>
     <string name="content_description_sliding_handle" msgid="415975056159262248">"Klizni regulator. Dodirnite &amp; držite."</string>
     <string name="description_target_unlock_tablet" msgid="3833195335629795055">"Prevucite za otključavanje ekrana."</string>
     <string name="action_bar_home_description" msgid="5293600496601490216">"Vratite se na početnu stranicu"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 318dd3e..4d78073 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -941,7 +941,7 @@
     <string name="menu_ctrl_shortcut_label" msgid="3917070091228880941">"Ctrl +"</string>
     <string name="menu_alt_shortcut_label" msgid="6249849492641218944">"Alt +"</string>
     <string name="menu_shift_shortcut_label" msgid="6773890288720306380">"Maiús +"</string>
-    <string name="menu_sym_shortcut_label" msgid="4019695553731017933">"Sim +"</string>
+    <string name="menu_sym_shortcut_label" msgid="4019695553731017933">"Sym +"</string>
     <string name="menu_function_shortcut_label" msgid="1984053777418162618">"Función +"</string>
     <string name="menu_space_shortcut_label" msgid="2410328639272162537">"espazo"</string>
     <string name="menu_enter_shortcut_label" msgid="2743362785111309668">"intro"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index bebd489..05ec806 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -518,8 +518,7 @@
     <string name="permdesc_imagesWrite" msgid="7073662756617474375">"इससे ऐप्लिकेशन को आपके फ़ोटो संग्रह में बदलाव करने की मंज़ूरी दी जाती है."</string>
     <string name="permlab_mediaLocation" msgid="8675148183726247864">"अपने मीडिया संग्रह से जगह की जानकारी एक्सेस करने की अनुमति दें"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"इससे ऐप्लिकेशन को आपके मीडिया संग्रह से जगह की जानकारी एक्सेस करने की अनुमति दी जाती है."</string>
-    <!-- no translation found for biometric_error_hw_unavailable (645781226537551036) -->
-    <skip />
+    <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"बायोमेट्रिक हार्डवेयर उपलब्ध नहीं है"</string>
     <string name="fingerprint_acquired_partial" msgid="735082772341716043">"आंशिक फ़िंगरप्रिंट की पहचान की गई. कृपया पुनः प्रयास करें."</string>
     <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"फ़िंगरप्रिंट संसाधित नहीं हो सका. कृपया पुन: प्रयास करें."</string>
     <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"फ़िंगरप्रिंट सेंसर गंदा है. कृपया साफ़ करें और फिर कोशिश करें."</string>
@@ -527,8 +526,7 @@
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"उंगली बहुत धीरे चलाई गई. कृपया फिर से कोशिश करें."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
-    <!-- no translation found for biometric_not_recognized (5770511773560736082) -->
-    <skip />
+    <string name="biometric_not_recognized" msgid="5770511773560736082">"पहचान नहीं हो पाई"</string>
     <string name="fingerprint_authenticated" msgid="5309333983002526448">"फ़िंगरप्रिंट की पुष्टि हो गई"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"चेहरे की पहचान की गई"</string>
     <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"चेहरे की पहचान की गई, कृपया पुष्टि बटन दबाएं"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index d6869c1..f1dc8d1 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -326,8 +326,8 @@
     <string name="capability_desc_canControlMagnification" msgid="4791858203568383773">"Valdyti ekrano mastelio keitimo lygį ir pozicijos nustatymą."</string>
     <string name="capability_title_canPerformGestures" msgid="7418984730362576862">"Veiksmai gestais"</string>
     <string name="capability_desc_canPerformGestures" msgid="8296373021636981249">"Galima paliesti, perbraukti, suimti ir atlikti kitus veiksmus gestais."</string>
-    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Kontrolinio kodo gestai"</string>
-    <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"Gali užfiksuoti gestus, atliktus naudojant įrenginio kontrolinio kodo jutiklį."</string>
+    <string name="capability_title_canCaptureFingerprintGestures" msgid="6309568287512278670">"Piršto antspaudo gestai"</string>
+    <string name="capability_desc_canCaptureFingerprintGestures" msgid="4386487962402228670">"Gali užfiksuoti gestus, atliktus naudojant įrenginio piršto antspaudo jutiklį."</string>
     <string name="permlab_statusBar" msgid="7417192629601890791">"išjungti ar keisti būsenos juostą"</string>
     <string name="permdesc_statusBar" msgid="8434669549504290975">"Leidžiama programai neleisti būsenos juostos arba pridėti ir pašalinti sistemos piktogramas."</string>
     <string name="permlab_statusBarService" msgid="4826835508226139688">"būti būsenos juosta"</string>
@@ -506,10 +506,10 @@
     <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Leidžiama programai neleisti klavišo užrakto ir visos susijusios slaptažodžio apsaugos. Pvz., telefonas neleidžia klavišo užrakto priimant gaunamąjį skambutį ir pakartotinai jį įgalina, kai skambutis baigiamas."</string>
     <string name="permlab_useBiometric" msgid="8837753668509919318">"naudoti biometrinę aparatinę įrangą"</string>
     <string name="permdesc_useBiometric" msgid="8389855232721612926">"Leidžiama programai naudoti biometrinę aparatinę įrangą tapatybei nustatyti"</string>
-    <string name="permlab_manageFingerprint" msgid="5640858826254575638">"tvarkyti kontrolinio kodo aparatinę įrangą"</string>
+    <string name="permlab_manageFingerprint" msgid="5640858826254575638">"tvarkyti piršto antspaudo aparatinę įrangą"</string>
     <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Leidžiama programai aktyvinti metodus, norint pridėti ir ištrinti naudojamus kontrolinių kodų šablonus."</string>
-    <string name="permlab_useFingerprint" msgid="3150478619915124905">"naudoti kontrolinio kodo aparatinę įrangą"</string>
-    <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Leidžiama programai naudoti kontrolinio kodo aparatinę įrangą tapatybei nustatyti"</string>
+    <string name="permlab_useFingerprint" msgid="3150478619915124905">"naudoti piršto antspaudo aparatinę įrangą"</string>
+    <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Leidžiama programai naudoti piršto antspaudo aparatinę įrangą tapatybei nustatyti"</string>
     <string name="permlab_audioRead" msgid="6617225220728465565">"skaityti muzikos kolekciją"</string>
     <string name="permdesc_audioRead" msgid="5034032570243484805">"Programai leidžiama skaityti muzikos kolekciją."</string>
     <string name="permlab_audioWrite" msgid="2661772059799779292">"keisti muzikos kolekciją"</string>
@@ -525,31 +525,31 @@
     <string name="permlab_mediaLocation" msgid="8675148183726247864">"skaityti vietoves iš medijos kolekcijos"</string>
     <string name="permdesc_mediaLocation" msgid="2237023389178865130">"Programai leidžiama skaityti vietoves iš medijos kolekcijos."</string>
     <string name="biometric_error_hw_unavailable" msgid="645781226537551036">"Biometrinė aparatinė įranga nepasiekiama"</string>
-    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Aptiktas dalinis kontrolinis kodas. Bandykite dar kartą."</string>
-    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Nepavyko apdoroti kontrolinio kodo. Bandykite dar kartą."</string>
-    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Kontrolinio kodo jutiklis purvinas. Nuvalykite ir bandykite dar kartą."</string>
+    <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Aptiktas dalinis piršto antspaudas. Bandykite dar kartą."</string>
+    <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Nepavyko apdoroti piršto antspaudo. Bandykite dar kartą."</string>
+    <string name="fingerprint_acquired_imager_dirty" msgid="1087209702421076105">"Piršto antspaudo jutiklis purvinas. Nuvalykite ir bandykite dar kartą."</string>
     <string name="fingerprint_acquired_too_fast" msgid="6470642383109155969">"Per greitai judinate pirštą. Bandykite dar kartą."</string>
     <string name="fingerprint_acquired_too_slow" msgid="59250885689661653">"Per lėtai judinate pirštą. Bandykite dar kartą."</string>
   <string-array name="fingerprint_acquired_vendor">
   </string-array>
     <string name="biometric_not_recognized" msgid="5770511773560736082">"Neatpažinta"</string>
-    <string name="fingerprint_authenticated" msgid="5309333983002526448">"Kontrolinis kodas autentifikuotas"</string>
+    <string name="fingerprint_authenticated" msgid="5309333983002526448">"Piršto antspaudas autentifikuotas"</string>
     <string name="face_authenticated_no_confirmation_required" msgid="4018680978348659031">"Veidas autentifikuotas"</string>
     <string name="face_authenticated_confirmation_required" msgid="8778347003507633610">"Veidas autentifikuotas, paspauskite patvirtinimo mygtuką"</string>
-    <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Kontrolinio kodo aparatinė įranga nepasiekiama."</string>
-    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Negalima išsaugoti kontrolinio kodo. Pašalinkite esamą kontrolinį kodą."</string>
-    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Baigėsi kontrolinio kodo nustatymo skirtasis laikas. Bandykite dar kartą."</string>
-    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Kontrolinio kodo operacija atšaukta."</string>
-    <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Kontrolinio kodo operaciją atšaukė naudotojas."</string>
+    <string name="fingerprint_error_hw_not_available" msgid="7955921658939936596">"Piršto antspaudo aparatinė įranga nepasiekiama."</string>
+    <string name="fingerprint_error_no_space" msgid="1055819001126053318">"Negalima išsaugoti piršto antspaudo. Pašalinkite esamą piršto antspaudą."</string>
+    <string name="fingerprint_error_timeout" msgid="3927186043737732875">"Baigėsi piršto antspaudo nustatymo skirtasis laikas. Bandykite dar kartą."</string>
+    <string name="fingerprint_error_canceled" msgid="4402024612660774395">"Piršto antspaudo operacija atšaukta."</string>
+    <string name="fingerprint_error_user_canceled" msgid="7999639584615291494">"Piršto antspaudo operaciją atšaukė naudotojas."</string>
     <string name="fingerprint_error_lockout" msgid="5536934748136933450">"Per daug bandymų. Vėliau bandykite dar kartą."</string>
-    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Per daug bandymų. Kontrolinio kodo jutiklis išjungtas."</string>
+    <string name="fingerprint_error_lockout_permanent" msgid="5033251797919508137">"Per daug bandymų. Piršto antspaudo jutiklis išjungtas."</string>
     <string name="fingerprint_error_unable_to_process" msgid="6107816084103552441">"Bandykite dar kartą."</string>
     <string name="fingerprint_error_no_fingerprints" msgid="7654382120628334248">"Neužregistruota jokių kontrolinių kodų."</string>
-    <string name="fingerprint_error_hw_not_present" msgid="5729436878065119329">"Šiame įrenginyje nėra kontrolinio kodo jutiklio"</string>
+    <string name="fingerprint_error_hw_not_present" msgid="5729436878065119329">"Šiame įrenginyje nėra piršto antspaudo jutiklio"</string>
     <string name="fingerprint_name_template" msgid="5870957565512716938">"<xliff:g id="FINGERID">%d</xliff:g> pirštas"</string>
   <string-array name="fingerprint_error_vendor">
   </string-array>
-    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Kontrolinio kodo piktograma"</string>
+    <string name="fingerprint_icon_content_description" msgid="2340202869968465936">"Piršto antspaudo piktograma"</string>
     <string name="permlab_manageFace" msgid="2137540986007309781">"tvarkyti veido autentifikavimo aparatinę įrangą"</string>
     <string name="permdesc_manageFace" msgid="8919637120670185330">"Programai leidžiama aktyv. metodus, norint pridėti ir ištrinti naudojamus veidų šablonus."</string>
     <string name="permlab_useFaceAuthentication" msgid="8996134460546804535">"naudoti veido autentifikavimo aparatinę įrangą"</string>
@@ -1580,8 +1580,8 @@
     <string name="expires_on" msgid="3676242949915959821">"Galiojimas baigiasi:"</string>
     <string name="serial_number" msgid="758814067660862493">"Serijos numeris:"</string>
     <string name="fingerprints" msgid="4516019619850763049">"Kontroliniai kodai"</string>
-    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 kontrolinis kodas"</string>
-    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 kontrolinis kodas"</string>
+    <string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 piršto antspaudas"</string>
+    <string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 piršto antspaudas"</string>
     <string name="activity_chooser_view_see_all" msgid="4292569383976636200">"Žr. viską"</string>
     <string name="activity_chooser_view_dialog_title_default" msgid="4710013864974040615">"Pasirinkti veiklą"</string>
     <string name="share_action_provider_share_with" msgid="5247684435979149216">"Bendrinti su"</string>
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index c8d4d05..931674a 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -50,7 +50,9 @@
          {@code TextAppearance.DeviceDefault.Widget.PopupMenu.Large}).</p>
           -->
     <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
-    <style name="Theme.DeviceDefault.Settings" parent="Theme.DeviceDefault"/>
+    <style name="Theme.DeviceDefault.Settings" parent="Theme.DeviceDefault">
+        <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
+    </style>
 
     <!-- Theme for the dialog shown when an app crashes or ANRs. -->
     <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert" />
diff --git a/core/res/res/values-night/values.xml b/core/res/res/values-night/values.xml
index 45cf0f0..9de8842 100644
--- a/core/res/res/values-night/values.xml
+++ b/core/res/res/values-night/values.xml
@@ -20,7 +20,7 @@
         <!-- Color palette -->
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
-        <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorAccent">@color/white</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
         <item name="colorControlNormal">?attr/textColorPrimary</item>
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Dialog.Alert</item>
@@ -32,6 +32,8 @@
         <item name="panelColorBackground">@color/material_grey_800</item>
     </style>
 
+    <style name="Theme.DeviceDefault.QuickSettings.Dialog" parent="Theme.DeviceDefault.Dialog" />
+
     <style name="TextAppearance.Material.Notification">
         <item name="textColor">@color/notification_secondary_text_color_dark</item>
         <item name="textSize">@dimen/notification_text_size</item>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index b84d68e..3bf8b78 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1759,8 +1759,8 @@
     <string name="package_installed_device_owner" msgid="6875717669960212648">"உங்கள் நிர்வாகி நிறுவியுள்ளார்"</string>
     <string name="package_updated_device_owner" msgid="1847154566357862089">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்"</string>
     <string name="package_deleted_device_owner" msgid="2307122077550236438">"உங்கள் நிர்வாகி நீக்கியுள்ளார்"</string>
-    <string name="battery_saver_description_with_learn_more" msgid="6323937147992667707">"பேட்டரியின் ஆயுளை அதிகரிக்க, பேட்டரி சேமிப்பான் அம்சமானது சில சாதன அம்சங்களை ஆஃப் செய்து, ஆப்ஸைக் கட்டுப்படுத்தும். "<annotation id="url">"மேலும் அறிக"</annotation></string>
-    <string name="battery_saver_description" msgid="769989536172631582">"பேட்டரி இயங்கும் நேரத்தை அதிகரிக்க, பேட்டரி சேமிப்பான் அம்சமானது சில சாதன அம்சங்களை ஆஃப் செய்து, ஆப்ஸைக் கட்டுப்படுத்தும்."</string>
+    <string name="battery_saver_description_with_learn_more" msgid="6323937147992667707">"பேட்டரி இயங்கும் நேரத்தை அதிகரிக்க, \'பேட்டரி சேமிப்பான்\' அம்சமானது சில சாதன அம்சங்களை ஆஃப் செய்து, ஆப்ஸைக் கட்டுப்படுத்தும். "<annotation id="url">"மேலும் அறிக"</annotation></string>
+    <string name="battery_saver_description" msgid="769989536172631582">"பேட்டரி இயங்கும் நேரத்தை அதிகரிக்க, \'பேட்டரி சேமிப்பான்\' அம்சமானது சில சாதன அம்சங்களை ஆஃப் செய்து, ஆப்ஸைக் கட்டுப்படுத்தும்."</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>
diff --git a/core/res/res/values-television/themes.xml b/core/res/res/values-television/themes.xml
index 48b59c7..176e89e 100644
--- a/core/res/res/values-television/themes.xml
+++ b/core/res/res/values-television/themes.xml
@@ -15,6 +15,7 @@
 -->
 <resources>
     <style name="Theme.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
+    <style name="Theme.Dialog.Confirmation" parent="Theme.Leanback.Dialog.Confirmation" />
     <style name="Theme.Holo.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.Holo.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
     <style name="Theme.Material.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index e0db946..a25c998 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1141,6 +1141,15 @@
 
         <!-- Alpha value of the spot shadow projected by elevated views, between 0 and 1. -->
         <attr name="spotShadowAlpha" format="float" />
+
+        <!-- <p>Whether or not the force dark feature is allowed to be applied to this theme.
+             <p>Setting this to false will disable the auto-dark feature on everything this
+             theme is applied to along with anything drawn by any children of views using
+             this theme.
+             <p>Setting this to true will allow this view to be automatically made dark, however
+             a value of 'true' will not override any 'false' value in its parent chain nor will
+             it prevent any 'false' in any of its children. -->
+        <attr name="forceDarkAllowed" format="boolean" />
     </declare-styleable>
 
     <!-- **************************************************************** -->
@@ -3116,8 +3125,13 @@
              {@link android.R.attr#ambientShadowAlpha} theme attribute. -->
         <attr name="outlineAmbientShadowColor" format="color" />
 
-        <!-- Whether to allow the rendering system to force this View to render as light-on-dark. -->
-        <attr name="allowForceDark" format="boolean" />
+        <!-- <p>Whether or not the force dark feature is allowed to be applied to this View.
+             <p>Setting this to false will disable the auto-dark feature on this View draws
+             including any descendants.
+             <p>Setting this to true will allow this view to be automatically made dark, however
+             a value of 'true' will not override any 'false' value in its parent chain nor will
+             it prevent any 'false' in any of its children. -->
+        <attr name="forceDarkAllowed" format="boolean" />
     </declare-styleable>
 
     <!-- Attributes that can be assigned to a tag for a particular View. -->
@@ -4184,9 +4198,9 @@
         row is full. The rowCount attribute may be used similarly in the vertical case.
         The default is horizontal. -->
         <attr name="orientation" />
-        <!-- The maxmimum number of rows to create when automatically positioning children. -->
+        <!-- The maximum number of rows to create when automatically positioning children. -->
         <attr name="rowCount" format="integer" />
-        <!-- The maxmimum number of columns to create when automatically positioning children. -->
+        <!-- The maximum number of columns to create when automatically positioning children. -->
         <attr name="columnCount" format="integer" />
         <!-- When set to true, tells GridLayout to use default margins when none are specified
         in a view's layout parameters.
@@ -4551,6 +4565,11 @@
         <attr name="typeface" />
         <!-- Font family (named by string or as a font resource reference) for the text. -->
         <attr name="fontFamily" />
+        <!-- Specifies the {@link android.os.LocaleList} for the text.
+             May be a string value, which is a comma-separated language tag list, such as "ja-JP,zh-CN".
+             When not specified or an empty string is given, it will fallback to the default one.
+             {@see android.os.LocaleList#forLanguageTags(String)} -->
+        <attr name="textLocale" format="string" />
         <!-- Color of the text selection highlight. -->
         <attr name="textColorHighlight" />
         <!-- Color of the hint text. -->
@@ -4642,6 +4661,13 @@
         <attr name="textFontWeight" />
         <!-- Font family (named by string or as a font resource reference) for the text. -->
         <attr name="fontFamily" />
+        <!-- Specifies the {@link android.os.LocaleList} for the text in this TextView.
+             If not given, the system default will be used.
+             May be a string value, which is a comma-separated language tag list, such as "ja-JP,zh-CN".
+             When not specified or an empty string is given, it will fallback to the default one.
+             {@see android.os.LocaleList#forLanguageTags(String)}
+             {@see android.text.TextView#setTextLocales(android.os.LocaleList)} -->
+        <attr name="textLocale" format="string" />
         <!-- Text color for links. -->
         <attr name="textColorLink" />
         <!-- Makes the cursor visible (the default) or invisible. -->
@@ -7882,6 +7908,9 @@
         <!-- Wallpapers optimized and capable of drawing in ambient mode will return true. -->
         <attr name="supportsAmbientMode" format="boolean" />
 
+        <!-- Uri that specifies a settings Slice for this wallpaper. -->
+        <attr name="settingsSliceUri" />
+
     </declare-styleable>
 
     <!-- Use <code>dream</code> as the root tag of the XML resource that
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 8ff29ba..99af0de 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1442,8 +1442,11 @@
          {@link #AndroidManifestService service},
          {@link #AndroidManifestReceiver receiver},
          {@link #AndroidManifestActivity activity},
-         {@link #AndroidManifestActivityAlias activity-alias}, and
-         {@link #AndroidManifestUsesLibrary uses-library}.  The application tag
+         {@link #AndroidManifestActivityAlias activity-alias},
+         {@link #AndroidManifestUsesLibrary uses-library},
+         {@link #AndroidManifestUsesStaticLibrary uses-static-library}, and
+         {@link #AndroidManifestUsesPackage uses-package}.
+         The application tag
          appears as a child of the root {@link #AndroidManifest manifest} tag in
          an application's manifest file. -->
     <declare-styleable name="AndroidManifestApplication" parent="AndroidManifest">
@@ -1877,12 +1880,35 @@
          library is singed with more than one certificate.
 
          <p>This appears as a child tag of the
-         {@link #AndroidManifestUsesStaticLibrary uses-static-library} tag. -->
+         {@link #AndroidManifestUsesStaticLibrary uses-static-library} or
+         {@link #AndroidManifestUsesPackage uses-package} tag. -->
     <declare-styleable name="AndroidManifestAdditionalCertificate" parent="AndroidManifestUsesStaticLibrary">
         <!-- The SHA-256 digest of the library signing certificate. -->
         <attr name="certDigest" />
     </declare-styleable>
 
+    <!-- The <code>uses-package</code> specifies some kind of dependency on another
+         package.  It does not have any impact on the app's execution on the device,
+         but provides information about dependencies it has on other packages that need
+         to  be satisfied for it to run correctly.  That is, this is primarily for
+         installers to know what other apps need to be installed along with this one.
+
+         <p>This appears as a child tag of the
+         {@link #AndroidManifestApplication application} tag. -->
+    <declare-styleable name="AndroidManifestUsesPackage" parent="AndroidManifestApplication">
+        <!-- Required type of association with the package, for example "android.package.ad_service"
+             if it provides an advertising service. -->
+        <attr name="packageType" format="string" />
+        <!-- Required name of the package you use. -->
+        <attr name="name" />
+        <!-- Optional minimum version of the package that satisfies the dependency. -->
+        <attr name="version" />
+        <!-- Optional minimum major version of the package that satisfies the dependency. -->
+        <attr name="versionMajor" format="integer" />
+        <!-- Optional SHA-256 digest of the package signing certificate. -->
+        <attr name="certDigest" format="string" />
+    </declare-styleable>
+
     <!-- The <code>supports-screens</code> specifies the screen dimensions an
          application supports.  By default a modern application supports all
          screen sizes and must explicitly disable certain screen sizes here;
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 0daf5a7..e257a5c 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -378,8 +378,8 @@
                    Values must be from NetworkCapabilities#NET_CAPABILITIES_* constants.
                [IP config] Optional. If empty or not specified - DHCP will be used, otherwise
                    use the following format to specify static IP configuration:
-		       ip=<ip-address/mask> gateway=<ip-address> dns=<comma-sep-ip-addresses>
-                       domains=<comma-sep-domains> 
+                       ip=<ip-address/mask> gateway=<ip-address> dns=<comma-sep-ip-addresses>
+                       domains=<comma-sep-domains>
          -->
     <string-array translatable="false" name="config_ethernet_interfaces">
         <!--
@@ -697,6 +697,10 @@
     <!-- Wifi driver supports IEEE80211AC for softap -->
     <bool translatable="false" name="config_wifi_softap_ieee80211ac_supported">false</bool>
 
+    <!-- Indicates that local-only hotspot should be brought up at 5GHz.  This option is
+         for automotive builds only (the one that have PackageManager#FEATURE_AUTOMOTIVE) -->
+    <bool translatable="false" name="config_wifi_local_only_hotspot_5ghz">false</bool>
+
     <!-- Flag indicating whether we should enable the automatic brightness.
          Software implementation will be used if config_hardware_auto_brightness_available is not set -->
     <bool name="config_automatic_brightness_available">false</bool>
@@ -1527,7 +1531,7 @@
     <bool name="config_checkWallpaperAtBoot">true</bool>
 
     <!-- Class name of WallpaperManagerService. -->
-    <string name="config_wallpaperManagerServiceName">com.android.server.wallpaper.WallpaperManagerService</string>
+    <string name="config_wallpaperManagerServiceName" translatable="false">com.android.server.wallpaper.WallpaperManagerService</string>
 
     <!-- Enables the TimeZoneRuleManager service. This is the master switch for the updateable time
          zone update mechanism. -->
@@ -2113,8 +2117,8 @@
     <!-- Type of the long press sensor. Empty if long press is not supported. -->
     <string name="config_dozeLongPressSensorType" translatable="false"></string>
 
-    <!-- Type of sensor that wakes up the lock screen. Empty if not supported. -->
-    <string name="config_dozeWakeLockScreenSensorType" translatable="false"></string>
+    <!-- If the sensor that wakes up the lock screen is available or not. -->
+    <bool name="config_dozeWakeLockScreenSensorAvailable">false</bool>
 
     <!-- Type of the wake up sensor. Empty if not supported. -->
     <string name="config_dozeWakeScreenSensorType" translatable="false"></string>
@@ -3367,22 +3371,22 @@
     <bool name="config_sendPackageName">false</bool>
 
     <!-- Name for the set of keys associating package names -->
-    <string name="config_help_package_name_key" translatable="false"></string>
+    <string name="config_helpPackageNameKey" translatable="false"></string>
 
     <!-- Name for the set of values of package names -->
-    <string name="config_help_package_name_value" translatable="false"></string>
+    <string name="config_helpPackageNameValue" translatable="false"></string>
 
     <!-- Intent key for the package name keys -->
-    <string name="config_help_intent_extra_key" translatable="false"></string>
+    <string name="config_helpIntentExtraKey" translatable="false"></string>
 
     <!-- Intent key for package name values -->
-    <string name="config_help_intent_name_key" translatable="false"></string>
+    <string name="config_helpIntentNameKey" translatable="false"></string>
 
     <!-- Intent key for the package name keys -->
-    <string name="config_feedback_intent_extra_key" translatable="false"></string>
+    <string name="config_feedbackIntentExtraKey" translatable="false"></string>
 
     <!-- Intent key for package name values -->
-    <string name="config_feedback_intent_name_key" translatable="false"></string>
+    <string name="config_feedbackIntentNameKey" translatable="false"></string>
 
     <!-- The apps that need to be hidden when they are disabled -->
     <string-array name="config_hideWhenDisabled_packageNames"></string-array>
@@ -3487,7 +3491,7 @@
     <string name="config_headlineFontFamilyMedium">@string/font_family_button_material</string>
 
     <!-- Size of icon shown beside a preference locked by admin -->
-    <dimen name="config_restricted_icon_size">@dimen/restricted_icon_size_material</dimen>
+    <dimen name="config_restrictedIconSize">@dimen/restricted_icon_size_material</dimen>
 
     <string translatable="false" name="config_batterySaverDeviceSpecificConfig"></string>
 
@@ -3550,4 +3554,11 @@
 
     <!-- Pre-scale volume at volume step 3 for Absolute Volume -->
     <fraction name="config_prescaleAbsoluteVolume_index3">85%</fraction>
+
+    <!-- Whether or not the "SMS app service" feature is enabled -->
+    <bool name="config_useSmsAppService">true</bool>
+
+    <!-- Component name for default assistant on this device -->
+    <string name="config_defaultAssistantComponentName">#+UNSET</string>
+
 </resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index fadefff..b790829 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2903,17 +2903,20 @@
   <eat-comment />
 
     <public-group type="attr" first-id="0x01010587">
+        <public name="packageType" />
         <public name="opticalInsetLeft" />
         <public name="opticalInsetTop" />
         <public name="opticalInsetRight" />
         <public name="opticalInsetBottom" />
-        <public name="allowForceDark" />
+        <public name="forceDarkAllowed" />
         <public name="supportsAmbientMode" />
         <!-- @hide For use by platform and tools only. Developers should not specify this value. -->
         <public name="usesNonSdkApi" />
         <public name="minimumUiTimeout" />
         <public name="isLightTheme" />
         <public name="isSplitRequired" />
+        <public name="textLocale" />
+        <public name="settingsSliceUri" />
     </public-group>
 
     <public-group type="drawable" first-id="0x010800b4">
@@ -2929,17 +2932,17 @@
 
     <public-group type="string" first-id="0x0104001b">
         <!-- @hide @SystemApi -->
-        <public name="config_help_package_name_key" />
+        <public name="config_helpPackageNameKey" />
         <!-- @hide @SystemApi -->
-        <public name="config_help_package_name_value" />
+        <public name="config_helpPackageNameValue" />
         <!-- @hide @SystemApi -->
-        <public name="config_help_intent_extra_key" />
+        <public name="config_helpIntentExtraKey" />
         <!-- @hide @SystemApi -->
-        <public name="config_help_intent_name_key" />
+        <public name="config_helpIntentNameKey" />
         <!-- @hide @SystemApi -->
-        <public name="config_feedback_intent_extra_key" />
+        <public name="config_feedbackIntentExtraKey" />
         <!-- @hide @SystemApi -->
-        <public name="config_feedback_intent_name_key" />
+        <public name="config_feedbackIntentNameKey" />
     </public-group>
 
     <public-group type="bool" first-id="0x01110000">
@@ -2949,7 +2952,7 @@
 
     <public-group type="dimen" first-id="0x01050007">
         <!-- @hide @SystemApi -->
-        <public name="config_restricted_icon_size" />
+        <public name="config_restrictedIconSize" />
     </public-group>
 
   <!-- ===============================================================
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 6d0127a4..9ea82a9 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -734,6 +734,14 @@
     <string name="permgrouprequest_microphone">Allow
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to record audio?</string>
 
+    <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
+    <string name="permgrouplab_activityRecognition">Activity recognition</string>
+    <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=40]-->
+    <string name="permgroupdesc_activityRecognition">recognize activity</string>
+    <!-- Message shown to the user when the apps requests permission from this group. If ever possible this should stay below 80 characters (assuming the parameters takes 20 characters). Don't abbreviate until the message reaches 120 characters though. [CHAR LIMIT=120] -->
+    <string name="permgrouprequest_activityRecognition">Allow
+        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to recognize your physical activity?</string>
+
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_camera">Camera</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1132,9 +1140,9 @@
     <string name="permdesc_accessCoarseLocation" product="default">This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permlab_accessBackgroundLocation">access precise location in the background</string>
+    <string name="permlab_accessBackgroundLocation">access location in the background</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_accessBackgroundLocation">This app can get your exact location any time it is in the background. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption.</string>
+    <string name="permdesc_accessBackgroundLocation">If this is granted additionally to the approximate or precise location access the app can access the location while running in the background.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_modifyAudioSettings">change your audio settings</string>
@@ -1151,6 +1159,11 @@
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_sim_communication">Allows the app to send commands to the SIM. This is very dangerous.</string>
 
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50]-->
+    <string name="permlab_activityRecognition">recognize physical activity</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=120]-->
+    <string name="permdesc_activityRecognition">This app can recognize your physical activity.</string>
+
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_camera">take pictures and videos</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
@@ -1418,6 +1431,9 @@
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_mediaLocation">Allows the app to read locations from your media collection.</string>
 
+    <!-- Title shown when the system-provided biometric dialog is shown, asking the user to authenticate. [CHAR LIMIT=40] -->
+    <string name="biometric_dialog_default_title">Application <xliff:g id="app" example="Gmail">%s</xliff:g> wants to authenticate.</string>
+
     <!-- Message shown when biometric hardware is not available [CHAR LIMIT=50] -->
     <string name="biometric_error_hw_unavailable">Biometric hardware unavailable</string>
 
@@ -2908,55 +2924,55 @@
     <!-- Title for EditText context menu [CHAR LIMIT=20] -->
     <string name="editTextMenuTitle">Text actions</string>
 
-    <!-- Label for item in the text selection menu to trigger an Email app. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to trigger an Email app. Should be a verb. [CHAR LIMIT=30] -->
     <string name="email">Email</string>
 
     <!-- Accessibility description for an item in the text selection menu to trigger an Email app [CHAR LIMIT=NONE] -->
     <string name="email_desc">Email selected address</string>
 
-    <!-- Label for item in the text selection menu to trigger a Dialer app. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to trigger a Dialer app. Should be a verb. [CHAR LIMIT=30] -->
     <string name="dial">Call</string>
 
     <!-- Accessibility description for an item in the text selection menu to call a phone number [CHAR LIMIT=NONE] -->
     <string name="dial_desc">Call selected phone number</string>
 
-    <!-- Label for item in the text selection menu to trigger a Map app. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to trigger a Map app. Should be a verb. [CHAR LIMIT=30] -->
     <string name="map">Map</string>
 
     <!-- Accessibility description for an item in the text selection menu to open maps for an address [CHAR LIMIT=NONE] -->
     <string name="map_desc">Locate selected address</string>
 
-    <!-- Label for item in the text selection menu to trigger a Browser app. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to trigger a Browser app. Should be a verb. [CHAR LIMIT=30] -->
     <string name="browse">Open</string>
 
     <!-- Accessibility description for an item in the text selection menu to open a URL in a browser [CHAR LIMIT=NONE] -->
     <string name="browse_desc">Open selected URL</string>
 
-    <!-- Label for item in the text selection menu to trigger an SMS app. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to trigger an SMS app. Should be a verb. [CHAR LIMIT=30] -->
     <string name="sms">Message</string>
 
     <!-- Accessibility description for an item in the text selection menu to send an SMS to a phone number [CHAR LIMIT=NONE] -->
     <string name="sms_desc">Message selected phone number</string>
 
-    <!-- Label for item in the text selection menu to trigger adding a contact. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to trigger adding a contact. Should be a verb. [CHAR LIMIT=30] -->
     <string name="add_contact">Add</string>
 
     <!-- Accessibility description for an item in the text selection menu to add the selected detail to contacts [CHAR LIMIT=NONE] -->
     <string name="add_contact_desc">Add to contacts</string>
 
-    <!-- Label for item in the text selection menu to view the calendar for the selected time/date. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to view the calendar for the selected time/date. Should be a verb. [CHAR LIMIT=30] -->
     <string name="view_calendar">View</string>
 
     <!-- Accessibility description for an item in the text selection menu to view the calendar for a date [CHAR LIMIT=NONE]-->
     <string name="view_calendar_desc">View selected time in calendar</string>
 
-    <!-- Label for item in the text selection menu to create a calendar event at the selected time/date. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to create a calendar event at the selected time/date. Should be a verb. [CHAR LIMIT=30] -->
     <string name="add_calendar_event">Schedule</string>
 
     <!-- Accessibility description for an item in the text selection menu to schedule an event for a date [CHAR LIMIT=NONE] -->
     <string name="add_calendar_event_desc">Schedule event for selected time</string>
 
-    <!-- Label for item in the text selection menu to track a selected flight number. Should be a verb. [CHAR LIMIT=20] -->
+    <!-- Label for item in the text selection menu to track a selected flight number. Should be a verb. [CHAR LIMIT=30] -->
     <string name="view_flight">Track</string>
 
     <!-- Accessibility description for an item in the text selection menu to track a flight [CHAR LIMIT=NONE] -->
@@ -5005,33 +5021,33 @@
 
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
          by an autofill service, but the service does not know what the activity represents [CHAR LIMIT=NONE] -->
-    <string name="autofill_save_title">Save to &lt;b><xliff:g id="label" example="MyPass">%1$s</xliff:g>&lt;/b>?</string>
+    <string name="autofill_save_title">Save to <b><xliff:g id="label" example="MyPass">%1$s</xliff:g></b>?</string>
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
-         by an autofill service, and the service does knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_save_title_with_type">Save <xliff:g id="type" example="Credit Card">%1$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%2$s</xliff:g>&lt;/b>?</string>
+         by an autofill service, and the service knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
+    <string name="autofill_save_title_with_type">Save <xliff:g id="type" example="Credit Card">%1$s</xliff:g> to <b><xliff:g id="label" example="MyPass">%2$s</xliff:g></b>?</string>
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
-         by an autofill service, and the service does knows what the activity represents, and it represents 2 types of
+         by an autofill service, and the service knows what the activity represents, and it represents 2 types of
          data (for example, password and credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_save_title_with_2types">Save <xliff:g id="type" example="Password">%1$s</xliff:g> and <xliff:g id="type" example="Credit Card">%2$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%3$s</xliff:g>&lt;/b>?</string>
+    <string name="autofill_save_title_with_2types">Save <xliff:g id="type" example="Password">%1$s</xliff:g> and <xliff:g id="type" example="Credit Card">%2$s</xliff:g> to <b><xliff:g id="label" example="MyPass">%3$s</xliff:g></b>?</string>
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
-         by an autofill service, and the service does knows what the activity represents, and it represents 3 types of
+         by an autofill service, and the service knows what the activity represents, and it represents 3 types of
          data (for example, username, password and credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_save_title_with_3types">Save <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, and <xliff:g id="type" example="Credit Card">%3$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%4$s</xliff:g>&lt;/b>?</string>
+    <string name="autofill_save_title_with_3types">Save <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, and <xliff:g id="type" example="Credit Card">%3$s</xliff:g> to <b><xliff:g id="label" example="MyPass">%4$s</xliff:g></b>?</string>
 
     <!-- Title for the autofill update dialog shown when the the contents of the activity can be updated
-         by an autofill service, but the service does not know what the activity represents [CHAR LIMIT=NONE] -->
-    <string name="autofill_update_title">Update to &lt;b><xliff:g id="label" example="MyPass">%1$s</xliff:g>&lt;/b>?</string>
+         in an autofill service, but the service does not know what the activity represents [CHAR LIMIT=NONE] -->
+    <string name="autofill_update_title">Update in <b><xliff:g id="label" example="MyPass">%1$s</xliff:g></b>?</string>
     <!-- Title for the autofill update dialog shown when the the contents of the activity can be updated
-         by an autofill service, and the service does knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_update_title_with_type">Update <xliff:g id="type" example="Credit Card">%1$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%2$s</xliff:g>&lt;/b>?</string>
+         in an autofill service, and the service knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
+    <string name="autofill_update_title_with_type">Update <xliff:g id="type" example="Credit Card">%1$s</xliff:g> in <b><xliff:g id="label" example="MyPass">%2$s</xliff:g></b>?</string>
     <!-- Title for the autofill update dialog shown when the the contents of the activity can be updated
-         by an autofill service, and the service does knows what the activity represents, and it represents 2 types of
+         in an autofill service, and the service knows what the activity represents, and it represents 2 types of
          data (for example, password and credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_update_title_with_2types">Update <xliff:g id="type" example="Password">%1$s</xliff:g> and <xliff:g id="type" example="Credit Card">%2$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%3$s</xliff:g>&lt;/b>?</string>
+    <string name="autofill_update_title_with_2types">Update <xliff:g id="type" example="Password">%1$s</xliff:g> and <xliff:g id="type" example="Credit Card">%2$s</xliff:g> in <b><xliff:g id="label" example="MyPass">%3$s</xliff:g></b>?</string>
     <!-- Title for the autofill update dialog shown when the the contents of the activity can be updated
-         by an autofill service, and the service does knows what the activity represents, and it represents 3 types of
+         in an autofill service, and the service knows what the activity represents, and it represents 3 types of
          data (for example, username, password and credit card info) [CHAR LIMIT=NONE] -->
-    <string name="autofill_update_title_with_3types">Update <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, and <xliff:g id="type" example="Credit Card">%3$s</xliff:g> to &lt;b><xliff:g id="label" example="MyPass">%4$s</xliff:g>&lt;/b>?</string>
+    <string name="autofill_update_title_with_3types">Update these items in <b><xliff:g id="label" example="MyPass">%4$s</xliff:g></b>: <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, and <xliff:g id="type" example="Credit Card">%3$s</xliff:g> ?</string>
 
 
     <!-- Label for the autofill save button [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 72ae0d6..81a1bf8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -186,6 +186,8 @@
   <java-symbol type="id" name="action0" />
   <java-symbol type="id" name="action1" />
   <java-symbol type="id" name="action2" />
+  <java-symbol type="id" name="action3" />
+  <java-symbol type="id" name="action4" />
   <java-symbol type="id" name="big_picture" />
   <java-symbol type="id" name="big_text" />
   <java-symbol type="id" name="chronometer" />
@@ -1873,6 +1875,7 @@
   <java-symbol type="bool" name="config_wifi_background_scan_support" />
   <java-symbol type="bool" name="config_wifi_dual_band_support" />
   <java-symbol type="bool" name="config_wifi_convert_apband_5ghz_to_any" />
+  <java-symbol type="bool" name="config_wifi_local_only_hotspot_5ghz" />
   <java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
   <java-symbol type="bool" name="config_wimaxEnabled" />
   <java-symbol type="bool" name="show_ongoing_ime_switcher" />
@@ -2394,6 +2397,7 @@
   <java-symbol type="string" name="config_keyguardComponent" />
 
   <!-- Biometric messages -->
+  <java-symbol type="string" name="biometric_dialog_default_title" />
   <java-symbol type="string" name="biometric_error_hw_unavailable" />
   <java-symbol type="string" name="biometric_not_recognized" />
 
@@ -3269,17 +3273,17 @@
   <java-symbol type="integer" name="default_data_warning_level_mb" />
   <java-symbol type="bool" name="config_useVideoPauseWorkaround" />
   <java-symbol type="bool" name="config_sendPackageName" />
-  <java-symbol type="string" name="config_help_package_name_key" />
-  <java-symbol type="string" name="config_help_package_name_value" />
-  <java-symbol type="string" name="config_help_intent_extra_key" />
-  <java-symbol type="string" name="config_help_intent_name_key" />
-  <java-symbol type="string" name="config_feedback_intent_extra_key" />
-  <java-symbol type="string" name="config_feedback_intent_name_key" />
+  <java-symbol type="string" name="config_helpPackageNameKey" />
+  <java-symbol type="string" name="config_helpPackageNameValue" />
+  <java-symbol type="string" name="config_helpIntentExtraKey" />
+  <java-symbol type="string" name="config_helpIntentNameKey" />
+  <java-symbol type="string" name="config_feedbackIntentExtraKey" />
+  <java-symbol type="string" name="config_feedbackIntentNameKey" />
 
   <java-symbol type="array" name="config_hideWhenDisabled_packageNames" />
 
   <java-symbol type="string" name="config_dozeLongPressSensorType" />
-  <java-symbol type="string" name="config_dozeWakeLockScreenSensorType" />
+  <java-symbol type="bool" name="config_dozeWakeLockScreenSensorAvailable" />
 
   <java-symbol type="array" name="config_allowedGlobalInstantAppSettings" />
   <java-symbol type="array" name="config_allowedSystemInstantAppSettings" />
@@ -3475,4 +3479,8 @@
   <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index1" />
   <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index2" />
   <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index3" />
+
+  <java-symbol type="bool" name="config_useSmsAppService" />
+
+  <java-symbol type="string" name="config_defaultAssistantComponentName" />
 </resources>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index a7530ce..ad38f3d 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -880,6 +880,9 @@
         <item name="windowActivityTransitions">false</item>
     </style>
 
+    <!-- @hide Special theme for the default system Activity-based Alert dialogs. -->
+    <style name="Theme.Dialog.Confirmation" parent="Theme.DeviceDefault.Light.Dialog.Alert" />
+
     <!-- Theme for a window that looks like a toast. -->
     <style name="Theme.Toast" parent="Theme.DeviceDefault.Dialog">
         <item name="windowBackground">?attr/toastFrameBackground</item>
diff --git a/core/res/res/values/themes_leanback.xml b/core/res/res/values/themes_leanback.xml
index f71df9f..a80725c 100644
--- a/core/res/res/values/themes_leanback.xml
+++ b/core/res/res/values/themes_leanback.xml
@@ -130,4 +130,7 @@
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
       </style>
 
+    <!-- @hide Special theme for the default system Activity-based Alert dialogs. -->
+    <style name="Theme.Leanback.Dialog.Confirmation" parent="Theme.DeviceDefault.Dialog.Alert" />
+
 </resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index fb78b3b..7b3d940 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -109,12 +109,12 @@
     <!-- France: 5 digits, free: 3xxxx, premium [4-8]xxxx, plus EU:
          http://clients.txtnation.com/entries/161972-france-premium-sms-short-code-requirements,
          visual voicemail code for Orange: 21101 -->
-    <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101|20366" />
+    <shortcode country="fr" premium="[4-8]\\d{4}" free="3\\d{4}|116\\d{3}|21101|20366|555|2051" />
 
     <!-- United Kingdom (Great Britain): 4-6 digits, common codes [5-8]xxxx, plus EU:
          http://www.short-codes.com/media/Co-regulatoryCodeofPracticeforcommonshortcodes170206.pdf,
          visual voicemail code for EE: 887 -->
-    <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|2020|35890|61002|61202|887|83669|34664|40406|60174|7726|37726" />
+    <shortcode country="gb" pattern="\\d{4,6}" premium="[5-8]\\d{4}" free="116\\d{3}|2020|35890|61002|61202|887|83669|34664|40406|60174|7726|37726|88555|9017|9018" />
 
     <!-- Georgia: 4 digits, known premium codes listed -->
     <shortcode country="ge" pattern="\\d{4}" premium="801[234]|888[239]" />
@@ -189,11 +189,14 @@
     <!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
     <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223" />
 
+    <!-- Nigeria -->
+    <shortcode country="ng" pattern="\\d{1,5}" free="2441" />
+
     <!-- Norway: 4-5 digits (not confirmed), known premium codes listed -->
     <shortcode country="no" pattern="\\d{4,5}" premium="2201|222[67]" free="2171" />
 
     <!-- New Zealand: 3-4 digits, known premium codes listed -->
-    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="3067|3068|4053" />
+    <shortcode country="nz" pattern="\\d{3,4}" premium="3903|8995|4679" free="1737|2141|3067|3068|3110|4006|4053|4061|4062|4202|4300|4334|4412|4575|5626|8006|8681" />
 
     <!-- Peru: 4-5 digits (not confirmed), known premium codes listed -->
     <shortcode country="pe" pattern="\\d{4,5}" free="9963" />
@@ -209,7 +212,7 @@
 
     <!-- Portugal: 5 digits, plus EU:
          http://clients.txtnation.com/entries/158326-portugal-premium-sms-short-code-regulations -->
-    <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}|1262" />
+    <shortcode country="pt" premium="6[1289]\\d{3}" free="116\\d{3}|1262|12666" />
 
     <!-- Qatar: 1-5 digits (standard system default, not country specific) -->
     <shortcode country="qa" pattern="\\d{1,5}" free="92451" />
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index 4a58f88..2989df8 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -16,6 +16,7 @@
 
 package com.android.bandwidthtest;
 
+import android.app.UiAutomation;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo.State;
@@ -74,7 +75,13 @@
         Log.v(LOG_TAG, "Initialized mConnectionUtil");
         mUid = Process.myUid();
         mTManager = (TelephonyManager)mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        mDeviceId = mTManager.getDeviceId();
+        final UiAutomation uiAutomation = getInstrumentation().getUiAutomation();
+        try {
+            uiAutomation.adoptShellPermissionIdentity();
+            mDeviceId = mTManager.getDeviceId();
+        } finally {
+            uiAutomation.dropShellPermissionIdentity();
+        }
     }
 
     @Override
diff --git a/core/tests/coretests/Android.mk b/core/tests/coretests/Android.mk
index e0d5393..041fb7e 100644
--- a/core/tests/coretests/Android.mk
+++ b/core/tests/coretests/Android.mk
@@ -47,7 +47,6 @@
 
 LOCAL_JAVA_LIBRARIES := \
     android.test.runner \
-    conscrypt \
     telephony-common \
     org.apache.http.legacy \
     android.test.base \
@@ -67,10 +66,6 @@
 
 # Disable AAPT2 because the hacks below depend on the AAPT rules implementation
 LOCAL_USE_AAPT2 := false
-# When AAPT2 is enabled it will need --warn-manifest-validation to fix:
-# frameworks/base/core/tests/coretests/AndroidManifest.xml:26: error: unknown element <meta-data> found.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-# LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(BUILD_PACKAGE)
 # Rules to copy all the test apks to the intermediate raw resource directory
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index d704957..f60d8d0ad 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -61,6 +61,7 @@
     <uses-permission android:name="android.permission.READ_LOGS"/>
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_SMS"/>
+    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
     <uses-permission android:name="android.permission.USE_CREDENTIALS" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
diff --git a/core/tests/coretests/apks/install_multi_package/Android.mk b/core/tests/coretests/apks/install_multi_package/Android.mk
index 9727593..3f163de 100644
--- a/core/tests/coretests/apks/install_multi_package/Android.mk
+++ b/core/tests/coretests/apks/install_multi_package/Android.mk
@@ -8,10 +8,6 @@
 LOCAL_PACKAGE_NAME := install_multi_package
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/core/tests/coretests/apks/install_multi_package/AndroidManifest.xml:46: error: unexpected element <package> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(FrameworkCoreTests_BUILD_PACKAGE)
 #include $(BUILD_PACKAGE)
diff --git a/core/tests/coretests/apks/install_verifier_bad/Android.mk b/core/tests/coretests/apks/install_verifier_bad/Android.mk
index 679327c..745b4d3 100644
--- a/core/tests/coretests/apks/install_verifier_bad/Android.mk
+++ b/core/tests/coretests/apks/install_verifier_bad/Android.mk
@@ -6,9 +6,5 @@
 LOCAL_PACKAGE_NAME := install_verifier_bad
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/core/tests/coretests/apks/install_verifier_bad/AndroidManifest.xml:19: error: unexpected element <package-verifier> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/apks/install_verifier_good/Android.mk b/core/tests/coretests/apks/install_verifier_good/Android.mk
index 7d621b3..150fd8d 100644
--- a/core/tests/coretests/apks/install_verifier_good/Android.mk
+++ b/core/tests/coretests/apks/install_verifier_good/Android.mk
@@ -6,9 +6,5 @@
 LOCAL_PACKAGE_NAME := install_verifier_good
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/core/tests/coretests/apks/install_verifier_good/AndroidManifest.xml:19: error: unexpected element <package-verifier> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(FrameworkCoreTests_BUILD_PACKAGE)
diff --git a/core/tests/coretests/assets/fonts/1em_bidi_font.ttf b/core/tests/coretests/assets/fonts/1em_bidi_font.ttf
new file mode 100644
index 0000000..4599254
--- /dev/null
+++ b/core/tests/coretests/assets/fonts/1em_bidi_font.ttf
Binary files differ
diff --git a/core/tests/coretests/src/android/app/assist/AssistStructureTest.java b/core/tests/coretests/src/android/app/assist/AssistStructureTest.java
index bdb3e08..fe51a39 100644
--- a/core/tests/coretests/src/android/app/assist/AssistStructureTest.java
+++ b/core/tests/coretests/src/android/app/assist/AssistStructureTest.java
@@ -15,7 +15,9 @@
  */
 package android.app.assist;
 
+import static android.view.View.AUTOFILL_TYPE_TEXT;
 import static android.view.View.IMPORTANT_FOR_AUTOFILL_AUTO;
+import static android.view.View.IMPORTANT_FOR_AUTOFILL_YES;
 
 import static com.google.common.truth.Truth.assertThat;
 
@@ -27,7 +29,9 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.rule.ActivityTestRule;
 import android.support.test.runner.AndroidJUnit4;
+import android.text.InputFilter;
 import android.util.Log;
+import android.view.autofill.AutofillId;
 import android.widget.EditText;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
@@ -68,6 +72,16 @@
     // Cannot be much big because it could hang test due to blocking GC
     private static final int NUMBER_SMALL_VIEWS = 10_000;
 
+    // Autofill field constants
+    private static final AutofillId AUTOFILL_ID = new AutofillId(2);
+    private static final String AUTOFILL_HINTS = "hints";
+    private static final int MIN_TEXT_EMS = 5;
+    private static final int MAX_TEXT_EMS = 17;
+    private static final int MAX_TEXT_LENGTH = 23;
+
+    // ViewNodeBuilder structure for editing autofill fields
+    private AssistStructure.ViewNodeBuilder mBuilder;
+
     private EmptyLayoutActivity mActivity;
 
     private final ActivityTestRule<EmptyLayoutActivity> mActivityTestRule =
@@ -211,6 +225,12 @@
     private EditText newSmallView() {
         EditText view = new EditText(mContext);
         view.setText("I AM GROOT");
+        view.setMinEms(MIN_TEXT_EMS);
+        view.setMaxEms(MAX_TEXT_EMS);
+        view.setAutofillId(AUTOFILL_ID);
+        view.setAutofillHints(AUTOFILL_HINTS);
+        view.setFilters(new InputFilter[] { new InputFilter.LengthFilter(MAX_TEXT_LENGTH) });
+        view.setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES);
         return view;
     }
 
@@ -220,6 +240,16 @@
         assertThat(view.getIdEntry()).isNull();
         assertThat(view.getAutofillId()).isNotNull();
         assertThat(view.getText().toString()).isEqualTo("I AM GROOT");
+
+        assertThat(view.getAutofillType()).isEqualTo(AUTOFILL_TYPE_TEXT);
+
+        // fields controlled by mAutofillFlag
+        assertThat(view.getAutofillId().getViewId()).isEqualTo(2);
+        assertThat(view.getAutofillHints()[0]).isEqualTo(AUTOFILL_HINTS);
+        assertThat(view.getMinTextEms()).isEqualTo(MIN_TEXT_EMS);
+        assertThat(view.getMaxTextEms()).isEqualTo(MAX_TEXT_EMS);
+        assertThat(view.getMaxTextLength()).isEqualTo(MAX_TEXT_LENGTH);
+        assertThat(view.getImportantForAutofill()).isEqualTo(IMPORTANT_FOR_AUTOFILL_YES);
     }
 
     private EditText newBigView() {
diff --git a/core/tests/coretests/src/android/content/ContentResolverTest.java b/core/tests/coretests/src/android/content/ContentResolverTest.java
index 6256d08..0036186 100644
--- a/core/tests/coretests/src/android/content/ContentResolverTest.java
+++ b/core/tests/coretests/src/android/content/ContentResolverTest.java
@@ -13,31 +13,149 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.content;
 
-import android.content.ContentResolver;
-import android.provider.ContactsContract;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
-@Suppress  // Failing.
-public class ContentResolverTest extends AndroidTestCase {
-    private ContentResolver mContentResolver;
+import android.content.res.AssetFileDescriptor;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ImageDecoder;
+import android.graphics.Paint;
+import android.net.Uri;
+import android.os.MemoryFile;
+import android.os.ParcelFileDescriptor;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Size;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContentResolver = mContext.getContentResolver();
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class ContentResolverTest {
+
+    private ContentResolver mResolver;
+    private IContentProvider mProvider;
+    private ContentProviderClient mClient;
+
+    private int mSize = 256_000;
+    private MemoryFile mImage;
+
+    @Before
+    public void setUp() throws Exception {
+        mResolver = InstrumentationRegistry.getInstrumentation().getTargetContext()
+                .getContentResolver();
+        mProvider = mock(IContentProvider.class);
+        mClient = new ContentProviderClient(mResolver, mProvider, false);
+
+        mImage = new MemoryFile("temp.png", mSize);
     }
 
-    @LargeTest
-    public void testCursorFinalizer() throws Exception {
-        // TODO: Want a test case that more predictably reproduce this issue. Selected
-        // 600 as this causes the problem 100% of the runs on current hw, it might not
-        // do so on some other configuration though.
-        for (int i = 0; i < 600; i++) {
-            mContentResolver.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
-        }
+    @After
+    public void tearDown() throws Exception {
+        mImage.close();
+        mImage = null;
+    }
+
+    private void initImage(int width, int height) throws Exception {
+        final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        final Canvas canvas = new Canvas(bitmap);
+
+        canvas.drawColor(Color.RED);
+
+        final Paint paint = new Paint();
+        paint.setColor(Color.BLUE);
+        paint.setStyle(Paint.Style.FILL);
+        canvas.drawRect(0, 0, width / 2, height / 2, paint);
+
+        bitmap.compress(Bitmap.CompressFormat.PNG, 90, mImage.getOutputStream());
+
+        final AssetFileDescriptor afd = new AssetFileDescriptor(
+                new ParcelFileDescriptor(mImage.getFileDescriptor()), 0, mSize, null);
+        when(mProvider.openTypedAssetFile(any(), any(), any(), any(), any())).thenReturn(afd);
+    }
+
+    private static void assertImageAspectAndContents(Bitmap bitmap) {
+        // And correct aspect ratio
+        final int before = (100 * 1280) / 960;
+        final int after = (100 * bitmap.getWidth()) / bitmap.getHeight();
+        assertEquals(before, after);
+
+        // And scaled correctly
+        final int halfX = bitmap.getWidth() / 2;
+        final int halfY = bitmap.getHeight() / 2;
+        assertEquals(Color.BLUE, bitmap.getPixel(halfX - 10, halfY - 10));
+        assertEquals(Color.RED, bitmap.getPixel(halfX + 10, halfY - 10));
+        assertEquals(Color.RED, bitmap.getPixel(halfX - 10, halfY + 10));
+        assertEquals(Color.RED, bitmap.getPixel(halfX + 10, halfY + 10));
+    }
+
+    @Test
+    public void testLoadThumbnail_Normal() throws Exception {
+        initImage(1280, 960);
+
+        Bitmap res = ContentResolver.loadThumbnail(mClient,
+                Uri.parse("content://com.example/"), new Size(1280, 960), null,
+                ImageDecoder.ALLOCATOR_SOFTWARE);
+
+        // Size should be untouched
+        assertEquals(1280, res.getWidth());
+        assertEquals(960, res.getHeight());
+
+        assertImageAspectAndContents(res);
+    }
+
+    @Test
+    public void testLoadThumbnail_Scaling() throws Exception {
+        initImage(1280, 960);
+
+        Bitmap res = ContentResolver.loadThumbnail(mClient,
+                Uri.parse("content://com.example/"), new Size(320, 240), null,
+                ImageDecoder.ALLOCATOR_SOFTWARE);
+
+        // Size should be much smaller
+        assertTrue(res.getWidth() <= 640);
+        assertTrue(res.getHeight() <= 480);
+
+        assertImageAspectAndContents(res);
+    }
+
+    @Test
+    public void testLoadThumbnail_Aspect() throws Exception {
+        initImage(1280, 960);
+
+        Bitmap res = ContentResolver.loadThumbnail(mClient,
+                Uri.parse("content://com.example/"), new Size(240, 320), null,
+                ImageDecoder.ALLOCATOR_SOFTWARE);
+
+        // Size should be much smaller
+        assertTrue(res.getWidth() <= 640);
+        assertTrue(res.getHeight() <= 480);
+
+        assertImageAspectAndContents(res);
+    }
+
+    @Test
+    public void testLoadThumbnail_Tiny() throws Exception {
+        initImage(32, 24);
+
+        Bitmap res = ContentResolver.loadThumbnail(mClient,
+                Uri.parse("content://com.example/"), new Size(320, 240), null,
+                ImageDecoder.ALLOCATOR_SOFTWARE);
+
+        // Size should be untouched
+        assertEquals(32, res.getWidth());
+        assertEquals(24, res.getHeight());
+
+        assertImageAspectAndContents(res);
     }
 }
diff --git a/core/tests/coretests/src/android/content/ContextTest.java b/core/tests/coretests/src/android/content/ContextTest.java
new file mode 100644
index 0000000..c8a3098
--- /dev/null
+++ b/core/tests/coretests/src/android/content/ContextTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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.content;
+
+import static org.junit.Assert.assertEquals;
+
+import android.app.ActivityThread;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.WindowManager;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ContextTest {
+    @Test
+    public void testDisplayIdForSystemContext() {
+        final Context systemContext =
+                ActivityThread.currentActivityThread().getSystemContext();
+
+        assertEquals(systemContext.getDisplay().getDisplayId(), systemContext.getDisplayId());
+    }
+
+    @Test
+    public void testDisplayIdForTestContext() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+
+        assertEquals(testContext.getDisplay().getDisplayId(), testContext.getDisplayId());
+    }
+
+    @Test
+    public void testDisplayIdForDefaultDisplayContext() {
+        final Context testContext =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        final WindowManager wm = testContext.getSystemService(WindowManager.class);
+        final Context defaultDisplayContext =
+                testContext.createDisplayContext(wm.getDefaultDisplay());
+
+        assertEquals(defaultDisplayContext.getDisplay().getDisplayId(),
+                defaultDisplayContext.getDisplayId());
+    }
+}
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 584257b..e248a77 100644
--- a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
+++ b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
@@ -45,7 +45,7 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
 
-import libcore.io.IoUtils;
+import libcore.testing.io.TestIoUtils;
 
 import org.junit.After;
 import org.junit.Assert;
@@ -63,7 +63,7 @@
 
     @Before
     public void setUp() {
-        mTmpDir = IoUtils.createTemporaryDirectory("DexMetadataHelperTest");
+        mTmpDir = TestIoUtils.createTemporaryDirectory("DexMetadataHelperTest");
     }
 
     @After
diff --git a/core/tests/coretests/src/android/os/BinderTest.java b/core/tests/coretests/src/android/os/BinderTest.java
new file mode 100644
index 0000000..1beb598
--- /dev/null
+++ b/core/tests/coretests/src/android/os/BinderTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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.os;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+public class BinderTest extends TestCase {
+
+    @SmallTest
+    public void testSetWorkSource() throws Exception {
+        Binder.setThreadWorkSource(100);
+        assertEquals(100, Binder.getThreadWorkSource());
+    }
+
+    @SmallTest
+    public void testClearWorkSource() throws Exception {
+        Binder.setThreadWorkSource(100);
+        Binder.clearThreadWorkSource();
+        assertEquals(-1, Binder.getThreadWorkSource());
+    }
+}
diff --git a/core/tests/coretests/src/android/os/FileUtilsTest.java b/core/tests/coretests/src/android/os/FileUtilsTest.java
index 20fe162..6966448 100644
--- a/core/tests/coretests/src/android/os/FileUtilsTest.java
+++ b/core/tests/coretests/src/android/os/FileUtilsTest.java
@@ -41,6 +41,7 @@
 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.content.Context;
 import android.os.FileUtils.MemoryPipe;
@@ -48,7 +49,6 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.runner.AndroidJUnit4;
 
-import libcore.io.IoUtils;
 import libcore.io.Streams;
 
 import com.google.android.collect.Sets;
@@ -95,7 +95,7 @@
 
     @After
     public void tearDown() throws Exception {
-        IoUtils.deleteContents(mDir);
+        FileUtils.deleteContents(mDir);
         FileUtils.deleteContents(mTarget);
     }
 
@@ -511,6 +511,20 @@
                 MODE_WRITE_ONLY | MODE_CREATE | MODE_APPEND);
     }
 
+    @Test
+    public void testTranslateMode_Invalid() throws Exception {
+        try {
+            translateModeStringToPosix("rwx");
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+        try {
+            translateModeStringToPosix("");
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
     private static void assertTranslate(String string, int posix, int pfd) {
         assertEquals(posix, translateModeStringToPosix(string));
         assertEquals(string, translateModePosixToString(posix));
diff --git a/core/tests/coretests/src/android/os/PowerManagerTest.java b/core/tests/coretests/src/android/os/PowerManagerTest.java
index 0d250b8..da17b56 100644
--- a/core/tests/coretests/src/android/os/PowerManagerTest.java
+++ b/core/tests/coretests/src/android/os/PowerManagerTest.java
@@ -64,7 +64,7 @@
 
         // TODO: Some sort of functional test (maybe not in the unit test here?)
         // that confirms that things are really happening e.g. screen power, keyboard power.
-}
+    }
 
     /**
      * Confirm that we can't create dysfunctional wakelocks.
@@ -85,6 +85,25 @@
     }
 
     /**
+     * Ensure that we can have work sources with work chains when uid is not set directly on work
+     * source, and that this doesn't crash system server.
+     *
+     * @throws Exception
+     */
+    @SmallTest
+    public void testWakeLockWithWorkChains() throws Exception {
+        PowerManager.WakeLock wakeLock = mPm.newWakeLock(
+                PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,
+                "TEST_LOCK");
+        WorkSource workSource = new WorkSource();
+        WorkSource.WorkChain workChain = workSource.createWorkChain();
+        workChain.addNode(1000, "test");
+        wakeLock.setWorkSource(workSource);
+
+        doTestWakeLock(wakeLock);
+    }
+
+    /**
      * Apply a few tests to a wakelock to make sure it's healthy.
      *
      * @param wl The wakelock to be tested.
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 4ecdc42..9778acb 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -368,6 +368,8 @@
                     Settings.Global.PRIV_APP_OOB_ENABLED,
                     Settings.Global.PRIV_APP_OOB_LIST,
                     Settings.Global.PRIVATE_DNS_DEFAULT_MODE,
+                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED,
+                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED,
                     Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
                     Settings.Global.RADIO_BLUETOOTH,
                     Settings.Global.RADIO_CELL,
@@ -397,6 +399,7 @@
                     Settings.Global.SHOW_TEMPERATURE_WARNING,
                     Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
                     Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
+                    Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED,
                     Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
                     Settings.Global.SMS_OUTGOING_CHECK_MAX_COUNT,
                     Settings.Global.SMS_SHORT_CODE_CONFIRMATION,
@@ -449,6 +452,7 @@
                     Settings.Global.GPU_DEBUG_APP,
                     Settings.Global.GPU_DEBUG_LAYERS,
                     Settings.Global.ANGLE_ENABLED_APP,
+                    Settings.Global.GPU_DEBUG_LAYER_APP,
                     Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING,
                     Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_PERSISTENT,
                     Settings.Global.INSTALL_CARRIER_APP_NOTIFICATION_SLEEP_MILLIS,
@@ -542,6 +546,7 @@
                  Settings.Secure.BACKUP_ENABLED,
                  Settings.Secure.BACKUP_PROVISIONED,
                  Settings.Secure.BACKUP_TRANSPORT,
+                 Settings.Secure.CALL_REDIRECTION_DEFAULT_APPLICATION,
                  Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED, // Candidate for backup?
                  Settings.Secure.CARRIER_APPS_HANDLED,
                  Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
diff --git a/core/tests/coretests/src/android/text/LayoutBidiCursorPathTest.java b/core/tests/coretests/src/android/text/LayoutBidiCursorPathTest.java
new file mode 100644
index 0000000..1208d7c
--- /dev/null
+++ b/core/tests/coretests/src/android/text/LayoutBidiCursorPathTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.text;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import android.content.Context;
+import android.graphics.Path;
+import android.graphics.Typeface;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.text.method.MetaKeyKeyListener;
+import android.view.KeyEvent;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class LayoutBidiCursorPathTest {
+
+    private static final float BIDI_TEXT_SIZE = 12f;
+    private static final String LTR_TEXT = "hello";
+    private static final String RTL_TEXT = "مرحبا";
+
+    private SpannableStringBuilder mBidiText;
+    private TextPaint mTextPaint;
+
+    @Before
+    public void setup() {
+        mBidiText = new SpannableStringBuilder(LTR_TEXT + RTL_TEXT);
+
+        final Context context = InstrumentationRegistry.getTargetContext();
+        mTextPaint = new TextPaint();
+        mTextPaint.setTypeface(
+                Typeface.createFromAsset(context.getAssets(), "fonts/1em_bidi_font.ttf"));
+        mTextPaint.setTextSize(BIDI_TEXT_SIZE);
+    }
+
+    @Test
+    public void testGetCursorPathSegments() {
+        // Setup layout and Act.
+        final Path actualPath = new Path();
+        setupLayoutAndGetCursorPath(actualPath);
+
+        // Expected path.
+        final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
+        final int top = 0;
+        // sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
+        final int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
+
+        final Path expectedPath = new Path();
+
+        expectedPath.moveTo(h1, top);
+        expectedPath.lineTo(h1, bottom);
+
+        // Assert.
+        assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
+    }
+
+    @Test
+    public void testGetCursorPath_whenShiftIsPressed() {
+        // When shift is pressed a triangle is drawn at the bottom quarter of the cursor.
+        // Set up key.
+        final MetaKeyKeyListener metaKeyKeyListener = new MetaKeyKeyListener() {};
+        metaKeyKeyListener
+            .onKeyDown(null /*view*/, mBidiText, KeyEvent.KEYCODE_SHIFT_RIGHT, null /*keyEvent*/);
+
+        // Setup layout and Act.
+        final Path actualPath = new Path();
+        setupLayoutAndGetCursorPath(actualPath);
+
+        // Expected path.
+        final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
+        final int top = 0;
+        // sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
+        int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
+        // Draw a triangle at the bottom quarter of the cursor, thus cut the cursor to its 3/4
+        // length.
+        final int dist = (bottom - top) / 4;
+        bottom -= dist;
+
+        final Path expectedPath = new Path();
+
+        expectedPath.moveTo(h1, top);
+        expectedPath.lineTo(h1, bottom);
+
+        expectedPath.moveTo(h1, bottom);
+        expectedPath.lineTo(h1 - dist, bottom + dist);
+
+        expectedPath.moveTo(h1 - dist, bottom + dist - 0.5f);
+        expectedPath.lineTo(h1 + dist, bottom + dist - 0.5f);
+
+        expectedPath.moveTo(h1 + dist, bottom + dist);
+        expectedPath.lineTo(h1, bottom);
+
+        // Assert.
+        assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
+    }
+
+    @Test
+    public void testGetCursorPath_whenAltIsPressed() {
+        // When alt is pressed a triangle is drawn at the top quarter of the cursor.
+        // Set up key.
+        final MetaKeyKeyListener metaKeyKeyListener = new MetaKeyKeyListener() {};
+        metaKeyKeyListener
+            .onKeyDown(null /*view*/, mBidiText, KeyEvent.KEYCODE_ALT_RIGHT, null /*keyEvent*/);
+
+        // Setup layout and Act.
+        final Path actualPath = new Path();
+        setupLayoutAndGetCursorPath(actualPath);
+
+        // Expected path.
+        final float h1 = BIDI_TEXT_SIZE * LTR_TEXT.length() - 0.5f;
+        int top = 0;
+        // sTypoLineGap is set to 1/5 of the Height in font metrics of the font file used here.
+        final int bottom = Math.round(BIDI_TEXT_SIZE + BIDI_TEXT_SIZE / 5f);
+        // Draw a triangle at the top quarter of the cursor, thus cut the cursor to its 3/4 length.
+        final int dist = (bottom - top) / 4;
+        top += dist;
+
+        final Path expectedPath = new Path();
+
+        expectedPath.moveTo(h1, top);
+        expectedPath.lineTo(h1, bottom);
+
+        expectedPath.moveTo(h1, top);
+        expectedPath.lineTo(h1 - dist, top - dist);
+
+        expectedPath.moveTo(h1 - dist, top - dist + 0.5f);
+        expectedPath.lineTo(h1 + dist, top - dist + 0.5f);
+
+        expectedPath.moveTo(h1 + dist, top - dist);
+        expectedPath.lineTo(h1, top);
+
+        // Assert.
+        assertArrayEquals(expectedPath.approximate(0f), actualPath.approximate(0f), 0f);
+    }
+
+    private void setupLayoutAndGetCursorPath(Path path) {
+        final Layout layout = StaticLayout.Builder.obtain(
+                mBidiText, 0, mBidiText.length(),  mTextPaint, Integer.MAX_VALUE)
+                .setIncludePad(false)
+                .build();
+
+        layout.getCursorPath(LTR_TEXT.length(), path, mBidiText);
+    }
+}
diff --git a/core/tests/coretests/src/android/text/MeasuredParagraphTest.java b/core/tests/coretests/src/android/text/MeasuredParagraphTest.java
index f3d6013..3d15eb9 100644
--- a/core/tests/coretests/src/android/text/MeasuredParagraphTest.java
+++ b/core/tests/coretests/src/android/text/MeasuredParagraphTest.java
@@ -73,7 +73,7 @@
         assertEquals(0, mt.getWidths().size());
         assertEquals(0, mt.getSpanEndCache().size());
         assertEquals(0, mt.getFontMetrics().size());
-        assertNull(mt.getNativeMeasuredParagraph());
+        assertNull(mt.getMeasuredText());
 
         // Recycle it
         MeasuredParagraph mt2 = MeasuredParagraph.buildForBidi("_VVV_", 1, 4, RTL, mt);
@@ -85,7 +85,7 @@
         assertEquals(0, mt2.getWidths().size());
         assertEquals(0, mt2.getSpanEndCache().size());
         assertEquals(0, mt2.getFontMetrics().size());
-        assertNull(mt.getNativeMeasuredParagraph());
+        assertNull(mt.getMeasuredText());
 
         mt2.recycle();
     }
@@ -107,7 +107,7 @@
         assertEquals(10, mt.getWidths().get(2), 0);
         assertEquals(0, mt.getSpanEndCache().size());
         assertEquals(0, mt.getFontMetrics().size());
-        assertNull(mt.getNativeMeasuredParagraph());
+        assertNull(mt.getMeasuredText());
 
         // Recycle it
         MeasuredParagraph mt2 =
@@ -124,7 +124,7 @@
         assertEquals(5, mt2.getWidths().get(2), 0);
         assertEquals(0, mt2.getSpanEndCache().size());
         assertEquals(0, mt2.getFontMetrics().size());
-        assertNull(mt.getNativeMeasuredParagraph());
+        assertNull(mt.getMeasuredText());
 
         mt2.recycle();
     }
@@ -144,7 +144,7 @@
         assertEquals(1, mt.getSpanEndCache().size());
         assertEquals(3, mt.getSpanEndCache().get(0));
         assertNotEquals(0, mt.getFontMetrics().size());
-        assertNotNull(mt.getNativeMeasuredParagraph());
+        assertNotNull(mt.getMeasuredText());
 
         // Recycle it
         MeasuredParagraph mt2 =
@@ -159,7 +159,7 @@
         assertEquals(1, mt2.getSpanEndCache().size());
         assertEquals(4, mt2.getSpanEndCache().get(0));
         assertNotEquals(0, mt2.getFontMetrics().size());
-        assertNotNull(mt.getNativeMeasuredParagraph());
+        assertNotNull(mt.getMeasuredText());
 
         mt2.recycle();
     }
diff --git a/core/tests/coretests/src/android/text/format/DateUtilsTest.java b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
index f8e3b4d..872b71a 100644
--- a/core/tests/coretests/src/android/text/format/DateUtilsTest.java
+++ b/core/tests/coretests/src/android/text/format/DateUtilsTest.java
@@ -117,7 +117,7 @@
     @Test
     public void testFormatSameDayTime() {
         // This test assumes a default DateFormat.is24Hour setting.
-        DateFormat.is24Hour = null;
+        DateFormat.set24HourTimePref(null);
         Date date = new Date(109, 0, 19, 3, 30, 15);
         long fixedTime = date.getTime();
 
diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
index c98e646..45a5010 100644
--- a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
+++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java
@@ -20,7 +20,6 @@
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
-import android.test.suitebuilder.annotation.Suppress;
 import android.text.InputType;
 import android.util.KeyUtils;
 import android.view.KeyEvent;
@@ -239,7 +238,6 @@
     }
 
     @Test
-    @Suppress
     public void testEmojiModifier() {
         EditorState state = new EditorState();
 
@@ -256,20 +254,15 @@
         // Isolated multiple emoji modifier
         state.setByString("| U+1F3FB U+1F3FB");
         forwardDelete(state, 0);
-        state.assertEquals("| U+1F3FB");
-        forwardDelete(state, 0);
         state.assertEquals("|");
 
         // Multiple emoji modifiers
         state.setByString("| U+1F466 U+1F3FB U+1F3FB");
         forwardDelete(state, 0);
-        state.assertEquals("| U+1F3FB");
-        forwardDelete(state, 0);
         state.assertEquals("|");
     }
 
     @Test
-    @Suppress
     public void testMixedEdgeCases() {
         EditorState state = new EditorState();
 
@@ -318,7 +311,7 @@
         // COMBINING ENCLOSING KEYCAP + emoji modifier
         state.setByString("| '1' U+20E3 U+1F3FB");
         forwardDelete(state, 0);
-        state.assertEquals("| U+1F3FB");
+        state.assertEquals("|");
 
         // Emoji modifier + COMBINING ENCLOSING KEYCAP
         state.setByString("| U+1F466 U+1F3FB U+20E3");
@@ -360,7 +353,7 @@
         // Variation selector + emoji modifier
         state.setByString("| U+2665 U+FE0F U+1F3FB");
         forwardDelete(state, 0);
-        state.assertEquals("| U+1F3FB");
+        state.assertEquals("|");
 
         // Emoji modifier + variation selector
         state.setByString("| U+1F466 U+1F3FB U+FE0F");
@@ -396,7 +389,7 @@
         // Start with ZERO WIDTH JOINER + emoji modifier
         state.setByString("| U+200D U+1F3FB");
         forwardDelete(state, 0);
-        state.assertEquals("| U+1F3FB");
+        state.assertEquals("|");
 
         // ZERO WIDTH JOINER + emoji modifier
         state.setByString("| U+1F469 U+200D U+1F3FB");
@@ -409,17 +402,14 @@
         state.assertEquals("|");
 
         // Emoji modifier + ZERO WIDTH JOINER
-        state.setByString("| U+1F466 U+1F3FB U+200D U+1F469");
-        forwardDelete(state, 0);
-        state.assertEquals("| U+1F469");
-        forwardDelete(state, 0);
-        state.assertEquals("|");
+        // TODO(nona): Revive this test once HarfBuzz is updated to 2.0.2 (b/117953171)
+        // state.setByString("| U+1F466 U+1F3FB U+200D U+1F469");
+        // forwardDelete(state, 0);
+        // state.assertEquals("|");
 
         // Regional indicator symbol + emoji modifier
         state.setByString("| U+1F1FA U+1F3FB");
         forwardDelete(state, 0);
-        state.assertEquals("| U+1F3FB");
-        forwardDelete(state, 0);
         state.assertEquals("|");
 
         // Emoji modifier + regional indicator symbol
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index fe45fe7..8e4f2cd 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -17,6 +17,7 @@
 package android.view;
 
 import static android.view.DisplayCutout.NO_CUTOUT;
+import static android.view.DisplayCutout.extractBoundsFromList;
 import static android.view.DisplayCutout.fromSpec;
 
 import static org.hamcrest.Matchers.equalTo;
@@ -28,6 +29,7 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
+import android.graphics.Insets;
 import android.graphics.Rect;
 import android.os.Parcel;
 import android.platform.test.annotations.Presubmit;
@@ -39,38 +41,95 @@
 import org.junit.runner.RunWith;
 
 import java.util.Arrays;
+import java.util.Collections;
+
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
 public class DisplayCutoutTest {
 
+    private static final Rect ZERO_RECT = new Rect();
+
     /** This is not a consistent cutout. Useful for verifying insets in one go though. */
     final DisplayCutout mCutoutNumbers = new DisplayCutout(
-            new Rect(1, 2, 3, 4),
-            Arrays.asList(new Rect(5, 6, 7, 8)));
+            Insets.of(5, 6, 7, 8) /* safeInsets */,
+            null /* boundLeft */,
+            new Rect(9, 0, 10, 1) /* boundTop */,
+            null /* boundRight */,
+            null /* boundBottom */);
 
     final DisplayCutout mCutoutTop = createCutoutTop();
 
     @Test
+    public void testExtractBoundsFromList_left() {
+        Rect safeInsets = new Rect(10, 0, 0, 0);
+        Rect bound = new Rect(0, 80, 10, 120);
+        assertThat(extractBoundsFromList(safeInsets, Collections.singletonList(bound)),
+                equalTo(new Rect[]{bound, ZERO_RECT, ZERO_RECT, ZERO_RECT}));
+    }
+
+    @Test
+    public void testExtractBoundsFromList_top() {
+        Rect safeInsets = new Rect(0, 10, 0, 0);
+        Rect bound = new Rect(80, 0, 120, 10);
+        assertThat(extractBoundsFromList(safeInsets, Collections.singletonList(bound)),
+                equalTo(new Rect[]{ZERO_RECT, bound, ZERO_RECT, ZERO_RECT}));
+    }
+
+    @Test
+    public void testExtractBoundsFromList_right() {
+        Rect safeInsets = new Rect(0, 0, 10, 0);
+        Rect bound = new Rect(190, 80, 200, 120);
+        assertThat(extractBoundsFromList(safeInsets, Collections.singletonList(bound)),
+                equalTo(new Rect[]{ZERO_RECT, ZERO_RECT, bound, ZERO_RECT}));
+    }
+
+    @Test
+    public void testExtractBoundsFromList_bottom() {
+        Rect safeInsets = new Rect(0, 0, 0, 10);
+        Rect bound = new Rect(80, 190, 120, 200);
+        assertThat(extractBoundsFromList(safeInsets, Collections.singletonList(bound)),
+                equalTo(new Rect[]{ZERO_RECT, ZERO_RECT, ZERO_RECT, bound}));
+    }
+
+    @Test
+    public void testExtractBoundsFromList_top_and_bottom() {
+        Rect safeInsets = new Rect(0, 1, 0, 10);
+        Rect boundTop = new Rect(80, 0, 120, 10);
+        Rect boundBottom = new Rect(80, 190, 120, 200);
+        assertThat(extractBoundsFromList(safeInsets,
+                Arrays.asList(new Rect[]{boundTop, boundBottom})),
+                equalTo(new Rect[]{ZERO_RECT, boundTop, ZERO_RECT, boundBottom}));
+    }
+
+    @Test
+    public void testExtractBoundsFromList_nullBoundingRects() {
+        Rect safeInsets = new Rect(0, 0, 0, 0);
+        assertThat(extractBoundsFromList(safeInsets, null /* boundingRects */),
+                equalTo(new Rect[]{ZERO_RECT, ZERO_RECT, ZERO_RECT, ZERO_RECT}));
+    }
+
+    @Test
+    public void testExtractBoundsFromList_nullSafeInsets() {
+        assertThat(extractBoundsFromList(null /* safeInsets */, Collections.emptyList()),
+                equalTo(new Rect[]{ZERO_RECT, ZERO_RECT, ZERO_RECT, ZERO_RECT}));
+    }
+
+    @Test
     public void hasCutout() throws Exception {
         assertTrue(NO_CUTOUT.isEmpty());
         assertFalse(mCutoutTop.isEmpty());
     }
 
     @Test
-    public void getSafeInsets() throws Exception {
-        assertEquals(1, mCutoutNumbers.getSafeInsetLeft());
-        assertEquals(2, mCutoutNumbers.getSafeInsetTop());
-        assertEquals(3, mCutoutNumbers.getSafeInsetRight());
-        assertEquals(4, mCutoutNumbers.getSafeInsetBottom());
+    public void testGetSafeInsets() throws Exception {
+        assertEquals(5, mCutoutNumbers.getSafeInsetLeft());
+        assertEquals(6, mCutoutNumbers.getSafeInsetTop());
+        assertEquals(7, mCutoutNumbers.getSafeInsetRight());
+        assertEquals(8, mCutoutNumbers.getSafeInsetBottom());
 
-        assertEquals(new Rect(1, 2, 3, 4), mCutoutNumbers.getSafeInsets());
-    }
-
-    @Test
-    public void getBoundingRect() throws Exception {
-        assertEquals(new Rect(50, 0, 75, 100), mCutoutTop.getBounds().getBounds());
+        assertEquals(new Rect(5, 6, 7, 8), mCutoutNumbers.getSafeInsets());
     }
 
     @Test
@@ -102,30 +161,30 @@
     public void inset_insets_withLeftCutout() throws Exception {
         DisplayCutout cutout = createCutoutWithInsets(100, 0, 0, 0).inset(1, 2, 3, 4);
 
-        assertEquals(cutout.getSafeInsetLeft(), 99);
-        assertEquals(cutout.getSafeInsetTop(), 0);
-        assertEquals(cutout.getSafeInsetRight(), 0);
-        assertEquals(cutout.getSafeInsetBottom(), 0);
+        assertEquals(99, cutout.getSafeInsetLeft());
+        assertEquals(0, cutout.getSafeInsetTop());
+        assertEquals(0, cutout.getSafeInsetRight());
+        assertEquals(0, cutout.getSafeInsetBottom());
     }
 
     @Test
     public void inset_insets_withTopCutout() throws Exception {
         DisplayCutout cutout = mCutoutTop.inset(1, 2, 3, 4);
 
-        assertEquals(cutout.getSafeInsetLeft(), 0);
-        assertEquals(cutout.getSafeInsetTop(), 98);
-        assertEquals(cutout.getSafeInsetRight(), 0);
-        assertEquals(cutout.getSafeInsetBottom(), 0);
+        assertEquals(0, cutout.getSafeInsetLeft());
+        assertEquals(98, cutout.getSafeInsetTop());
+        assertEquals(0, cutout.getSafeInsetRight());
+        assertEquals(0, cutout.getSafeInsetBottom());
     }
 
     @Test
     public void inset_insets_withRightCutout() throws Exception {
         DisplayCutout cutout = createCutoutWithInsets(0, 0, 100, 0).inset(1, 2, 3, 4);
 
-        assertEquals(cutout.getSafeInsetLeft(), 0);
-        assertEquals(cutout.getSafeInsetTop(), 0);
-        assertEquals(cutout.getSafeInsetRight(), 97);
-        assertEquals(cutout.getSafeInsetBottom(), 0);
+        assertEquals(0, cutout.getSafeInsetLeft());
+        assertEquals(0, cutout.getSafeInsetTop());
+        assertEquals(97, cutout.getSafeInsetRight());
+        assertEquals(0, cutout.getSafeInsetBottom());
     }
 
     @Test
@@ -153,16 +212,20 @@
     @Test
     public void inset_bounds() throws Exception {
         DisplayCutout cutout = mCutoutTop.inset(1, 2, 3, 4);
-
-        assertEquals(new Rect(49, -2, 74, 98), cutout.getBounds().getBounds());
+        assertThat(cutout.getBoundingRectsAll(), equalTo(
+                new Rect[]{ ZERO_RECT, new Rect(49, -2, 74, 98), ZERO_RECT, ZERO_RECT }));
     }
 
+
+    // TODO: Deprecate fromBoundingRect.
+    /*
     @Test
     public void fromBoundingPolygon() throws Exception {
         assertEquals(
                 new Rect(50, 0, 75, 100),
                 DisplayCutout.fromBoundingRect(50, 0, 75, 100).getBounds().getBounds());
     }
+    */
 
     @Test
     public void parcel_unparcel_regular() {
@@ -231,6 +294,10 @@
         DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z"
                 + "@bottom M -50,0 v -10,0 h 100 v 20 z", 200, 400, 2f);
         assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 10)));
+        assertThat(cutout.getBoundingRectsAll(), equalTo(new Rect[]{
+                ZERO_RECT, new Rect(50, 0, 150, 20),
+                ZERO_RECT, new Rect(50, 390, 150, 410)
+        }));
     }
 
     @Test
@@ -281,8 +348,10 @@
     }
 
     private static DisplayCutout createCutoutWithInsets(int left, int top, int right, int bottom) {
+        Insets safeInset = Insets.of(left, top, right, bottom);
+        Rect boundTop = new Rect(50, 0, 75, 100);
         return new DisplayCutout(
-                new Rect(left, top, right, bottom),
-                Arrays.asList(new Rect(50, 0, 75, 100)));
+                safeInset, null /* boundLeft */, boundTop, null /* boundRight */,
+                null /* boundBottom */);
     }
 }
diff --git a/core/tests/coretests/src/android/view/MotionEventTest.java b/core/tests/coretests/src/android/view/MotionEventTest.java
index 1a480c7..023526f 100644
--- a/core/tests/coretests/src/android/view/MotionEventTest.java
+++ b/core/tests/coretests/src/android/view/MotionEventTest.java
@@ -54,6 +54,13 @@
         MotionEvent motionEvent = MotionEvent.obtain(0, 0, ACTION_DOWN,
                 pointerCount, properties, coords,
                 0, 0, 0, 0, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, displayId, 0);
+
+        MotionEvent motionEvent_Single = MotionEvent.obtain(0 /* downTime */, 0 /* eventTime */,
+                ACTION_DOWN /* action */, 0f /* x */, 0f /* y */, 0/* pressure */, 0 /* size */,
+                0 /* metaState */, 0 /* xPrecision */, 0 /* yPrecision */,
+                0 /* deviceId */, 0 /* edgeFlags */, InputDevice.SOURCE_TOUCHSCREEN, displayId);
+
+        assertEquals(displayId, motionEvent_Single.getDisplayId());
         assertEquals(displayId, motionEvent.getDisplayId());
 
         displayId = 5;
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
index 69d2828..506e544 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityNodeInfoTest.java
@@ -45,7 +45,7 @@
     // The number of fields tested in the corresponding CTS AccessibilityNodeInfoTest:
     // See fullyPopulateAccessibilityNodeInfo, assertEqualsAccessibilityNodeInfo,
     // and assertAccessibilityNodeInfoCleared in that class.
-    private static final int NUM_MARSHALLED_PROPERTIES = 33;
+    private static final int NUM_MARSHALLED_PROPERTIES = 34;
 
     /**
      * The number of properties that are purposely not marshalled
diff --git a/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
index 9edbf3e..1b00e09 100644
--- a/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/InputMethodInfoTest.java
@@ -26,8 +26,8 @@
 import android.content.pm.ServiceInfo;
 import android.os.Bundle;
 import android.os.Parcel;
-import android.support.test.filters.LargeTest;
 import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
 import com.android.frameworks.coretests.R;
@@ -35,7 +35,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-@LargeTest
+@SmallTest
 @RunWith(AndroidJUnit4.class)
 public class InputMethodInfoTest {
 
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
index e891fc9..8646c68 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassificationManagerTest.java
@@ -307,6 +307,24 @@
     }
 
     @Test
+    public void testDetectLanguage() {
+        if (isTextClassifierDisabled()) return;
+        String text = "This is English text";
+        TextLanguage.Request request = new TextLanguage.Request.Builder(text).build();
+        TextLanguage textLanguage = mClassifier.detectLanguage(request);
+        assertThat(textLanguage, isTextLanguage("en"));
+    }
+
+    @Test
+    public void testDetectLanguage_japanese() {
+        if (isTextClassifierDisabled()) return;
+        String text = "これは日本語のテキストです";
+        TextLanguage.Request request = new TextLanguage.Request.Builder(text).build();
+        TextLanguage textLanguage = mClassifier.detectLanguage(request);
+        assertThat(textLanguage, isTextLanguage("ja"));
+    }
+
+    @Test
     public void testSetTextClassifier() {
         TextClassifier classifier = mock(TextClassifier.class);
         mTcm.setTextClassifier(classifier);
@@ -444,4 +462,23 @@
             }
         };
     }
+
+    private static Matcher<TextLanguage> isTextLanguage(final String languageTag) {
+        return new BaseMatcher<TextLanguage>() {
+            @Override
+            public boolean matches(Object o) {
+                if (o instanceof TextLanguage) {
+                    TextLanguage result = (TextLanguage) o;
+                    return result.getLocaleHypothesisCount() > 0
+                            && languageTag.equals(result.getLocale(0).toLanguageTag());
+                }
+                return false;
+            }
+
+            @Override
+            public void describeTo(Description description) {
+                description.appendText("locale=").appendValue(languageTag);
+            }
+        };
+    }
 }
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextLanguageTest.java b/core/tests/coretests/src/android/view/textclassifier/TextLanguageTest.java
new file mode 100644
index 0000000..75ca769
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/TextLanguageTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.view.textclassifier;
+
+import static org.junit.Assert.assertEquals;
+
+import android.icu.util.ULocale;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for TextLanguage.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class TextLanguageTest {
+
+    private static final float EPSILON = 0.000001f;
+
+    @Test
+    public void testParcel() throws Exception {
+        final String bundleKey = "experiment.int";
+        final Bundle bundle = new Bundle();
+        bundle.putInt(bundleKey, 1234);
+
+        final TextLanguage reference = new TextLanguage.Builder()
+                .setId("id")
+                .setExtras(bundle)
+                .putLocale(ULocale.ENGLISH, 0.8f)
+                .putLocale(ULocale.GERMAN, 0.2f)
+                .build();
+
+        final Parcel parcel = Parcel.obtain();
+        reference.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        final TextLanguage result = TextLanguage.CREATOR.createFromParcel(parcel);
+
+        assertEquals("id", result.getId());
+        assertEquals(1234, result.getExtras().getInt(bundleKey));
+        assertEquals(2, result.getLocaleHypothesisCount());
+        assertEquals(ULocale.ENGLISH, result.getLocale(0));
+        assertEquals(0.8f, result.getConfidenceScore(ULocale.ENGLISH), EPSILON);
+        assertEquals(ULocale.GERMAN, result.getLocale(1));
+        assertEquals(0.2f, result.getConfidenceScore(ULocale.GERMAN), EPSILON);
+    }
+
+    @Test
+    public void testRequestParcel() throws Exception {
+        final String text = "This is random text";
+        final String bundleKey = "experiment.str";
+        final Bundle bundle = new Bundle();
+        bundle.putString(bundleKey, "bundle");
+
+        final TextLanguage.Request reference = new TextLanguage.Request.Builder(text)
+                .setExtras(bundle)
+                .build();
+
+        final Parcel parcel = Parcel.obtain();
+        reference.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        final TextLanguage.Request result = TextLanguage.Request.CREATOR.createFromParcel(parcel);
+
+        assertEquals(text, result.getText());
+        assertEquals("bundle", result.getExtras().getString(bundleKey));
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
index 0c8dd9d..f637b7c 100644
--- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java
@@ -77,9 +77,13 @@
 
         Message message = mHandlerFirst.obtainMessage(1000);
         message.workSourceUid = 1000;
+        message.when = looperStats.getSystemUptimeMillis();
+
+        looperStats.tickUptime(30);
         Object token = looperStats.messageDispatchStarting();
         looperStats.tickRealtime(100);
         looperStats.tickThreadTime(10);
+        looperStats.tickUptime(200);
         looperStats.messageDispatched(token, message);
 
         List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
@@ -98,6 +102,10 @@
         assertThat(entry.maxLatencyMicros).isEqualTo(100);
         assertThat(entry.cpuUsageMicros).isEqualTo(10);
         assertThat(entry.maxCpuUsageMicros).isEqualTo(10);
+        assertThat(entry.recordedDelayMessageCount).isEqualTo(1);
+        assertThat(entry.delayMillis).isEqualTo(30);
+        assertThat(entry.maxDelayMillis).isEqualTo(30);
+
     }
 
     @Test
@@ -215,6 +223,56 @@
     }
 
     @Test
+    public void testDispatchDelayIsRecorded() {
+        TestableLooperStats looperStats = new TestableLooperStats(1, 100);
+
+        // Dispatched right on time.
+        Message message1 = mHandlerFirst.obtainMessage(1000);
+        message1.when = looperStats.getSystemUptimeMillis();
+        Object token1 = looperStats.messageDispatchStarting();
+        looperStats.tickUptime(10);
+        looperStats.messageDispatched(token1, message1);
+
+        // Dispatched 100ms late.
+        Message message2 = mHandlerFirst.obtainMessage(1000);
+        message2.when = looperStats.getSystemUptimeMillis() - 100;
+        Object token2 = looperStats.messageDispatchStarting();
+        looperStats.tickUptime(10);
+        looperStats.messageDispatched(token2, message2);
+
+        // No target dispatching time.
+        Message message3 = mHandlerFirst.obtainMessage(1000);
+        message3.when = 0;
+        Object token3 = looperStats.messageDispatchStarting();
+        looperStats.tickUptime(10);
+        looperStats.messageDispatched(token3, message3);
+
+        // Dispatched too soon (should never happen).
+        Message message4 = mHandlerFirst.obtainMessage(1000);
+        message4.when = looperStats.getSystemUptimeMillis() + 200;
+        Object token4 = looperStats.messageDispatchStarting();
+        looperStats.tickUptime(10);
+        looperStats.messageDispatched(token4, message4);
+
+        // Dispatched 300ms late.
+        Message message5 = mHandlerFirst.obtainMessage(1000);
+        message5.when = looperStats.getSystemUptimeMillis() - 300;
+        Object token5 = looperStats.messageDispatchStarting();
+        looperStats.tickUptime(10);
+        looperStats.messageDispatched(token5, message5);
+
+        List<LooperStats.ExportedEntry> entries = looperStats.getEntries();
+        assertThat(entries).hasSize(1);
+
+        LooperStats.ExportedEntry entry = entries.get(0);
+        assertThat(entry.messageCount).isEqualTo(5);
+        assertThat(entry.recordedMessageCount).isEqualTo(5);
+        assertThat(entry.recordedDelayMessageCount).isEqualTo(4);
+        assertThat(entry.delayMillis).isEqualTo(400);
+        assertThat(entry.maxDelayMillis).isEqualTo(300);
+    }
+
+    @Test
     public void testDataNotCollectedBeforeDeviceStateSet() {
         TestableLooperStats looperStats = new TestableLooperStats(1, 100);
         looperStats.setDeviceState(null);
@@ -385,6 +443,7 @@
         private int mCount;
         private long mRealtimeMicros;
         private long mThreadTimeMicros;
+        private long mUptimeMillis;
         private int mSamplingInterval;
 
         TestableLooperStats(int samplingInterval, int sizeCap) {
@@ -401,6 +460,10 @@
             mThreadTimeMicros += micros;
         }
 
+        void tickUptime(long millis) {
+            mUptimeMillis += millis;
+        }
+
         @Override
         protected long getElapsedRealtimeMicro() {
             return INITIAL_MICROS + mRealtimeMicros;
@@ -412,6 +475,11 @@
         }
 
         @Override
+        protected long getSystemUptimeMillis() {
+            return INITIAL_MICROS / 1000 + mUptimeMillis;
+        }
+
+        @Override
         protected boolean shouldCollectDetailedData() {
             return mCount++ % mSamplingInterval == 0;
         }
diff --git a/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java b/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
index cac4e88..218566e 100644
--- a/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/ActionBarOverlayLayoutTest.java
@@ -27,6 +27,7 @@
 import static org.junit.Assert.assertThat;
 
 import android.content.Context;
+import android.graphics.Insets;
 import android.graphics.Rect;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
@@ -44,18 +45,20 @@
 import org.junit.runner.RunWith;
 
 import java.lang.reflect.Field;
-import java.util.Arrays;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ActionBarOverlayLayoutTest {
 
-    private static final Rect TOP_INSET_5 = new Rect(0, 5, 0, 0);
-    private static final Rect TOP_INSET_25 = new Rect(0, 25, 0, 0);
-    private static final Rect ZERO_INSET = new Rect(0, 0, 0, 0);
+    private static final Insets TOP_INSET_5 = Insets.of(0, 5, 0, 0);
+    private static final Insets TOP_INSET_25 = Insets.of(0, 25, 0, 0);
     private static final DisplayCutout CONSUMED_CUTOUT = null;
-    private static final DisplayCutout CUTOUT_5 = new DisplayCutout(TOP_INSET_5, Arrays.asList(
-            new Rect(100, 0, 200, 5)));
+    private static final DisplayCutout CUTOUT_5 = new DisplayCutout(
+            TOP_INSET_5,
+            null /* boundLeft */,
+            new Rect(100, 0, 200, 5),
+            null /* boundRight */,
+            null /* boundBottom*/);
     private static final int EXACTLY_1000 = makeMeasureSpec(1000, EXACTLY);
 
     private Context mContext;
@@ -112,7 +115,7 @@
 
         mLayout.measure(EXACTLY_1000, EXACTLY_1000);
 
-        assertThat(mContentInsetsListener.captured, is(insetsWith(ZERO_INSET, CONSUMED_CUTOUT)));
+        assertThat(mContentInsetsListener.captured, is(insetsWith(Insets.NONE, CONSUMED_CUTOUT)));
     }
 
     @Test
@@ -136,7 +139,7 @@
 
         mLayout.measure(EXACTLY_1000, EXACTLY_1000);
 
-        assertThat(mContentInsetsListener.captured, is(insetsWith(ZERO_INSET, NO_CUTOUT)));
+        assertThat(mContentInsetsListener.captured, is(insetsWith(Insets.NONE, NO_CUTOUT)));
     }
 
     @Test
@@ -160,11 +163,11 @@
 
         mLayout.measure(EXACTLY_1000, EXACTLY_1000);
 
-        assertThat(mContentInsetsListener.captured, is(insetsWith(ZERO_INSET, NO_CUTOUT)));
+        assertThat(mContentInsetsListener.captured, is(insetsWith(Insets.NONE, NO_CUTOUT)));
     }
 
-    private WindowInsets insetsWith(Rect content, DisplayCutout cutout) {
-        return new WindowInsets(content, null, null, false, false, cutout);
+    private WindowInsets insetsWith(Insets content, DisplayCutout cutout) {
+        return new WindowInsets(content.toRect(), null, null, false, false, cutout);
     }
 
     private ViewGroup createViewGroupWithId(int id) {
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk b/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
index edad4b2..97a3d00 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/Android.mk
@@ -20,4 +20,6 @@
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
index 3fae8e1..a347025 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayTwo/Android.mk
@@ -20,4 +20,6 @@
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk b/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
index c352c05..e4819e1 100644
--- a/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
+++ b/core/tests/overlaytests/device/test-apps/FrameworkOverlay/Android.mk
@@ -20,4 +20,6 @@
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := device-tests
 LOCAL_CERTIFICATE := platform
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
index ab3faf0..8656781 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
@@ -21,6 +21,8 @@
 LOCAL_SDK_VERSION := current
 LOCAL_COMPATIBILITY_SUITE := general-tests
 LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT_FLAGS := --no-resource-removal
 include $(BUILD_PACKAGE)
 
 my_package_prefix := com.android.server.om.hosttest.framework_overlay
diff --git a/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java b/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java
index 1097bc7..01382aa 100644
--- a/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java
+++ b/core/tests/packagemanagertests/src/android/content/pm/KernelPackageMappingTests.java
@@ -17,14 +17,9 @@
 package android.content.pm;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
 
 import android.content.Context;
 import android.os.FileUtils;
-import android.os.Process;
 import android.os.ServiceManager;
 import android.os.UserManager;
 import android.support.test.InstrumentationRegistry;
@@ -32,7 +27,6 @@
 import android.util.Log;
 
 import org.junit.After;
-import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -86,12 +80,23 @@
     }
 
     @Test
+    public void testSharedInstalledPrimary() throws Exception {
+        assertEquals("1001", getContent(getKernelPackageFile("shared:android.uid.phone", "appid")));
+    }
+
+    @Test
     public void testInstalledAll() throws Exception {
         assertEquals("", getContent(getKernelPackageFile("com.android.settings",
                 "excluded_userids")));
     }
 
     @Test
+    public void testSharedInstalledAll() throws Exception {
+        assertEquals("", getContent(getKernelPackageFile("shared:android.uid.phone",
+                "excluded_userids")));
+    }
+
+    @Test
     public void testNotInstalledSecondary() throws Exception {
         mSecondaryUser = getUserManager().createUser("Secondary", 0);
         assertEquals(Integer.toString(mSecondaryUser.id),
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 114c228..28e92db 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -139,12 +139,14 @@
         <permission name="android.permission.USE_RESERVED_DISK"/>
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
+        <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"/>
     </privapp-permissions>
 
     <privapp-permissions package="com.android.permissioncontroller">
         <permission name="android.permission.CLEAR_APP_CACHE"/>
         <permission name="android.permission.MANAGE_USERS"/>
         <permission name="android.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS"/>
+        <permission name="android.permission.GET_APP_OPS_STATS"/>
         <permission name="android.permission.UPDATE_APP_OPS_STATS"/>
     </privapp-permissions>
 
@@ -322,7 +324,9 @@
         <permission name="android.permission.PACKAGE_USAGE_STATS" />
         <permission name="android.permission.READ_FRAME_BUFFER"/>
         <permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.REAL_GET_TASKS"/>
+        <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
         <permission name="android.permission.REGISTER_CALL_PROVIDER"/>
         <permission name="android.permission.REGISTER_CONNECTION_MANAGER"/>
         <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index fa37bed..3db240b 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -83,7 +83,7 @@
 
     // ---------------------------------------------------------------------------
     // Drawing methods
-    // These are also implemented in DisplayListCanvas so that we can
+    // These are also implemented in RecordingCanvas so that we can
     // selectively apply on them
     // Everything below here is copy/pasted from Canvas.java
     // The JNI registration is handled by android_view_Canvas.cpp
@@ -376,6 +376,53 @@
         drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, rx, ry, paint);
     }
 
+    /**
+     * Make lint happy.
+     * See {@link Canvas#drawDoubleRoundRect(RectF, float, float, RectF, float, float, Paint)}
+     */
+    public void drawDoubleRoundRect(@NonNull RectF outer, float outerRx, float outerRy,
+            @NonNull RectF inner, float innerRx, float innerRy, @NonNull Paint paint) {
+        throwIfHasHwBitmapInSwMode(paint);
+        float outerLeft = outer.left;
+        float outerTop = outer.top;
+        float outerRight = outer.right;
+        float outerBottom = outer.bottom;
+
+        float innerLeft = inner.left;
+        float innerTop = inner.top;
+        float innerRight = inner.right;
+        float innerBottom = inner.bottom;
+        nDrawDoubleRoundRect(mNativeCanvasWrapper, outerLeft, outerTop, outerRight, outerBottom,
+                outerRx, outerRy, innerLeft, innerTop, innerRight, innerBottom, innerRx, innerRy,
+                paint.getNativeInstance());
+    }
+
+    /**
+     * Make lint happy.
+     * See {@link Canvas#drawDoubleRoundRect(RectF, float[], RectF, float[], Paint)}
+     */
+    public void drawDoubleRoundRect(@NonNull RectF outer, float[] outerRadii,
+            @NonNull RectF inner, float[] innerRadii, @NonNull Paint paint) {
+        throwIfHasHwBitmapInSwMode(paint);
+        if (innerRadii == null || outerRadii == null
+                || innerRadii.length != 8 || outerRadii.length != 8) {
+            throw new IllegalArgumentException("Both inner and outer radii arrays must contain "
+                    + "exactly 8 values");
+        }
+        float outerLeft = outer.left;
+        float outerTop = outer.top;
+        float outerRight = outer.right;
+        float outerBottom = outer.bottom;
+
+        float innerLeft = inner.left;
+        float innerTop = inner.top;
+        float innerRight = inner.right;
+        float innerBottom = inner.bottom;
+        nDrawDoubleRoundRect(mNativeCanvasWrapper, outerLeft, outerTop, outerRight,
+                outerBottom, outerRadii, innerLeft, innerTop, innerRight, innerBottom, innerRadii,
+                paint.getNativeInstance());
+    }
+
     public void drawText(@NonNull char[] text, int index, int count, float x, float y,
             @NonNull Paint paint) {
         if ((index | count | (index + count) |
@@ -502,7 +549,7 @@
                             contextStart - paraStart,
                             contextEnd - contextStart,
                             x, y, isRtl, paint.getNativeInstance(),
-                            mp.getNativeMeasuredParagraph().getNativePtr());
+                            mp.getMeasuredText().getNativePtr());
                     return;
                 }
             }
@@ -631,6 +678,16 @@
     private static native void nDrawRoundRect(long nativeCanvas, float left, float top, float right,
             float bottom, float rx, float ry, long nativePaint);
 
+    private static native void nDrawDoubleRoundRect(long nativeCanvas, float outerLeft,
+            float outerTop, float outerRight, float outerBottom, float outerRx, float outerRy,
+            float innerLeft, float innerTop, float innerRight, float innerBottom, float innerRx,
+            float innerRy, long nativePaint);
+
+    private static native void nDrawDoubleRoundRect(long nativeCanvas, float outerLeft,
+            float outerTop, float outerRight, float outerBottom, float[] outerRadii,
+            float innerLeft, float innerTop, float innerRight, float innerBottom,
+            float[] innerRadii, long nativePaint);
+
     private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint);
 
     private static native void nDrawRegion(long nativeCanvas, long nativeRegion, long nativePaint);
diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java
index 6e93691..4de7ca7 100644
--- a/graphics/java/android/graphics/BaseRecordingCanvas.java
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -377,6 +377,24 @@
     }
 
     @Override
+    public final void drawDoubleRoundRect(@NonNull RectF outer, float outerRx, float outerRy,
+            @NonNull RectF inner, float innerRx, float innerRy, @NonNull Paint paint) {
+        nDrawDoubleRoundRect(mNativeCanvasWrapper,
+                outer.left, outer.top, outer.right, outer.bottom, outerRx, outerRy,
+                inner.left, inner.top, inner.right, inner.bottom, innerRx, innerRy,
+                paint.getNativeInstance());
+    }
+
+    @Override
+    public final void drawDoubleRoundRect(@NonNull RectF outer, float[] outerRadii,
+            @NonNull RectF inner, float[] innerRadii, @NonNull Paint paint) {
+        nDrawDoubleRoundRect(mNativeCanvasWrapper,
+                outer.left, outer.top, outer.right, outer.bottom, outerRadii,
+                inner.left, inner.top, inner.right, inner.bottom, innerRadii,
+                paint.getNativeInstance());
+    }
+
+    @Override
     public final void drawText(@NonNull char[] text, int index, int count, float x, float y,
             @NonNull Paint paint) {
         if ((index | count | (index + count)
@@ -502,7 +520,7 @@
                             contextStart - paraStart,
                             contextEnd - contextStart,
                             x, y, isRtl, paint.getNativeInstance(),
-                            mp.getNativeMeasuredParagraph().getNativePtr());
+                            mp.getMeasuredText().getNativePtr());
                     return;
                 }
             }
@@ -593,6 +611,18 @@
             float bottom, float rx, float ry, long nativePaint);
 
     @FastNative
+    private static native void nDrawDoubleRoundRect(long nativeCanvas,
+            float outerLeft, float outerTop, float outerRight, float outerBottom,
+            float outerRx, float outerRy, float innerLeft, float innerTop, float innerRight,
+            float innerBottom, float innerRx, float innerRy, long nativePaint);
+
+    @FastNative
+    private static native void nDrawDoubleRoundRect(long nativeCanvas, float outerLeft,
+            float outerTop, float outerRight, float outerBottom, float[] outerRadii,
+            float innerLeft, float innerTop, float innerRight, float innerBottom,
+            float[] innerRadii, long nativePaint);
+
+    @FastNative
     private static native void nDrawPath(long nativeCanvas, long nativePath, long nativePaint);
 
     @FastNative
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 9cbbf4e..632edfa 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -24,14 +24,13 @@
 import android.annotation.UnsupportedAppUsage;
 import android.annotation.WorkerThread;
 import android.content.res.ResourcesImpl;
+import android.hardware.HardwareBuffer;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.StrictMode;
 import android.os.Trace;
 import android.util.DisplayMetrics;
 import android.util.Log;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 import android.view.ThreadedRenderer;
 
 import dalvik.annotation.optimization.CriticalNative;
@@ -724,6 +723,48 @@
     }
 
     /**
+     * Create a hardware bitmap backed by a {@link HardwareBuffer}.
+     *
+     * <p>The passed HardwareBuffer's usage flags must contain
+     * {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE}.
+     *
+     * <p>The bitmap will keep a reference to the buffer so that callers can safely close the
+     * HardwareBuffer without affecting the Bitmap. However the HardwareBuffer must not be
+     * modified while a wrapped Bitmap is accessing it. Doing so will result in undefined behavior.
+     *
+     * @param hardwareBuffer The HardwareBuffer to wrap.
+     * @param colorSpace The color space of the bitmap. Must be a {@link ColorSpace.Rgb} colorspace.
+     *                   If null, SRGB is assumed.
+     * @return A bitmap wrapping the buffer, or null if there was a problem creating the bitmap.
+     * @throws IllegalArgumentException if the HardwareBuffer has an invalid usage, or an invalid
+     *                                  colorspace is given.
+     */
+    @Nullable
+    public static Bitmap wrapHardwareBuffer(@NonNull HardwareBuffer hardwareBuffer,
+            @Nullable ColorSpace colorSpace) {
+        if ((hardwareBuffer.getUsage() & HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE) == 0) {
+            throw new IllegalArgumentException("usage flags must contain USAGE_GPU_SAMPLED_IMAGE.");
+        }
+        int format = hardwareBuffer.getFormat();
+        ColorSpace.Rgb rgb = null;
+        if (colorSpace != null) {
+            if (!(colorSpace instanceof ColorSpace.Rgb)) {
+                throw new IllegalArgumentException("colorSpace must be an RGB color space");
+            }
+            rgb = (ColorSpace.Rgb) colorSpace;
+        } else {
+            rgb = (ColorSpace.Rgb) ColorSpace.get(ColorSpace.Named.SRGB);
+        }
+        ColorSpace.Rgb.TransferParameters parameters = rgb.getTransferParameters();
+        if (parameters == null) {
+            throw new IllegalArgumentException("colorSpace must use an ICC "
+                    + "parametric transfer function");
+        }
+        ColorSpace.Rgb d50 = (ColorSpace.Rgb) ColorSpace.adapt(rgb, ColorSpace.ILLUMINANT_D50);
+        return nativeWrapHardwareBufferBitmap(hardwareBuffer, d50.getTransform(), parameters);
+    }
+
+    /**
      * Creates a new bitmap, scaled from an existing bitmap, when possible. If the
      * specified width and height are the same as the current width and height of
      * the source bitmap, the source bitmap is returned and no new bitmap is
@@ -1253,8 +1294,8 @@
             final RenderNode node = RenderNode.create("BitmapTemporary", null);
             node.setLeftTopRightBottom(0, 0, width, height);
             node.setClipToBounds(false);
-            node.setAllowForceDark(false);
-            final DisplayListCanvas canvas = node.start(width, height);
+            node.setForceDarkAllowed(false);
+            final RecordingCanvas canvas = node.start(width, height);
             if (source.getWidth() != width || source.getHeight() != height) {
                 canvas.scale(width / (float) source.getWidth(),
                         height / (float) source.getHeight());
@@ -2118,6 +2159,9 @@
     private static native int nativeGetAllocationByteCount(long nativeBitmap);
     private static native Bitmap nativeCopyPreserveInternalConfig(long nativeBitmap);
     private static native Bitmap nativeCreateHardwareBitmap(GraphicBuffer buffer);
+    private static native Bitmap nativeWrapHardwareBufferBitmap(HardwareBuffer buffer,
+                                                              @Size(9) float[] xyzD50,
+                                                              ColorSpace.Rgb.TransferParameters p);
     private static native GraphicBuffer nativeCreateGraphicBufferHandle(long nativeBitmap);
     private static native boolean nativeGetColorSpace(long nativePtr, float[] xyz, float[] params);
     private static native boolean nativeIsSRGB(long nativePtr);
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 36c1c21..e35a3be 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1877,6 +1877,51 @@
     }
 
     /**
+     * Draws a double rounded rectangle using the specified paint. The resultant round rect
+     * will be filled in the area defined between the outer and inner rectangular bounds if
+     * the {@link Paint} configured with {@link Paint.Style#FILL}.
+     * Otherwise if {@link Paint.Style#STROKE} is used, then 2 rounded rect strokes will
+     * be drawn at the outer and inner rounded rectangles
+     *
+     * @param outer The outer rectangular bounds of the roundRect to be drawn
+     * @param outerRx The x-radius of the oval used to round the corners on the outer rectangle
+     * @param outerRy The y-radius of the oval used to round the corners on the outer rectangle
+     * @param inner The inner rectangular bounds of the roundRect to be drawn
+     * @param innerRx The x-radius of the oval used to round the corners on the inner rectangle
+     * @param innerRy The y-radius of the oval used to round the corners on the outer rectangle
+     * @param paint The paint used to draw the double roundRect
+     */
+    @Override
+    public void drawDoubleRoundRect(@NonNull RectF outer, float outerRx, float outerRy,
+            @NonNull RectF inner, float innerRx, float innerRy, @NonNull Paint paint) {
+        super.drawDoubleRoundRect(outer, outerRx, outerRy, inner, innerRx, innerRy, paint);
+    }
+
+    /**
+     * Draws a double rounded rectangle using the specified paint. The resultant round rect
+     * will be filled in the area defined between the outer and inner rectangular bounds if
+     * the {@link Paint} configured with {@link Paint.Style#FILL}.
+     * Otherwise if {@link Paint.Style#STROKE} is used, then 2 rounded rect strokes will
+     * be drawn at the outer and inner rounded rectangles
+     *
+     * @param outer The outer rectangular bounds of the roundRect to be drawn
+     * @param outerRadii Array of 8 float representing the x, y corner radii for top left,
+     *                   top right, bottom right, bottom left corners respectively on the outer
+     *                   rounded rectangle
+     *
+     * @param inner The inner rectangular bounds of the roundRect to be drawn
+     * @param innerRadii Array of 8 float representing the x, y corner radii for top left,
+     *                   top right, bottom right, bottom left corners respectively on the
+     *                   outer rounded rectangle
+     * @param paint The paint used to draw the double roundRect
+     */
+    @Override
+    public void drawDoubleRoundRect(@NonNull RectF outer, float[] outerRadii,
+            @NonNull RectF inner, float[] innerRadii, @NonNull Paint paint) {
+        super.drawDoubleRoundRect(outer, outerRadii, inner, innerRadii, paint);
+    }
+
+    /**
      * Draw the text, with origin at (x,y), using the specified paint. The origin is interpreted
      * based on the Align setting in the paint.
      *
diff --git a/graphics/java/android/graphics/ColorSpace.java b/graphics/java/android/graphics/ColorSpace.java
index 8414d6a..2e1d81a 100644
--- a/graphics/java/android/graphics/ColorSpace.java
+++ b/graphics/java/android/graphics/ColorSpace.java
@@ -472,8 +472,8 @@
          *     <tr>
          *         <td>Electro-optical transfer function (EOTF)</td>
          *         <td colspan="4">\(\begin{equation}
-         *             C_{linear} = \begin{cases}\frac{C_{DisplayP3}}{12.92} & C_{sRGB} \lt 0.039 \\\
-         *             \left( \frac{C_{DisplayP3} + 0.055}{1.055} \right) ^{2.4} & C_{sRGB} \ge 0.039 \end{cases}
+         *             C_{linear} = \begin{cases}\frac{C_{DisplayP3}}{12.92} & C_{sRGB} \lt 0.04045 \\\
+         *             \left( \frac{C_{DisplayP3} + 0.055}{1.055} \right) ^{2.4} & C_{sRGB} \ge 0.04045 \end{cases}
          *             \end{equation}\)
          *         </td>
          *     </tr>
@@ -1484,7 +1484,7 @@
                 "Display P3",
                 new float[] { 0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f },
                 ILLUMINANT_D65,
-                new Rgb.TransferParameters(1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.039, 2.4),
+                new Rgb.TransferParameters(1 / 1.055, 0.055 / 1.055, 1 / 12.92, 0.04045, 2.4),
                 Named.DISPLAY_P3.ordinal()
         );
         sNamedColorSpaces[Named.NTSC_1953.ordinal()] = new ColorSpace.Rgb(
@@ -2525,9 +2525,7 @@
                     gamma == 1.0 ? DoubleUnaryOperator.identity() :
                             x -> Math.pow(x < 0.0 ? 0.0 : x, gamma),
                     min, max, id);
-            mTransferParameters = gamma == 1.0 ?
-                    new TransferParameters(0.0, 0.0, 1.0, 1.0 + Math.ulp(1.0f), gamma) :
-                    new TransferParameters(1.0, 0.0, 0.0, 0.0, gamma);
+            mTransferParameters = new TransferParameters(1.0, 0.0, 0.0, 0.0, gamma);
         }
 
         /**
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 6ce66bd..009e042 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -59,6 +59,7 @@
 import java.io.InputStream;
 import java.lang.annotation.Retention;
 import java.nio.ByteBuffer;
+import java.util.concurrent.Callable;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -283,26 +284,7 @@
 
                 return createFromStream(is, true, this);
             }
-
-            final FileDescriptor fd = assetFd.getFileDescriptor();
-            final long offset = assetFd.getStartOffset();
-
-            ImageDecoder decoder = null;
-            try {
-                try {
-                    Os.lseek(fd, offset, SEEK_SET);
-                    decoder = nCreate(fd, this);
-                } catch (ErrnoException e) {
-                    decoder = createFromStream(new FileInputStream(fd), true, this);
-                }
-            } finally {
-                if (decoder == null) {
-                    IoUtils.closeQuietly(assetFd);
-                } else {
-                    decoder.mAssetFd = assetFd;
-                }
-            }
-            return decoder;
+            return createFromAssetFileDescriptor(assetFd, this);
         }
     }
 
@@ -354,6 +336,30 @@
         return decoder;
     }
 
+    @NonNull
+    private static ImageDecoder createFromAssetFileDescriptor(@NonNull AssetFileDescriptor assetFd,
+            Source source) throws IOException {
+        final FileDescriptor fd = assetFd.getFileDescriptor();
+        final long offset = assetFd.getStartOffset();
+
+        ImageDecoder decoder = null;
+        try {
+            try {
+                Os.lseek(fd, offset, SEEK_SET);
+                decoder = nCreate(fd, source);
+            } catch (ErrnoException e) {
+                decoder = createFromStream(new FileInputStream(fd), true, source);
+            }
+        } finally {
+            if (decoder == null) {
+                IoUtils.closeQuietly(assetFd);
+            } else {
+                decoder.mAssetFd = assetFd;
+            }
+        }
+        return decoder;
+    }
+
     /**
      * For backwards compatibility, this does *not* close the InputStream.
      *
@@ -528,6 +534,29 @@
         }
     }
 
+    private static class CallableSource extends Source {
+        CallableSource(@NonNull Callable<AssetFileDescriptor> callable) {
+            mCallable = callable;
+        }
+
+        private final Callable<AssetFileDescriptor> mCallable;
+
+        @Override
+        public ImageDecoder createImageDecoder() throws IOException {
+            AssetFileDescriptor assetFd = null;
+            try {
+                assetFd = mCallable.call();
+            } catch (Exception e) {
+                if (e instanceof IOException) {
+                    throw (IOException) e;
+                } else {
+                    throw new IOException(e);
+                }
+            }
+            return createFromAssetFileDescriptor(assetFd, this);
+        }
+    }
+
     /**
      *  Information about an encoded image.
      */
@@ -971,6 +1000,27 @@
     }
 
     /**
+     * Create a new {@link Source Source} from a {@link Callable} that returns a
+     * new {@link AssetFileDescriptor} for each request. This provides control
+     * over how the {@link AssetFileDescriptor} is created, such as passing
+     * options into {@link ContentResolver#openTypedAssetFileDescriptor}, or
+     * enabling use of a {@link android.os.CancellationSignal}.
+     * <p>
+     * It's important for the given {@link Callable} to return a new, unique
+     * {@link AssetFileDescriptor} for each invocation, to support reuse of the
+     * returned {@link Source Source}.
+     *
+     * @return a new Source object, which can be passed to
+     *         {@link #decodeDrawable decodeDrawable} or {@link #decodeBitmap
+     *         decodeBitmap}.
+     */
+    @AnyThread
+    @NonNull
+    public static Source createSource(@NonNull Callable<AssetFileDescriptor> callable) {
+        return new CallableSource(callable);
+    }
+
+    /**
      *  Return the width and height of a given sample size.
      *
      *  <p>This takes an input that functions like
diff --git a/graphics/java/android/graphics/Insets.java b/graphics/java/android/graphics/Insets.java
index c3449dd..de110c8 100644
--- a/graphics/java/android/graphics/Insets.java
+++ b/graphics/java/android/graphics/Insets.java
@@ -73,6 +73,15 @@
     }
 
     /**
+     * Returns a Rect intance with the appropriate values.
+     *
+     * @hide
+     */
+    public @NonNull Rect toRect() {
+        return new Rect(left, top, right, bottom);
+    }
+
+    /**
      * Two Insets instances are equal iff they belong to the same class and their fields are
      * pairwise equal.
      *
diff --git a/graphics/java/android/graphics/Picture.java b/graphics/java/android/graphics/Picture.java
index f7acb11..f6d801b 100644
--- a/graphics/java/android/graphics/Picture.java
+++ b/graphics/java/android/graphics/Picture.java
@@ -17,6 +17,7 @@
 package android.graphics;
 
 import android.annotation.UnsupportedAppUsage;
+
 import java.io.InputStream;
 import java.io.OutputStream;
 
@@ -216,7 +217,7 @@
         public PictureCanvas(Picture pict, long nativeCanvas) {
             super(nativeCanvas);
             mPicture = pict;
-            // Disable bitmap density scaling. This matches DisplayListCanvas.
+            // Disable bitmap density scaling. This matches RecordingCanvas.
             mDensity = 0;
         }
 
diff --git a/graphics/java/android/graphics/Point.java b/graphics/java/android/graphics/Point.java
index f291e27..ea93501 100644
--- a/graphics/java/android/graphics/Point.java
+++ b/graphics/java/android/graphics/Point.java
@@ -19,6 +19,7 @@
 import android.annotation.NonNull;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.Size;
 import android.util.proto.ProtoOutputStream;
 
 import java.io.PrintWriter;
@@ -168,4 +169,14 @@
         x = in.readInt();
         y = in.readInt();
     }
+
+    /** {@hide} */
+    public static @NonNull Point convert(@NonNull Size size) {
+        return new Point(size.getWidth(), size.getHeight());
+    }
+
+    /** {@hide} */
+    public static @NonNull Size convert(@NonNull Point point) {
+        return new Size(point.x, point.y);
+    }
 }
diff --git a/core/java/android/view/DisplayListCanvas.java b/graphics/java/android/graphics/RecordingCanvas.java
similarity index 86%
rename from core/java/android/view/DisplayListCanvas.java
rename to graphics/java/android/graphics/RecordingCanvas.java
index 667fab5..7af006b 100644
--- a/core/java/android/view/DisplayListCanvas.java
+++ b/graphics/java/android/graphics/RecordingCanvas.java
@@ -14,47 +14,47 @@
  * limitations under the License.
  */
 
-package android.view;
+package android.graphics;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
-import android.graphics.BaseRecordingCanvas;
-import android.graphics.Bitmap;
-import android.graphics.CanvasProperty;
-import android.graphics.Paint;
 import android.util.Pools.SynchronizedPool;
+import android.view.TextureLayer;
 
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 
 /**
  * A Canvas implementation that records view system drawing operations for deferred rendering.
- * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
+ * This is intended for use with RenderNode. This class keeps a list of all the Paint and
  * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
- * the DisplayList is still holding a native reference to the memory.
+ * the RecordingCanvas is still holding a native reference to the memory.
  *
  * @hide
  */
-public final class DisplayListCanvas extends BaseRecordingCanvas {
+public final class RecordingCanvas extends BaseRecordingCanvas {
     // The recording canvas pool should be large enough to handle a deeply nested
     // view hierarchy because display lists are generated recursively.
     private static final int POOL_LIMIT = 25;
 
     public static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
 
-    private static final SynchronizedPool<DisplayListCanvas> sPool =
+    private static final SynchronizedPool<RecordingCanvas> sPool =
             new SynchronizedPool<>(POOL_LIMIT);
 
-    RenderNode mNode;
+    /**
+     * TODO: Temporarily exposed for RenderNodeAnimator(Set)
+     * @hide */
+    public RenderNode mNode;
     private int mWidth;
     private int mHeight;
 
-    static DisplayListCanvas obtain(@NonNull RenderNode node, int width, int height) {
+    static RecordingCanvas obtain(@NonNull RenderNode node, int width, int height) {
         if (node == null) throw new IllegalArgumentException("node cannot be null");
-        DisplayListCanvas canvas = sPool.acquire();
+        RecordingCanvas canvas = sPool.acquire();
         if (canvas == null) {
-            canvas = new DisplayListCanvas(node, width, height);
+            canvas = new RecordingCanvas(node, width, height);
         } else {
             nResetDisplayListCanvas(canvas.mNativeCanvasWrapper, node.mNativeRenderNode,
                     width, height);
@@ -83,7 +83,7 @@
     // Constructors
     ///////////////////////////////////////////////////////////////////////////
 
-    private DisplayListCanvas(@NonNull RenderNode node, int width, int height) {
+    private RecordingCanvas(@NonNull RenderNode node, int width, int height) {
         super(nCreateDisplayListCanvas(node.mNativeRenderNode, width, height));
         mDensity = 0; // disable bitmap density scaling
     }
@@ -95,7 +95,7 @@
 
     @Override
     public void setDensity(int density) {
-        // drop silently, since DisplayListCanvas doesn't perform density scaling
+        // drop silently, since RecordingCanvas doesn't perform density scaling
     }
 
     @Override
@@ -156,6 +156,8 @@
      * functionality used by webview for calling into their renderer from our display lists.
      *
      * @param drawGLFunction A native function pointer
+     *
+     * @hide
      */
     @UnsupportedAppUsage
     public void callDrawGLFunction2(long drawGLFunction) {
@@ -166,13 +168,15 @@
      * Records the functor specified with the drawGLFunction function pointer. This is
      * functionality used by webview for calling into their renderer from our display lists.
      *
-     * @param drawGLFunction A native function pointer
+     * @param drawGLFunctor A native function pointer
      * @param releasedCallback Called when the display list is destroyed, and thus
      * the functor is no longer referenced by this canvas's display list.
      *
      * NOTE: The callback does *not* necessarily mean that there are no longer
      * any references to the functor, just that the reference from this specific
      * canvas's display list has been released.
+     *
+     * @hide
      */
     @UnsupportedAppUsage
     public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
@@ -201,8 +205,9 @@
      * Draws the specified layer onto this canvas.
      *
      * @param layer The layer to composite on this canvas
+     * @hide
      */
-    void drawTextureLayer(TextureLayer layer) {
+    public void drawTextureLayer(TextureLayer layer) {
         nDrawTextureLayer(mNativeCanvasWrapper, layer.getLayerHandle());
     }
 
@@ -210,6 +215,16 @@
     // Drawing
     ///////////////////////////////////////////////////////////////////////////
 
+    /**
+     * Draws a circle
+     *
+     * @param cx
+     * @param cy
+     * @param radius
+     * @param paint
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
     public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
             CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
@@ -217,6 +232,19 @@
                 radius.getNativeContainer(), paint.getNativeContainer());
     }
 
+    /**
+     * Draws a round rect
+     *
+     * @param left
+     * @param top
+     * @param right
+     * @param bottom
+     * @param rx
+     * @param ry
+     * @param paint
+     *
+     * @hide
+     */
     public void drawRoundRect(CanvasProperty<Float> left, CanvasProperty<Float> top,
             CanvasProperty<Float> right, CanvasProperty<Float> bottom, CanvasProperty<Float> rx,
             CanvasProperty<Float> ry, CanvasProperty<Paint> paint) {
diff --git a/core/java/android/view/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
similarity index 92%
rename from core/java/android/view/RenderNode.java
rename to graphics/java/android/graphics/RenderNode.java
index 8ae9127..b61488c 100644
--- a/core/java/android/view/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -14,16 +14,15 @@
  * limitations under the License.
  */
 
-package android.view;
+package android.graphics;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
-import android.graphics.Matrix;
-import android.graphics.Outline;
-import android.graphics.Paint;
-import android.graphics.Rect;
+import android.view.NativeVectorDrawableAnimator;
+import android.view.RenderNodeAnimator;
+import android.view.View;
 
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
@@ -36,7 +35,7 @@
 /**
  * <p>A display list records a series of graphics related operations and can replay
  * them later. Display lists are usually built by recording operations on a
- * {@link DisplayListCanvas}. Replaying the operations from a display list avoids
+ * {@link RecordingCanvas}. Replaying the operations from a display list avoids
  * executing application code on every frame, and is thus much more efficient.</p>
  *
  * <p>Display lists are used internally for all views by default, and are not
@@ -53,7 +52,7 @@
  * affected paragraph needs to be recorded again.</p>
  *
  * <h3>Hardware acceleration</h3>
- * <p>Display lists can only be replayed using a {@link DisplayListCanvas}. They are not
+ * <p>Display lists can only be replayed using a {@link RecordingCanvas}. They are not
  * supported in software. Always make sure that the {@link android.graphics.Canvas}
  * you are using to render a display list is hardware accelerated using
  * {@link android.graphics.Canvas#isHardwareAccelerated()}.</p>
@@ -63,7 +62,7 @@
  *     ThreadedRenderer renderer = myView.getThreadedRenderer();
  *     if (renderer != null) {
  *         DisplayList displayList = renderer.createDisplayList();
- *         DisplayListCanvas canvas = displayList.start(width, height);
+ *         RecordingCanvas canvas = displayList.start(width, height);
  *         try {
  *             // Draw onto the canvas
  *             // For instance: canvas.drawBitmap(...);
@@ -77,7 +76,7 @@
  * <pre class="prettyprint">
  *     protected void onDraw(Canvas canvas) {
  *         if (canvas.isHardwareAccelerated()) {
- *             DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
+ *             RecordingCanvas displayListCanvas = (RecordingCanvas) canvas;
  *             displayListCanvas.drawDisplayList(mDisplayList);
  *         }
  *     }
@@ -102,7 +101,7 @@
  * <pre class="prettyprint">
  *     private void createDisplayList() {
  *         mDisplayList = DisplayList.create("MyDisplayList");
- *         DisplayListCanvas canvas = mDisplayList.start(width, height);
+ *         RecordingCanvas canvas = mDisplayList.start(width, height);
  *         try {
  *             for (Bitmap b : mBitmaps) {
  *                 canvas.drawBitmap(b, 0.0f, 0.0f, null);
@@ -115,7 +114,7 @@
  *
  *     protected void onDraw(Canvas canvas) {
  *         if (canvas.isHardwareAccelerated()) {
- *             DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
+ *             RecordingCanvas displayListCanvas = (RecordingCanvas) canvas;
  *             displayListCanvas.drawDisplayList(mDisplayList);
  *         }
  *     }
@@ -143,10 +142,10 @@
                 RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
     }
 
-    /** Not for general use; use only if you are ThreadedRenderer or DisplayListCanvas.
+    /** Not for general use; use only if you are ThreadedRenderer or RecordingCanvas.
      * @hide
      */
-    final long mNativeRenderNode;
+    public final long mNativeRenderNode;
     private final AnimationHost mAnimationHost;
 
     private RenderNode(String name, AnimationHost animationHost) {
@@ -195,7 +194,7 @@
      *
      * @hide
      */
-    interface PositionUpdateListener {
+    public interface PositionUpdateListener {
 
         /**
          * Called by native by a Rendering Worker thread to update window position
@@ -228,7 +227,7 @@
      * stored in this display list.
      *
      * Calling this method will mark the render node invalid until
-     * {@link #end(DisplayListCanvas)} is called.
+     * {@link #end(RecordingCanvas)} is called.
      * Only valid render nodes can be replayed.
      *
      * @param width The width of the recording viewport
@@ -236,19 +235,19 @@
      *
      * @return A canvas to record drawing operations.
      *
-     * @see #end(DisplayListCanvas)
+     * @see #end(RecordingCanvas)
      * @see #isValid()
      */
     @UnsupportedAppUsage
-    public DisplayListCanvas start(int width, int height) {
-        return DisplayListCanvas.obtain(this, width, height);
+    public RecordingCanvas start(int width, int height) {
+        return RecordingCanvas.obtain(this, width, height);
     }
 
     /**
      * Same as {@link #start(int, int)} but with the RenderNode's width & height
      */
-    public DisplayListCanvas start() {
-        return DisplayListCanvas.obtain(this,
+    public RecordingCanvas start() {
+        return RecordingCanvas.obtain(this,
                 nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
     }
 
@@ -261,7 +260,7 @@
      * @see #isValid()
      */
     @UnsupportedAppUsage
-    public void end(DisplayListCanvas canvas) {
+    public void end(RecordingCanvas canvas) {
         long displayList = canvas.finishRecording();
         nSetDisplayList(mNativeRenderNode, displayList);
         canvas.recycle();
@@ -292,14 +291,32 @@
     // Matrix manipulation
     ///////////////////////////////////////////////////////////////////////////
 
+    /**
+     * Whether or not the RenderNode has an identity transform. This is a faster
+     * way to do the otherwise equivalent {@link #getMatrix(Matrix)} {@link Matrix#isIdentity()}
+     * as it doesn't require copying the Matrix first, thus minimizing overhead.
+     *
+     * @return true if the RenderNode has an identity transform, false otherwise
+     */
     public boolean hasIdentityMatrix() {
         return nHasIdentityMatrix(mNativeRenderNode);
     }
 
+    /**
+     * Gets the current transform matrix
+     *
+     * @param outMatrix The matrix to store the transform of the RenderNode
+     */
     public void getMatrix(@NonNull Matrix outMatrix) {
         nGetTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
     }
 
+    /**
+     * Gets the current transform inverted. This is a faster way to do the otherwise
+     * equivalent {@link #getMatrix(Matrix)} followed by {@link Matrix#invert(Matrix)}
+     *
+     * @param outMatrix The matrix to store the inverse transform of the RenderNode
+     */
     public void getInverseMatrix(@NonNull Matrix outMatrix) {
         nGetInverseTransformMatrix(mNativeRenderNode, outMatrix.native_instance);
     }
@@ -308,14 +325,25 @@
     // RenderProperty Setters
     ///////////////////////////////////////////////////////////////////////////
 
+    /**
+     * TODO
+     */
     public boolean setLayerType(int layerType) {
         return nSetLayerType(mNativeRenderNode, layerType);
     }
 
+    /**
+     * TODO
+     */
     public boolean setLayerPaint(@Nullable Paint paint) {
         return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
     }
 
+    /**
+     * Sets the clip bounds of the RenderNode.
+     * @param rect the bounds to clip to. If null, the clip bounds are reset
+     * @return True if the clip bounds changed, false otherwise
+     */
     public boolean setClipBounds(@Nullable Rect rect) {
         if (rect == null) {
             return nSetClipBoundsEmpty(mNativeRenderNode);
@@ -371,8 +399,10 @@
             case Outline.MODE_EMPTY:
                 return nSetOutlineEmpty(mNativeRenderNode);
             case Outline.MODE_ROUND_RECT:
-                return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top,
-                        outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha);
+                return nSetOutlineRoundRect(mNativeRenderNode,
+                        outline.mRect.left, outline.mRect.top,
+                        outline.mRect.right, outline.mRect.bottom,
+                        outline.mRadius, outline.mAlpha);
             case Outline.MODE_CONVEX_PATH:
                 return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath,
                         outline.mAlpha);
@@ -381,6 +411,9 @@
         throw new IllegalArgumentException("Unrecognized outline?");
     }
 
+    /**
+     * @return True if this RenderNode has a shadow, false otherwise
+     */
     public boolean hasShadow() {
         return nHasShadow(mNativeRenderNode);
     }
@@ -414,6 +447,11 @@
         return nSetClipToOutline(mNativeRenderNode, clipToOutline);
     }
 
+    /**
+     * See {@link #setClipToOutline(boolean)}
+     *
+     * @return True if this RenderNode clips to its outline, false otherwise
+     */
     public boolean getClipToOutline() {
         return nGetClipToOutline(mNativeRenderNode);
     }
@@ -518,10 +556,21 @@
         return nHasOverlappingRendering(mNativeRenderNode);
     }
 
+    /**
+     * Sets the base elevation of this RenderNode in pixels
+     *
+     * @param lift the elevation in pixels
+     * @return true if the elevation changed, false if it was the same
+     */
     public boolean setElevation(float lift) {
         return nSetElevation(mNativeRenderNode, lift);
     }
 
+    /**
+     * See {@link #setElevation(float)}
+     *
+     * @return The RenderNode's current elevation
+     */
     public float getElevation() {
         return nGetElevation(mNativeRenderNode);
     }
@@ -882,16 +931,16 @@
      * @param allow Whether or not to allow force dark.
      * @return true If the value has changed, false otherwise.
      */
-    public boolean setAllowForceDark(boolean allow) {
+    public boolean setForceDarkAllowed(boolean allow) {
         return nSetAllowForceDark(mNativeRenderNode, allow);
     }
 
     /**
-     * See {@link #setAllowForceDark(boolean)}
+     * See {@link #setForceDarkAllowed(boolean)}
      *
      * @return true if force dark is allowed (default), false if it is disabled
      */
-    public boolean getAllowForceDark() {
+    public boolean isForceDarkAllowed() {
         return nGetAllowForceDark(mNativeRenderNode);
     }
 
@@ -906,9 +955,12 @@
      * bit of a kludge.
      *
      * @hide */
-    interface AnimationHost {
+    public interface AnimationHost {
+        /** checkstyle */
         void registerAnimatingRenderNode(RenderNode animator);
+        /** checkstyle */
         void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator);
+        /** checkstyle */
         boolean isAttached();
     }
 
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 7ad207f..ba47300 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -27,6 +27,7 @@
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
 import android.content.res.AssetManager;
+import android.graphics.fonts.FontStyle;
 import android.graphics.fonts.FontVariationAxis;
 import android.graphics.fonts.SystemFonts;
 import android.net.Uri;
@@ -148,7 +149,7 @@
     @UnsupportedAppUsage
     private @Style int mStyle = 0;
 
-    private @IntRange(from = 0, to = android.graphics.fonts.Font.FONT_WEIGHT_MAX) int mWeight = 0;
+    private @IntRange(from = 0, to = FontStyle.FONT_WEIGHT_MAX) int mWeight = 0;
 
     // Value for weight and italic. Indicates the value is resolved by font metadata.
     // Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index 6c1372f..789e38c 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -39,7 +39,9 @@
 import android.graphics.Outline;
 import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.RenderNode;
 import android.os.Build;
 import android.util.ArrayMap;
 import android.util.AttributeSet;
@@ -50,9 +52,7 @@
 import android.util.Property;
 import android.util.TimeUtils;
 import android.view.Choreographer;
-import android.view.DisplayListCanvas;
 import android.view.NativeVectorDrawableAnimator;
-import android.view.RenderNode;
 import android.view.RenderNodeAnimatorSetHelper;
 import android.view.View;
 
@@ -1542,11 +1542,11 @@
         }
 
         /**
-         * Holds a weak reference to the target that was last seen (through the DisplayListCanvas
+         * Holds a weak reference to the target that was last seen (through the RecordingCanvas
          * in the last draw call), so that when animator set needs to start, we can add the animator
          * to the last seen RenderNode target and start right away.
          */
-        protected void recordLastSeenTarget(DisplayListCanvas canvas) {
+        protected void recordLastSeenTarget(RecordingCanvas canvas) {
             final RenderNode node = RenderNodeAnimatorSetHelper.getTarget(canvas);
             mLastSeenTarget = new WeakReference<RenderNode>(node);
             // Add the animator to the list of animators on every draw
@@ -1742,7 +1742,7 @@
         @Override
         public void onDraw(Canvas canvas) {
             if (canvas.isHardwareAccelerated()) {
-                recordLastSeenTarget((DisplayListCanvas) canvas);
+                recordLastSeenTarget((RecordingCanvas) canvas);
             }
         }
 
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 7efe522..f41cc7e 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -21,7 +21,6 @@
 import android.annotation.IdRes;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -570,7 +569,7 @@
      * Version of createWithResource that takes Resources. Do not use.
      * @hide
      */
-    @SystemApi
+    @UnsupportedAppUsage
     public static Icon createWithResource(Resources res, @DrawableRes int resId) {
         if (res == null) {
             throw new IllegalArgumentException("Resource must not be null.");
diff --git a/graphics/java/android/graphics/drawable/RippleComponent.java b/graphics/java/android/graphics/drawable/RippleComponent.java
index 626bcee..c1f8798 100644
--- a/graphics/java/android/graphics/drawable/RippleComponent.java
+++ b/graphics/java/android/graphics/drawable/RippleComponent.java
@@ -16,15 +16,8 @@
 
 package android.graphics.drawable;
 
-import android.animation.Animator;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.graphics.Rect;
 import android.util.DisplayMetrics;
-import android.view.DisplayListCanvas;
-import android.view.RenderNodeAnimator;
-
-import java.util.ArrayList;
 
 /**
  * Abstract class that handles size & positioning common to the ripple & focus states.
diff --git a/graphics/java/android/graphics/drawable/RippleForeground.java b/graphics/java/android/graphics/drawable/RippleForeground.java
index a8dc34a..cce9ba3 100644
--- a/graphics/java/android/graphics/drawable/RippleForeground.java
+++ b/graphics/java/android/graphics/drawable/RippleForeground.java
@@ -23,10 +23,10 @@
 import android.graphics.Canvas;
 import android.graphics.CanvasProperty;
 import android.graphics.Paint;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.util.FloatProperty;
 import android.util.MathUtils;
-import android.view.DisplayListCanvas;
 import android.view.RenderNodeAnimator;
 import android.view.animation.AnimationUtils;
 import android.view.animation.LinearInterpolator;
@@ -132,7 +132,7 @@
         }
     }
 
-    private void startPending(DisplayListCanvas c) {
+    private void startPending(RecordingCanvas c) {
         if (!mPendingHwAnimators.isEmpty()) {
             for (int i = 0; i < mPendingHwAnimators.size(); i++) {
                 RenderNodeAnimator animator = mPendingHwAnimators.get(i);
@@ -164,7 +164,7 @@
         }
     }
 
-    private void drawHardware(DisplayListCanvas c, Paint p) {
+    private void drawHardware(RecordingCanvas c, Paint p) {
         startPending(c);
         pruneHwFinished();
         if (mPropPaint != null) {
@@ -332,11 +332,11 @@
      * @param p the paint used to draw the ripple
      */
     public void draw(Canvas c, Paint p) {
-        final boolean hasDisplayListCanvas = !mForceSoftware && c instanceof DisplayListCanvas;
+        final boolean hasDisplayListCanvas = !mForceSoftware && c instanceof RecordingCanvas;
 
         pruneSwFinished();
         if (hasDisplayListCanvas) {
-            final DisplayListCanvas hw = (DisplayListCanvas) c;
+            final RecordingCanvas hw = (RecordingCanvas) c;
             drawHardware(hw, p);
         } else {
             drawSoftware(c, p);
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index bd1ac25..f426b2d 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -51,61 +51,6 @@
     private static final int STYLE_NORMAL = 0;
 
     /**
-     * A minimum weight value for the font
-     */
-    public static final int FONT_WEIGHT_MIN = 1;
-
-    /**
-     * A font weight value for the thin weight
-     */
-    public static final int FONT_WEIGHT_THIN = 100;
-
-    /**
-     * A font weight value for the extra-light weight
-     */
-    public static final int FONT_WEIGHT_EXTRA_LIGHT = 200;
-
-    /**
-     * A font weight value for the light weight
-     */
-    public static final int FONT_WEIGHT_LIGHT = 300;
-
-    /**
-     * A font weight value for the normal weight
-     */
-    public static final int FONT_WEIGHT_NORMAL = 400;
-
-    /**
-     * A font weight value for the medium weight
-     */
-    public static final int FONT_WEIGHT_MEDIUM = 500;
-
-    /**
-     * A font weight value for the semi-bold weight
-     */
-    public static final int FONT_WEIGHT_SEMI_BOLD = 600;
-
-    /**
-     * A font weight value for the bold weight.
-     */
-    public static final int FONT_WEIGHT_BOLD = 700;
-
-    /**
-     * A font weight value for the extra-bold weight
-     */
-    public static final int FONT_WEIGHT_EXTRA_BOLD = 800;
-
-    /**
-     * A font weight value for the black weight
-     */
-    public static final int FONT_WEIGHT_BLACK = 900;
-
-    /**
-     * A maximum weight value for the font
-     */
-    public static final int FONT_WEIGHT_MAX = 1000;
-
-    /**
      * A builder class for creating new Font.
      */
     public static class Builder {
@@ -275,66 +220,68 @@
          *  <tr>
          *  <td align="center">100</td>
          *  <td align="center">Thin</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_THIN}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_THIN}</td>
          *  </tr>
          *  <tr>
          *  <td align="center">200</td>
          *  <td align="center">Extra Light (Ultra Light)</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_EXTRA_LIGHT}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_LIGHT}</td>
          *  </tr>
          *  <tr>
          *  <td align="center">300</td>
          *  <td align="center">Light</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_LIGHT}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_LIGHT}</td>
          *  </tr>
          *  <tr>
          *  <td align="center">400</td>
          *  <td align="center">Normal (Regular)</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_NORMAL}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_NORMAL}</td>
          *  </tr>
          *  <tr>
          *  <td align="center">500</td>
          *  <td align="center">Medium</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_MEDIUM}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_MEDIUM}</td>
          *  </tr>
          *  <tr>
          *  <td align="center">600</td>
          *  <td align="center">Semi Bold (Demi Bold)</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_SEMI_BOLD}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_SEMI_BOLD}</td>
          *  </tr>
          *  <tr>
          *  <td align="center">700</td>
          *  <td align="center">Bold</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_BOLD}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_BOLD}</td>
          *  </tr>
          *  <tr>
          *  <td align="center">800</td>
          *  <td align="center">Extra Bold (Ultra Bold)</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_EXTRA_BOLD}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_BOLD}</td>
          *  </tr>
          *  <tr>
          *  <td align="center">900</td>
          *  <td align="center">Black (Heavy)</td>
-         *  <td align="center">{@link Font#FONT_WEIGHT_BLACK}</td>
+         *  <td align="center">{@link FontStyle#FONT_WEIGHT_BLACK}</td>
          *  </tr>
          *  </tbody>
          * </p>
          *
-         * @see Font#FONT_WEIGHT_THIN
-         * @see Font#FONT_WEIGHT_EXTRA_LIGHT
-         * @see Font#FONT_WEIGHT_LIGHT
-         * @see Font#FONT_WEIGHT_NORMAL
-         * @see Font#FONT_WEIGHT_MEDIUM
-         * @see Font#FONT_WEIGHT_SEMI_BOLD
-         * @see Font#FONT_WEIGHT_BOLD
-         * @see Font#FONT_WEIGHT_EXTRA_BOLD
-         * @see Font#FONT_WEIGHT_BLACK
+         * @see FontStyle#FONT_WEIGHT_THIN
+         * @see FontStyle#FONT_WEIGHT_EXTRA_LIGHT
+         * @see FontStyle#FONT_WEIGHT_LIGHT
+         * @see FontStyle#FONT_WEIGHT_NORMAL
+         * @see FontStyle#FONT_WEIGHT_MEDIUM
+         * @see FontStyle#FONT_WEIGHT_SEMI_BOLD
+         * @see FontStyle#FONT_WEIGHT_BOLD
+         * @see FontStyle#FONT_WEIGHT_EXTRA_BOLD
+         * @see FontStyle#FONT_WEIGHT_BLACK
          * @param weight a weight value
          * @return this builder
          */
         public @NonNull Builder setWeight(
-                @IntRange(from = FONT_WEIGHT_MIN, to = FONT_WEIGHT_MAX) int weight) {
-            Preconditions.checkArgument(FONT_WEIGHT_MIN <= weight && weight <= FONT_WEIGHT_MAX);
+                @IntRange(from = FontStyle.FONT_WEIGHT_MIN, to = FontStyle.FONT_WEIGHT_MAX)
+                int weight) {
+            Preconditions.checkArgument(
+                    FontStyle.FONT_WEIGHT_MIN <= weight && weight <= FontStyle.FONT_WEIGHT_MAX);
             mWeight = weight;
             return this;
         }
@@ -346,13 +293,12 @@
          * will resolve the style by reading font tables.
          *
          * For example, if you want to use italic font as upright font, call {@code
-         * setItalic(false)} explicitly.
+         * setSlant(false)} explicitly.
          *
-         * @param italic {@code true} if the font is italic. Otherwise {@code false}.
          * @return this builder
          */
-        public @NonNull Builder setItalic(boolean italic) {
-            mItalic = italic ? STYLE_ITALIC : STYLE_NORMAL;
+        public @NonNull Builder setSlant(@FontStyle.FontSlant int slant) {
+            mItalic = slant == FontStyle.FONT_SLANT_UPRIGHT ? STYLE_NORMAL : STYLE_ITALIC;
             return this;
         }
 
@@ -414,8 +360,11 @@
                     mItalic = STYLE_NORMAL;
                 }
             }
-            mWeight = Math.max(FONT_WEIGHT_MIN, Math.min(FONT_WEIGHT_MAX, mWeight));
+            mWeight = Math.max(FontStyle.FONT_WEIGHT_MIN,
+                    Math.min(FontStyle.FONT_WEIGHT_MAX, mWeight));
             final boolean italic = (mItalic == STYLE_ITALIC);
+            final int slant = (mItalic == STYLE_ITALIC)
+                    ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT;
             final long builderPtr = nInitBuilder();
             if (mAxes != null) {
                 for (FontVariationAxis axis : mAxes) {
@@ -424,8 +373,8 @@
             }
             final ByteBuffer readonlyBuffer = mBuffer.asReadOnlyBuffer();
             final long ptr = nBuild(builderPtr, readonlyBuffer, mWeight, italic, mTtcIndex);
-            final Font font = new Font(ptr, readonlyBuffer, mFile, mWeight, italic, mTtcIndex,
-                    mAxes, mLocaleList);
+            final Font font = new Font(ptr, readonlyBuffer, mFile,
+                    new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList);
             sFontRegistory.registerNativeAllocation(font, ptr);
             return font;
         }
@@ -454,8 +403,7 @@
     private final long mNativePtr;  // address of the shared ptr of minikin::Font
     private final @NonNull ByteBuffer mBuffer;
     private final @Nullable File mFile;
-    private final @IntRange(from = 0, to = 1000) int mWeight;
-    private final boolean mItalic;
+    private final FontStyle mFontStyle;
     private final @IntRange(from = 0) int mTtcIndex;
     private final @Nullable FontVariationAxis[] mAxes;
     private final @NonNull String mLocaleList;
@@ -464,13 +412,11 @@
      * Use Builder instead
      */
     private Font(long nativePtr, @NonNull ByteBuffer buffer, @Nullable File file,
-            @IntRange(from = 0, to = 1000) int weight, boolean italic,
-            @IntRange(from = 0) int ttcIndex, @Nullable FontVariationAxis[] axes,
-            @NonNull String localeList) {
+            @NonNull FontStyle fontStyle, @IntRange(from = 0) int ttcIndex,
+            @Nullable FontVariationAxis[] axes, @NonNull String localeList) {
         mBuffer = buffer;
         mFile = file;
-        mWeight = weight;
-        mItalic = italic;
+        mFontStyle = fontStyle;
         mNativePtr = nativePtr;
         mTtcIndex = ttcIndex;
         mAxes = axes;
@@ -504,17 +450,17 @@
      * @return a weight value
      */
     public @IntRange(from = 0, to = 1000)int getWeight() {
-        return mWeight;
+        return mFontStyle.getWeight();
     }
 
     /**
-     * Returns true if this font is marked as italic, otherwise returns false.
+     * Get a slant value associated with this font.
      *
-     * @see Builder#setItalic(boolean)
-     * @return true if italic, otherwise false
+     * @see Builder#setSlant(boolean)
+     * @return a slant value
      */
-    public boolean isItalic() {
-        return mItalic;
+    public @FontStyle.FontSlant int getSlant() {
+        return mFontStyle.getSlant();
     }
 
     /**
@@ -564,21 +510,20 @@
             return false;
         }
         Font f = (Font) o;
-        return f.mWeight == mWeight && f.mItalic == mItalic && f.mTtcIndex == mTtcIndex
+        return mFontStyle.equals(f.mFontStyle) && f.mTtcIndex == mTtcIndex
                 && Arrays.equals(f.mAxes, mAxes) && f.mBuffer.equals(mBuffer);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(mWeight, mItalic, mTtcIndex, Arrays.hashCode(mAxes), mBuffer);
+        return Objects.hash(mFontStyle, mTtcIndex, Arrays.hashCode(mAxes), mBuffer);
     }
 
     @Override
     public String toString() {
         return "Font {"
             + "path=" + mFile
-            + ", weight=" + mWeight
-            + ", italic=" + mItalic
+            + ", style=" + mFontStyle
             + ", ttcIndex=" + mTtcIndex
             + ", axes=" + FontVariationAxis.toFontVariationSettings(mAxes)
             + ", localeList=" + mLocaleList
diff --git a/graphics/java/android/graphics/fonts/FontFamily.java b/graphics/java/android/graphics/fonts/FontFamily.java
index 3bcdc31..52a37da 100644
--- a/graphics/java/android/graphics/fonts/FontFamily.java
+++ b/graphics/java/android/graphics/fonts/FontFamily.java
@@ -124,7 +124,7 @@
         }
 
         private static int makeStyleIdentifier(@NonNull Font font) {
-            return font.getWeight() | (font.isItalic() ? (1 << 16) : 0);
+            return font.getWeight() | (font.getSlant()  << 16);
         }
 
         private static native long nInitBuilder();
diff --git a/graphics/java/android/graphics/fonts/FontStyle.java b/graphics/java/android/graphics/fonts/FontStyle.java
new file mode 100644
index 0000000..82fc7ac
--- /dev/null
+++ b/graphics/java/android/graphics/fonts/FontStyle.java
@@ -0,0 +1,256 @@
+/*
+ * 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.graphics.fonts;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.Nullable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * A font style object.
+ *
+ * This class represents a single font style which is a pair of weight value and slant value.
+ * Here are common font styles examples:
+ * <p>
+ * <pre>
+ * <code>
+ * final FontStyle NORMAL = new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_UPRIGHT);
+ * final FontStyle BOLD = new FontStyle(FONT_WEIGHT_BOLD, FONT_SLANT_UPRIGHT);
+ * final FontStyle ITALIC = new FontStyle(FONT_WEIGHT_NORMAL, FONT_SLANT_ITALIC);
+ * final FontStyle BOLD_ITALIC = new FontStyle(FONT_WEIGHT_BOLD, FONT_SLANT_ITALIC);
+ * </code>
+ * </pre>
+ * </p>
+ *
+ */
+public final class FontStyle {
+    private static final String TAG = "FontStyle";
+
+    /**
+     * A minimum weight value for the font
+     */
+    public static final int FONT_WEIGHT_MIN = 1;
+
+    /**
+     * A font weight value for the thin weight
+     */
+    public static final int FONT_WEIGHT_THIN = 100;
+
+    /**
+     * A font weight value for the extra-light weight
+     */
+    public static final int FONT_WEIGHT_EXTRA_LIGHT = 200;
+
+    /**
+     * A font weight value for the light weight
+     */
+    public static final int FONT_WEIGHT_LIGHT = 300;
+
+    /**
+     * A font weight value for the normal weight
+     */
+    public static final int FONT_WEIGHT_NORMAL = 400;
+
+    /**
+     * A font weight value for the medium weight
+     */
+    public static final int FONT_WEIGHT_MEDIUM = 500;
+
+    /**
+     * A font weight value for the semi-bold weight
+     */
+    public static final int FONT_WEIGHT_SEMI_BOLD = 600;
+
+    /**
+     * A font weight value for the bold weight.
+     */
+    public static final int FONT_WEIGHT_BOLD = 700;
+
+    /**
+     * A font weight value for the extra-bold weight
+     */
+    public static final int FONT_WEIGHT_EXTRA_BOLD = 800;
+
+    /**
+     * A font weight value for the black weight
+     */
+    public static final int FONT_WEIGHT_BLACK = 900;
+
+    /**
+     * A maximum weight value for the font
+     */
+    public static final int FONT_WEIGHT_MAX = 1000;
+
+    /**
+     * A font slant value for upright
+     */
+    public static final int FONT_SLANT_UPRIGHT = 0;
+
+    /**
+     * A font slant value for italic
+     */
+    public static final int FONT_SLANT_ITALIC = 1;
+
+    // TODO: Support FONT_SLANT_OBLIQUE
+
+    /** @hide */
+    @IntDef(prefix = { "FONT_SLANT_" }, value = {
+            FONT_SLANT_UPRIGHT,
+            FONT_SLANT_ITALIC
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FontSlant {}
+
+    private final @IntRange(from = 0, to = 1000) int mWeight;
+    private final @FontSlant int mSlant;
+    // TODO: Support width
+
+    public FontStyle() {
+        mWeight = FONT_WEIGHT_NORMAL;
+        mSlant = FONT_SLANT_UPRIGHT;
+    }
+
+    /**
+     * Create FontStyle with specific weight and italic
+     *
+     * <p>
+     *  <table>
+     *  <thead>
+     *  <tr>
+     *  <th align="center">Value</th>
+     *  <th align="center">Name</th>
+     *  <th align="center">Android Definition</th>
+     *  </tr>
+     *  </thead>
+     *  <tbody>
+     *  <tr>
+     *  <td align="center">100</td>
+     *  <td align="center">Thin</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_THIN}</td>
+     *  </tr>
+     *  <tr>
+     *  <td align="center">200</td>
+     *  <td align="center">Extra Light (Ultra Light)</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_LIGHT}</td>
+     *  </tr>
+     *  <tr>
+     *  <td align="center">300</td>
+     *  <td align="center">Light</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_LIGHT}</td>
+     *  </tr>
+     *  <tr>
+     *  <td align="center">400</td>
+     *  <td align="center">Normal (Regular)</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_NORMAL}</td>
+     *  </tr>
+     *  <tr>
+     *  <td align="center">500</td>
+     *  <td align="center">Medium</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_MEDIUM}</td>
+     *  </tr>
+     *  <tr>
+     *  <td align="center">600</td>
+     *  <td align="center">Semi Bold (Demi Bold)</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_SEMI_BOLD}</td>
+     *  </tr>
+     *  <tr>
+     *  <td align="center">700</td>
+     *  <td align="center">Bold</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_BOLD}</td>
+     *  </tr>
+     *  <tr>
+     *  <td align="center">800</td>
+     *  <td align="center">Extra Bold (Ultra Bold)</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_EXTRA_BOLD}</td>
+     *  </tr>
+     *  <tr>
+     *  <td align="center">900</td>
+     *  <td align="center">Black (Heavy)</td>
+     *  <td align="center">{@link FontStyle#FONT_WEIGHT_BLACK}</td>
+     *  </tr>
+     *  </tbody>
+     * </p>
+     *
+     * @see FontStyle#FONT_WEIGHT_THIN
+     * @see FontStyle#FONT_WEIGHT_EXTRA_LIGHT
+     * @see FontStyle#FONT_WEIGHT_LIGHT
+     * @see FontStyle#FONT_WEIGHT_NORMAL
+     * @see FontStyle#FONT_WEIGHT_MEDIUM
+     * @see FontStyle#FONT_WEIGHT_SEMI_BOLD
+     * @see FontStyle#FONT_WEIGHT_BOLD
+     * @see FontStyle#FONT_WEIGHT_EXTRA_BOLD
+     * @see FontStyle#FONT_WEIGHT_BLACK
+     * @param weight a weight value
+     * @param slant a slant value
+     */
+    public FontStyle(int weight, @FontSlant int slant) {
+        Preconditions.checkArgument(FONT_WEIGHT_MIN <= weight && weight <= FONT_WEIGHT_MAX,
+                "weight value must be [" + FONT_WEIGHT_MIN + ", " + FONT_WEIGHT_MAX + "]");
+        Preconditions.checkArgument(slant == FONT_SLANT_UPRIGHT || slant == FONT_SLANT_ITALIC,
+                "slant value must be FONT_SLANT_UPRIGHT or FONT_SLANT_UPRIGHT");
+        mWeight = weight;
+        mSlant = slant;
+    }
+
+
+     /**
+      * Gets the weight value
+      *
+      * @see FontStyle#setWeight(int)
+      * @return a weight value
+      */
+    public @IntRange(from = 0, to = 1000) int getWeight() {
+        return mWeight;
+    }
+
+    /**
+     * Gets the slant value
+     *
+     * @return a slant value
+     */
+    public @FontSlant int getSlant() {
+        return mSlant;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (o == this) {
+            return true;
+        }
+        if (o == null || !(o instanceof FontStyle)) {
+            return false;
+        }
+        FontStyle fontStyle = (FontStyle) o;
+        return fontStyle.mWeight == mWeight && fontStyle.mSlant == mSlant;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mWeight, mSlant);
+    }
+
+    @Override
+    public String toString() {
+        return "FontStyle { weight=" + mWeight + ", slant=" + mSlant + "}";
+    }
+}
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index 2d21bbb..750adb2 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -192,7 +192,8 @@
             try {
                 font = new Font.Builder(buffer, new File(fullPath), languageTags)
                         .setWeight(fontConfig.getWeight())
-                        .setItalic(fontConfig.isItalic())
+                        .setSlant(fontConfig.isItalic() ? FontStyle.FONT_SLANT_ITALIC
+                                : FontStyle.FONT_SLANT_UPRIGHT)
                         .setTtcIndex(fontConfig.getTtcIndex())
                         .setFontVariationSettings(fontConfig.getAxes())
                         .build();
diff --git a/graphics/java/android/graphics/pdf/PdfEditor.java b/graphics/java/android/graphics/pdf/PdfEditor.java
index 3821bc7..21ce1b8 100644
--- a/graphics/java/android/graphics/pdf/PdfEditor.java
+++ b/graphics/java/android/graphics/pdf/PdfEditor.java
@@ -27,7 +27,6 @@
 import android.system.OsConstants;
 import dalvik.system.CloseGuard;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.IOException;
 
diff --git a/core/java/android/text/NativeLineBreaker.java b/graphics/java/android/graphics/text/LineBreaker.java
similarity index 67%
rename from core/java/android/text/NativeLineBreaker.java
rename to graphics/java/android/graphics/text/LineBreaker.java
index 94e10e8..1647909 100644
--- a/core/java/android/text/NativeLineBreaker.java
+++ b/graphics/java/android/graphics/text/LineBreaker.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.text;
+package android.graphics.text;
 
 import android.annotation.FloatRange;
 import android.annotation.IntDef;
@@ -32,11 +32,60 @@
 import java.lang.annotation.RetentionPolicy;
 
 /**
- * A native implementation of the line breaker.
- * TODO: Consider to make this class public.
- * @hide
+ * Provides automatic line breaking for a <em>single</em> paragraph.
+ *
+ * <p>
+ * <pre>
+ * <code>
+ * Paint paint = new Paint();
+ * Paint bigPaint = new Paint();
+ * bigPaint.setTextSize(paint.getTextSize() * 2.0);
+ * String text = "Hello, Android.";
+ *
+ * // Prepare the measured text
+ * MeasuredText mt = new MeasuredText.Builder(text.toCharArray())
+ *     .appendStyleRun(paint, 7, false)  // Use paint for "Hello, "
+ *     .appednStyleRun(bigPaint, 8, false)  // Use bigPaint for "Hello, "
+ *     .build();
+ *
+ * LineBreaker lb = new LineBreaker.Builder()
+ *     // Use simple line breaker
+ *     .setBreakStrategy(LineBreaker.BREAK_STRATEGY_SIMPLE)
+ *     // Do not add hyphenation.
+ *     .setHyphenationFrequency(LineBreaker.HYPHENATION_FREQUENCY_NONE)
+ *     // Build the LineBreaker
+ *     .build();
+ *
+ * ParagraphConstraints c = new ParagraphConstraints();
+ * c.setWidth(240);  // Set the line wieth as 1024px
+ *
+ * // Do the line breaking
+ * Result r = lb.computeLineBreaks(mt, c, 0);
+ *
+ * // Compute the total height of the text.
+ * float totalHeight = 0;
+ * for (int i = 0; i < r.getLineCount(); ++i) {  // iterate over the lines
+ *    totalHeight += r.getLineDescent(i) - r.getLineAscent(i);
+ * }
+ *
+ * // Draw text to the canvas
+ * Bitmap bmp = new Bitmap.createBitmap(240, totalHeight, Bitmap.Config.ARGB_8888);
+ * Canvas c = new Canvas(bmp);
+ * float yOffset = 0f;
+ * int prevOffset = 0;
+ * for (int i = 0; i < r.getLineCount(); ++i) {  // iterate over the lines
+ *     int nextOffset = r.getLineBreakOffset(i);
+ *     c.drawText(text, prevOffset, nextOffset, 0f, yOffset, paint);
+ *
+ *     prevOffset = nextOffset;
+ *     yOffset += r.getLineDescent(i) - r.getLineAscent(i);
+ * }
+ * </code>
+ * </pre>
+ * </p>
  */
-public class NativeLineBreaker {
+public class LineBreaker {
+    /** @hide */
     @IntDef(prefix = { "BREAK_STRATEGY_" }, value = {
             BREAK_STRATEGY_SIMPLE,
             BREAK_STRATEGY_HIGH_QUALITY,
@@ -46,25 +95,33 @@
     public @interface BreakStrategy {}
 
     /**
-     * Value for break strategy indicating simple line breaking. Automatic hyphens are not added
-     * (though soft hyphens are respected), and modifying text generally doesn't affect the layout
-     * before it (which yields a more consistent user experience when editing), but layout may not
-     * be the highest quality.
+     * Value for break strategy indicating simple line breaking.
+     *
+     * The line breaker puts words to the line as much as possible and breaks line if no more words
+     * can fit into the same line. Automatic hyphens are only added when a line has a single word
+     * and that word is longer than line width. This is the fastest break strategy and ideal for
+     * editor.
      */
     public static final int BREAK_STRATEGY_SIMPLE = 0;
 
     /**
-     * Value for break strategy indicating high quality line breaking, including automatic
-     * hyphenation and doing whole-paragraph optimization of line breaks.
+     * Value for break strategy indicating high quality line breaking.
+     *
+     * With this option line breaker does whole-paragraph optimization for more readable text, and
+     * also applies automatic hyphenation when required.
      */
     public static final int BREAK_STRATEGY_HIGH_QUALITY = 1;
 
     /**
-     * Value for break strategy indicating balanced line breaking. The breaks are chosen to
-     * make all lines as close to the same length as possible, including automatic hyphenation.
+     * Value for break strategy indicating balanced line breaking.
+     *
+     * The line breaker does whole-paragraph optimization for making all lines similar length, and
+     * also applies automatic hyphenation when required. This break strategy is good for small
+     * screen devices such as watch screens.
      */
     public static final int BREAK_STRATEGY_BALANCED = 2;
 
+    /** @hide */
     @IntDef(prefix = { "HYPHENATION_FREQUENCY_" }, value = {
             HYPHENATION_FREQUENCY_NORMAL,
             HYPHENATION_FREQUENCY_FULL,
@@ -74,28 +131,32 @@
     public @interface HyphenationFrequency {}
 
     /**
-     * Value for hyphenation frequency indicating no automatic hyphenation. Useful
-     * for backward compatibility, and for cases where the automatic hyphenation algorithm results
-     * in incorrect hyphenation. Mid-word breaks may still happen when a word is wider than the
-     * layout and there is otherwise no valid break. Soft hyphens are ignored and will not be used
-     * as suggestions for potential line breaks.
+     * Value for hyphenation frequency indicating no automatic hyphenation.
+     *
+     * Using this option disables auto hyphenation which results in better text layout performance.
+     * A word may be broken without hyphens when a line has a single word and that word is longer
+     * than line width. Soft hyphens are ignored and will not be used as suggestions for potential
+     * line breaks.
      */
     public static final int HYPHENATION_FREQUENCY_NONE = 0;
 
     /**
-     * Value for hyphenation frequency indicating a light amount of automatic hyphenation, which
-     * is a conservative default. Useful for informal cases, such as short sentences or chat
+     * Value for hyphenation frequency indicating a light amount of automatic hyphenation.
+     *
+     * This hyphenation frequency is useful for informal cases, such as short sentences or chat
      * messages.
      */
     public static final int HYPHENATION_FREQUENCY_NORMAL = 1;
 
     /**
-     * Value for hyphenation frequency indicating the full amount of automatic hyphenation, typical
-     * in typography. Useful for running text and where it's important to put the maximum amount of
-     * text in a screen with limited space.
+     * Value for hyphenation frequency indicating the full amount of automatic hyphenation.
+     *
+     * This hyphenation frequency is useful for running text and where it's important to put the
+     * maximum amount of text in a screen with limited space.
      */
     public static final int HYPHENATION_FREQUENCY_FULL = 2;
 
+    /** @hide */
     @IntDef(prefix = { "JUSTIFICATION_MODE_" }, value = {
             JUSTIFICATION_MODE_NONE,
             JUSTIFICATION_MODE_INTER_WORD
@@ -114,7 +175,7 @@
     public static final int JUSTIFICATION_MODE_INTER_WORD = 1;
 
     /**
-     * A builder class of NativeLineBreaker.
+     * Helper class for creating a {@link LineBreaker}.
      */
     public static class Builder {
         private @BreakStrategy int mBreakStrategy = BREAK_STRATEGY_SIMPLE;
@@ -123,12 +184,10 @@
         private @Nullable int[] mIndents = null;
 
         /**
-         * Construct a builder class.
-         */
-        public Builder() {}
-
-        /**
          * Set break strategy.
+         *
+         * You can change the line breaking behavior by setting break strategy. The default value is
+         * {@link #BREAK_STRATEGY_SIMPLE}.
          */
         public Builder setBreakStrategy(@BreakStrategy int breakStrategy) {
             mBreakStrategy = breakStrategy;
@@ -137,6 +196,9 @@
 
         /**
          * Set hyphenation frequency.
+         *
+         * You can change the amount of automatic hyphenation used. The default value is
+         * {@link #HYPHENATION_FREQUENCY_NONE}.
          */
         public Builder setHyphenationFrequency(@HyphenationFrequency int hyphenationFrequency) {
             mHyphenationFrequency = hyphenationFrequency;
@@ -145,6 +207,10 @@
 
         /**
          * Set whether the text is justified.
+         *
+         * By setting {@link #JUSTIFICATION_MODE_INTER_WORD}, the line breaker will change the
+         * internal parameters for justification.
+         * The default value is {@link #JUSTIFICATION_MODE_NONE}
          */
         public Builder setJustified(@JustificationMode int justified) {
             mJustified = justified;
@@ -152,9 +218,11 @@
         }
 
         /**
-         * Set indents for entire text.
+         * Set indents.
          *
-         * Sets the total (left + right) indents in pixel per lines.
+         * The supplied array provides the total amount of indentation per line, in pixel. This
+         * amount is the sum of both left and right indentations. For lines past the last element in
+         * the array, the indentation amount of the last element is used.
          */
         public Builder setIndents(@Nullable int[] indents) {
             mIndents = indents;
@@ -162,11 +230,12 @@
         }
 
         /**
-         * Returns the NativeLineBreaker with given parameters.
+         * Build a new LineBreaker with given parameters.
+         *
+         * You can reuse the Builder instance even after calling this method.
          */
-        NativeLineBreaker build() {
-            return new NativeLineBreaker(mBreakStrategy, mHyphenationFrequency, mJustified,
-                    mIndents);
+        public LineBreaker build() {
+            return new LineBreaker(mBreakStrategy, mHyphenationFrequency, mJustified, mIndents);
         }
     }
 
@@ -184,8 +253,10 @@
 
         /**
          * Set width for this paragraph.
+         *
+         * @see #getWidth()
          */
-        public void setWidth(@FloatRange(from = 0.0f) float width) {
+        public void setWidth(@Px @FloatRange(from = 0.0f) float width) {
             mWidth = width;
         }
 
@@ -194,9 +265,11 @@
          *
          * @param firstWidth the line width of the starting of the paragraph
          * @param firstWidthLineCount the number of lines that applies the firstWidth
+         * @see #getFirstWidth()
+         * @see #getFirstWidthLineCount()
          */
-        public void setIndent(@FloatRange(from = 0.0f) float firstWidth,
-                @IntRange(from = 0) int firstWidthLineCount) {
+        public void setIndent(@Px @FloatRange(from = 0.0f) float firstWidth,
+                @Px @IntRange(from = 0) int firstWidthLineCount) {
             mFirstWidth = firstWidth;
             mFirstWidthLineCount = firstWidthLineCount;
         }
@@ -206,16 +279,21 @@
          *
          * @param tabStops the array of pixels of tap stopping position
          * @param defaultTabStop pixels of the default tab stopping position
+         * @see #getTabStops()
+         * @see #getDefaultTabStop()
          */
-        public void setTabStops(@Nullable int[] tabStops, @IntRange(from = 0) int defaultTabStop) {
+        public void setTabStops(@Nullable int[] tabStops,
+                @Px @IntRange(from = 0) int defaultTabStop) {
             mVariableTabStops = tabStops;
             mDefaultTabStop = defaultTabStop;
         }
 
         /**
          * Return the width for this paragraph in pixels.
+         *
+         * @see #setWidth(float)
          */
-        public @FloatRange(from = 0.0f) float getWidth() {
+        public @Px @FloatRange(from = 0.0f) float getWidth() {
             return mWidth;
         }
 
@@ -224,7 +302,7 @@
          *
          * @see #setIndent(float, int)
          */
-        public @FloatRange(from = 0.0f) float getFirstWidth() {
+        public @Px @FloatRange(from = 0.0f) float getFirstWidth() {
             return mFirstWidth;
         }
 
@@ -233,7 +311,7 @@
          *
          * @see #setIndent(float, int)
          */
-        public @IntRange(from = 0) int getFirstWidthLineCount() {
+        public @Px @IntRange(from = 0) int getFirstWidthLineCount() {
             return mFirstWidthLineCount;
         }
 
@@ -251,13 +329,14 @@
          *
          * @see #setTabStop(int[], int)
          */
-        public @IntRange(from = 0) int getDefaultTabStop() {
+        public @Px @IntRange(from = 0) int getDefaultTabStop() {
             return mDefaultTabStop;
         }
     }
 
     /**
-     * A result object of a line breaking
+     * Holds the result of the {@link LineBreaker#computeLineBreaks line breaking algorithm}.
+     * @see LineBreaker#computeLineBreaks
      */
     public static class Result {
         // Following two contstant must be synced with minikin's line breaker.
@@ -274,7 +353,7 @@
         }
 
         /**
-         * Returns a number of line count.
+         * Returns the number of lines in the paragraph.
          *
          * @return number of lines
          */
@@ -283,7 +362,7 @@
         }
 
         /**
-         * Returns a break offset of the line.
+         * Returns character offset of the break for a given line.
          *
          * @param lineIndex an index of the line.
          * @return the break offset.
@@ -293,17 +372,17 @@
         }
 
         /**
-         * Returns a width of the line in pixels.
+         * Returns width of a given line in pixels.
          *
          * @param lineIndex an index of the line.
-         * @return a width of the line in pixexls
+         * @return width of the line in pixels
          */
         public @Px float getLineWidth(@IntRange(from = 0) int lineIndex) {
             return nGetLineWidth(mPtr, lineIndex);
         }
 
         /**
-         * Returns an entier font ascent of the line in pixels.
+         * Returns font ascent of the line in pixels.
          *
          * @param lineIndex an index of the line.
          * @return an entier font ascent of the line in pixels.
@@ -313,7 +392,7 @@
         }
 
         /**
-         * Returns an entier font descent of the line in pixels.
+         * Returns font descent of the line in pixels.
          *
          * @param lineIndex an index of the line.
          * @return an entier font descent of the line in pixels.
@@ -337,6 +416,7 @@
          *
          * @param lineIndex an index of the line.
          * @return a packed hyphen edit for the line.
+         *
          * @see android.text.Hyphenator#unpackStartHyphenEdit(int)
          * @see android.text.Hyphenator#unpackEndHyphenEdit(int)
          * @see android.text.Hyphenator#packHyphenEdit(int,int)
@@ -347,14 +427,14 @@
     }
 
     private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
-            NativeLineBreaker.class.getClassLoader(), nGetReleaseFunc(), 64);
+            LineBreaker.class.getClassLoader(), nGetReleaseFunc(), 64);
 
     private final long mNativePtr;
 
     /**
      * Use Builder instead.
      */
-    private NativeLineBreaker(@BreakStrategy int breakStrategy,
+    private LineBreaker(@BreakStrategy int breakStrategy,
             @HyphenationFrequency int hyphenationFrequency, @JustificationMode int justify,
             @Nullable int[] indents) {
         mNativePtr = nInit(breakStrategy, hyphenationFrequency,
@@ -372,7 +452,7 @@
      * @param lineNumber a line number of this paragraph
      */
     public Result computeLineBreaks(
-            @NonNull NativeMeasuredParagraph measuredPara,
+            @NonNull MeasuredText measuredPara,
             @NonNull ParagraphConstraints constraints,
             @IntRange(from = 0) int lineNumber) {
         return new Result(nComputeLineBreaks(
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
new file mode 100644
index 0000000..3efe655
--- /dev/null
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -0,0 +1,348 @@
+/*
+ * 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.graphics.text;
+
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Px;
+import android.graphics.Paint;
+import android.graphics.Rect;
+
+import com.android.internal.util.Preconditions;
+
+import dalvik.annotation.optimization.CriticalNative;
+
+import libcore.util.NativeAllocationRegistry;
+
+/**
+ * Result of text shaping of the single paragraph string.
+ *
+ * <p>
+ * <pre>
+ * <code>
+ * Paint paint = new Paint();
+ * Paint bigPaint = new Paint();
+ * bigPaint.setTextSize(paint.getTextSize() * 2.0);
+ * String text = "Hello, Android.";
+ * MeasuredText mt = new MeasuredText.Builder(text.toCharArray())
+ *      .appendStyleRun(paint, 7, false)  // Use paint for "Hello, "
+ *      .appendStyleRun(bigPaint, 8, false)  // Use bigPaint for "Hello, "
+ *      .build();
+ * </code>
+ * </pre>
+ * </p>
+ */
+public class MeasuredText {
+    private static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry(
+            MeasuredText.class.getClassLoader(), nGetReleaseFunc(), 1024);
+
+    private long mNativePtr;
+    private @NonNull char[] mChars;
+
+    // Use builder instead.
+    private MeasuredText(long ptr, @NonNull char[] chars) {
+        mNativePtr = ptr;
+        mChars = chars;
+    }
+
+    /**
+     * Returns the characters in the paragraph used to compute this MeasuredText instance.
+     */
+    public @NonNull char[] getChars() {
+        return mChars;
+    }
+
+    /**
+     * Returns the width of a given range.
+     *
+     * @param start an inclusive start index of the range
+     * @param end an exclusive end index of the range
+     */
+    public @FloatRange(from = 0.0) @Px float getWidth(
+            @IntRange(from = 0) int start, @IntRange(from = 0) int end) {
+        Preconditions.checkArgument(0 <= start && start <= mChars.length,
+                "start(" + start + ") must be 0 <= start <= " + mChars.length);
+        Preconditions.checkArgument(0 <= end && end <= mChars.length,
+                "end(" + end + ") must be 0 <= end <= " + mChars.length);
+        Preconditions.checkArgument(start <= end,
+                "start(" + start + ") is larger than end(" + end + ")");
+        return nGetWidth(mNativePtr, start, end);
+    }
+
+    /**
+     * Returns a memory usage of the native object.
+     *
+     * @hide
+     */
+    public int getMemoryUsage() {
+        return nGetMemoryUsage(mNativePtr);
+    }
+
+    /**
+     * Retrieves the boundary box of the given range
+     *
+     * @param start an inclusive start index of the range
+     * @param end an exclusive end index of the range
+     * @param rect an output parameter
+     */
+    public void getBounds(@IntRange(from = 0) int start, @IntRange(from = 0) int end,
+            @NonNull Rect rect) {
+        Preconditions.checkArgument(0 <= start && start <= mChars.length,
+                "start(" + start + ") must be 0 <= start <= " + mChars.length);
+        Preconditions.checkArgument(0 <= end && end <= mChars.length,
+                "end(" + end + ") must be 0 <= end <= " + mChars.length);
+        Preconditions.checkArgument(start <= end,
+                "start(" + start + ") is larger than end(" + end + ")");
+        Preconditions.checkNotNull(rect);
+        nGetBounds(mNativePtr, mChars, start, end, rect);
+    }
+
+    /**
+     * Returns the width of the character at the given offset.
+     *
+     * @param offset an offset of the character.
+     */
+    public @FloatRange(from = 0.0f) @Px float getCharWidthAt(@IntRange(from = 0) int offset) {
+        Preconditions.checkArgument(0 <= offset && offset < mChars.length,
+                "offset(" + offset + ") is larger than text length: " + mChars.length);
+        return nGetCharWidthAt(mNativePtr, offset);
+    }
+
+    /**
+     * Returns a native pointer of the underlying native object.
+     *
+     * @hide
+     */
+    public long getNativePtr() {
+        return mNativePtr;
+    }
+
+    @CriticalNative
+    private static native float nGetWidth(/* Non Zero */ long nativePtr,
+                                         @IntRange(from = 0) int start,
+                                         @IntRange(from = 0) int end);
+
+    @CriticalNative
+    private static native /* Non Zero */ long nGetReleaseFunc();
+
+    @CriticalNative
+    private static native int nGetMemoryUsage(/* Non Zero */ long nativePtr);
+
+    private static native void nGetBounds(long nativePtr, char[] buf, int start, int end,
+            Rect rect);
+
+    @CriticalNative
+    private static native float nGetCharWidthAt(long nativePtr, int offset);
+
+    /**
+     * Helper class for creating a {@link MeasuredText}.
+     * <p>
+     * <pre>
+     * <code>
+     * Paint paint = new Paint();
+     * String text = "Hello, Android.";
+     * MeasuredText mt = new MeasuredText.Builder(text.toCharArray())
+     *      .appendStyleRun(paint, text.length, false)
+     *      .build();
+     * </code>
+     * </pre>
+     * </p>
+     *
+     * Note: The appendStyle and appendReplacementRun should be called to cover the text length.
+     */
+    public static class Builder {
+        private long mNativePtr;
+
+        private final @NonNull char[] mText;
+        private boolean mComputeHyphenation = false;
+        private boolean mComputeLayout = true;
+        private int mCurrentOffset = 0;
+
+        /**
+         * Construct a builder.
+         *
+         * The MeasuredText returned by build method will hold a reference of the text. Developer is
+         * not supposed to modify the text.
+         *
+         * @param text a text
+         */
+        public Builder(@NonNull char[] text) {
+            Preconditions.checkNotNull(text);
+            mText = text;
+            mNativePtr = nInitBuilder();
+        }
+
+        /**
+         * Apply styles to the given length.
+         *
+         * Keeps an internal offset which increases at every append. The initial value for this
+         * offset is zero. After the style is applied the internal offset is moved to {@code offset
+         * + length}, and next call will start from this new position.
+         *
+         * @param paint a paint
+         * @param length a length to be applied with a given paint, can not exceed the length of the
+         *               text
+         * @param isRtl true if the text is in RTL context, otherwise false.
+         */
+        public Builder appendStyleRun(@NonNull Paint paint, @IntRange(from = 0) int length,
+                boolean isRtl) {
+            Preconditions.checkNotNull(paint);
+            Preconditions.checkArgument(length > 0, "length can not be negative");
+            final int end = mCurrentOffset + length;
+            Preconditions.checkArgument(end <= mText.length, "Style exceeds the text length");
+            nAddStyleRun(mNativePtr, paint.getNativeInstance(), mCurrentOffset, end, isRtl);
+            mCurrentOffset = end;
+            return this;
+        }
+
+        /**
+         * Used to inform the text layout that the given length is replaced with the object of given
+         * width.
+         *
+         * Keeps an internal offset which increases at every append. The initial value for this
+         * offset is zero. After the style is applied the internal offset is moved to {@code offset
+         * + length}, and next call will start from this new position.
+         *
+         * Informs the layout engine that the given length should not be processed, instead the
+         * provided width should be used for calculating the width of that range.
+         *
+         * @param length a length to be replaced with the object, can not exceed the length of the
+         *               text
+         * @param width a replacement width of the range
+         */
+        public Builder appendReplacementRun(@NonNull Paint paint,
+                @IntRange(from = 0) int length, @FloatRange(from = 0) float width) {
+            Preconditions.checkArgument(length > 0, "length can not be negative");
+            final int end = mCurrentOffset + length;
+            Preconditions.checkArgument(end <= mText.length, "Replacement exceeds the text length");
+            nAddReplacementRun(mNativePtr, paint.getNativeInstance(), mCurrentOffset, end, width);
+            mCurrentOffset = end;
+            return this;
+        }
+
+        /**
+         * By passing true to this method, the build method will compute all possible hyphenation
+         * pieces as well.
+         *
+         * If you don't want to use automatic hyphenation, you can pass false to this method and
+         * save the computation time of hyphenation. The default value is false.
+         *
+         * Even if you pass false to this method, you can still enable automatic hyphenation of
+         * LineBreaker but line break computation becomes slower.
+         *
+         * @param computeHyphenation true if you want to use automatic hyphenations.
+         */
+        public Builder setComputeHyphenation(boolean computeHyphenation) {
+            mComputeHyphenation = computeHyphenation;
+            return this;
+        }
+
+        /**
+         * By passing true to this method, the build method will compute all full layout
+         * information.
+         *
+         * If you don't use {@link MeasuredText#getBounds(int,int,android.graphics.Rect)}, you can
+         * pass false to this method and save the memory spaces. The default value is true.
+         *
+         * Even if you pass false to this method, you can still call getBounds but it becomes
+         * slower.
+         *
+         * @param computeLayout true if you want to retrieve full layout info, e.g. bbox.
+         */
+        public Builder setComputeLayout(boolean computeLayout) {
+            mComputeLayout = computeLayout;
+            return this;
+        }
+
+        /**
+         * Creates a MeasuredText.
+         *
+         * Once you called build() method, you can't reuse the Builder class again.
+         * @throws IllegalStateException if this Builder is reused.
+         * @throws IllegalStateException if the whole text is not covered by one or more runs (style
+         *                               or replacement)
+         */
+        public MeasuredText build() {
+            ensureNativePtrNoReuse();
+            if (mCurrentOffset != mText.length) {
+                throw new IllegalStateException("Style info has not been provided for all text.");
+            }
+            try {
+                long ptr = nBuildMeasuredText(mNativePtr, mText, mComputeHyphenation,
+                        mComputeLayout);
+                MeasuredText res = new MeasuredText(ptr, mText);
+                sRegistry.registerNativeAllocation(res, ptr);
+                return res;
+            } finally {
+                nFreeBuilder(mNativePtr);
+                mNativePtr = 0;
+            }
+        }
+
+        /**
+         * Ensures {@link #mNativePtr} is not reused.
+         *
+         * <p/> This is a method by itself to help increase testability - eg. Robolectric might want
+         * to override the validation behavior in test environment.
+         */
+        private void ensureNativePtrNoReuse() {
+            if (mNativePtr == 0) {
+                throw new IllegalStateException("Builder can not be reused.");
+            }
+        }
+
+        private static native /* Non Zero */ long nInitBuilder();
+
+        /**
+         * Apply style to make native measured text.
+         *
+         * @param nativeBuilderPtr The native MeasuredParagraph builder pointer.
+         * @param paintPtr The native paint pointer to be applied.
+         * @param start The start offset in the copied buffer.
+         * @param end The end offset in the copied buffer.
+         * @param isRtl True if the text is RTL.
+         */
+        private static native void nAddStyleRun(/* Non Zero */ long nativeBuilderPtr,
+                                                /* Non Zero */ long paintPtr,
+                                                @IntRange(from = 0) int start,
+                                                @IntRange(from = 0) int end,
+                                                boolean isRtl);
+        /**
+         * Apply ReplacementRun to make native measured text.
+         *
+         * @param nativeBuilderPtr The native MeasuredParagraph builder pointer.
+         * @param paintPtr The native paint pointer to be applied.
+         * @param start The start offset in the copied buffer.
+         * @param end The end offset in the copied buffer.
+         * @param width The width of the replacement.
+         */
+        private static native void nAddReplacementRun(/* Non Zero */ long nativeBuilderPtr,
+                                                      /* Non Zero */ long paintPtr,
+                                                      @IntRange(from = 0) int start,
+                                                      @IntRange(from = 0) int end,
+                                                      @FloatRange(from = 0) float width);
+
+        private static native long nBuildMeasuredText(
+                /* Non Zero */ long nativeBuilderPtr,
+                @NonNull char[] text,
+                boolean computeHyphenation,
+                boolean computeLayout);
+
+        private static native void nFreeBuilder(/* Non Zero */ long nativeBuilderPtr);
+    }
+}
diff --git a/keystore/OWNERS b/keystore/OWNERS
new file mode 100644
index 0000000..a63ca46
--- /dev/null
+++ b/keystore/OWNERS
@@ -0,0 +1,4 @@
+jbires@google.com
+jdanis@google.com
+robbarnes@google.com
+swillden@google.com
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index bba36bc..98af3eb 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -43,11 +43,14 @@
         "AssetManager2.cpp",
         "AttributeResolution.cpp",
         "ChunkIterator.cpp",
+        "ConfigDescription.cpp",
         "Idmap.cpp",
         "LoadedArsc.cpp",
+        "Locale.cpp",
         "LocaleData.cpp",
         "misc.cpp",
         "ObbFile.cpp",
+        "PosixUtils.cpp",
         "ResourceTypes.cpp",
         "ResourceUtils.cpp",
         "StreamingZipInflater.cpp",
@@ -135,10 +138,12 @@
         "tests/AttributeResolution_test.cpp",
         "tests/ByteBucketArray_test.cpp",
         "tests/Config_test.cpp",
+        "tests/ConfigDescription_test.cpp",
         "tests/ConfigLocale_test.cpp",
         "tests/DynamicRefTable_test.cpp",
         "tests/Idmap_test.cpp",
         "tests/LoadedArsc_test.cpp",
+        "tests/Locale_test.cpp",
         "tests/ResourceUtils_test.cpp",
         "tests/ResTable_test.cpp",
         "tests/Split_test.cpp",
@@ -153,6 +158,7 @@
             srcs: [
                 "tests/BackupData_test.cpp",
                 "tests/ObbFile_test.cpp",
+                "tests/PosixUtils_test.cpp",
             ],
             shared_libs: common_test_libs + ["libui"],
         },
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 8f58f74..66a5477 100644
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -39,7 +39,7 @@
 
 static const std::string kResourcesArsc("resources.arsc");
 
-ApkAssets::ApkAssets(void* unmanaged_handle, const std::string& path)
+ApkAssets::ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path)
     : zip_handle_(unmanaged_handle, ::CloseArchive), path_(path) {
 }
 
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 9c1629b..04cc5bb 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -67,10 +67,10 @@
 }
 
 bool AssetManager2::SetApkAssets(const std::vector<const ApkAssets*>& apk_assets,
-                                 bool invalidate_caches) {
+                                 bool invalidate_caches, bool filter_incompatible_configs) {
   apk_assets_ = apk_assets;
   BuildDynamicRefTable();
-  RebuildFilterList();
+  RebuildFilterList(filter_incompatible_configs);
   if (invalidate_caches) {
     InvalidateCaches(static_cast<uint32_t>(-1));
   }
@@ -825,7 +825,7 @@
   return 0u;
 }
 
-void AssetManager2::RebuildFilterList() {
+void AssetManager2::RebuildFilterList(bool filter_incompatible_configs) {
   for (PackageGroup& group : package_groups_) {
     for (ConfiguredPackage& impl : group.packages_) {
       // Destroy it.
@@ -841,7 +841,7 @@
         for (auto iter = spec->types; iter != iter_end; ++iter) {
           ResTable_config this_config;
           this_config.copyFromDtoH((*iter)->config);
-          if (this_config.match(configuration_)) {
+          if (!filter_incompatible_configs || this_config.match(configuration_)) {
             group.configurations.push_back(this_config);
             group.types.push_back(*iter);
           }
diff --git a/tools/aapt2/ConfigDescription.cpp b/libs/androidfw/ConfigDescription.cpp
similarity index 98%
rename from tools/aapt2/ConfigDescription.cpp
rename to libs/androidfw/ConfigDescription.cpp
index f621660..1f3a89e 100644
--- a/tools/aapt2/ConfigDescription.cpp
+++ b/libs/androidfw/ConfigDescription.cpp
@@ -14,22 +14,16 @@
  * limitations under the License.
  */
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
+#include "androidfw/Locale.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/StringPiece.h"
+#include "androidfw/Util.h"
 
 #include <string>
 #include <vector>
 
-#include "androidfw/ResourceTypes.h"
-#include "androidfw/StringPiece.h"
-
-#include "Locale.h"
-#include "SdkConstants.h"
-#include "util/Util.h"
-
-using android::ResTable_config;
-using android::StringPiece;
-
-namespace aapt {
+namespace android {
 
 static const char* kWildcardName = "any";
 
@@ -883,7 +877,7 @@
 }
 
 std::string ConfigDescription::to_string() const {
-  const android::String8 str = toString();
+  const String8 str = toString();
   return std::string(str.string(), str.size());
 }
 
@@ -996,4 +990,4 @@
   return !ConflictsWith(o) && !Dominates(o) && !o.Dominates(*this);
 }
 
-}  // namespace aapt
+}  // namespace android
diff --git a/libs/androidfw/LoadedArsc.cpp b/libs/androidfw/LoadedArsc.cpp
index c2740c9..68d216d 100644
--- a/libs/androidfw/LoadedArsc.cpp
+++ b/libs/androidfw/LoadedArsc.cpp
@@ -203,6 +203,39 @@
   return true;
 }
 
+LoadedPackage::iterator::iterator(const LoadedPackage* lp, size_t ti, size_t ei)
+    : loadedPackage_(lp),
+      typeIndex_(ti),
+      entryIndex_(ei),
+      typeIndexEnd_(lp->resource_ids_.size() + 1) {
+  while (typeIndex_ < typeIndexEnd_ && loadedPackage_->resource_ids_[typeIndex_] == 0) {
+    typeIndex_++;
+  }
+}
+
+LoadedPackage::iterator& LoadedPackage::iterator::operator++() {
+  while (typeIndex_ < typeIndexEnd_) {
+    if (entryIndex_ + 1 < loadedPackage_->resource_ids_[typeIndex_]) {
+      entryIndex_++;
+      break;
+    }
+    entryIndex_ = 0;
+    typeIndex_++;
+    if (typeIndex_ < typeIndexEnd_ && loadedPackage_->resource_ids_[typeIndex_] != 0) {
+      break;
+    }
+  }
+  return *this;
+}
+
+uint32_t LoadedPackage::iterator::operator*() const {
+  if (typeIndex_ >= typeIndexEnd_) {
+    return 0;
+  }
+  return make_resid(loadedPackage_->package_id_, typeIndex_ + loadedPackage_->type_id_offset_,
+          entryIndex_);
+}
+
 const ResTable_entry* LoadedPackage::GetEntry(const ResTable_type* type_chunk,
                                               uint16_t entry_index) {
   uint32_t entry_offset = GetEntryOffset(type_chunk, entry_index);
@@ -488,6 +521,7 @@
         std::unique_ptr<TypeSpecPtrBuilder>& builder_ptr = type_builder_map[type_spec->id - 1];
         if (builder_ptr == nullptr) {
           builder_ptr = util::make_unique<TypeSpecPtrBuilder>(type_spec, idmap_entry_header);
+          loaded_package->resource_ids_.set(type_spec->id, entry_count);
         } else {
           LOG(WARNING) << StringPrintf("RES_TABLE_TYPE_SPEC_TYPE already defined for ID %02x",
                                        type_spec->id);
diff --git a/tools/aapt2/Locale.cpp b/libs/androidfw/Locale.cpp
similarity index 98%
rename from tools/aapt2/Locale.cpp
rename to libs/androidfw/Locale.cpp
index d81921f..2870066 100644
--- a/tools/aapt2/Locale.cpp
+++ b/libs/androidfw/Locale.cpp
@@ -14,7 +14,8 @@
  * limitations under the License.
  */
 
-#include "Locale.h"
+#include "androidfw/Locale.h"
+#include "androidfw/Util.h"
 
 #include <ctype.h>
 
@@ -22,12 +23,10 @@
 #include <string>
 #include <vector>
 
-#include "util/Util.h"
-
 using ::android::ResTable_config;
 using ::android::StringPiece;
 
-namespace aapt {
+namespace android {
 
 void LocaleValue::set_language(const char* language_chars) {
   size_t i = 0;
@@ -258,4 +257,4 @@
   }
 }
 
-}  // namespace aapt
+}  // namespace android
diff --git a/libs/androidfw/PosixUtils.cpp b/libs/androidfw/PosixUtils.cpp
new file mode 100644
index 0000000..df0dd7c
--- /dev/null
+++ b/libs/androidfw/PosixUtils.cpp
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+#ifdef _WIN32
+// nothing to see here
+#else
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "android-base/logging.h"
+
+#include "androidfw/PosixUtils.h"
+
+namespace {
+
+std::unique_ptr<std::string> ReadFile(int fd) {
+  std::unique_ptr<std::string> str(new std::string());
+  char buf[1024];
+  ssize_t r;
+  while ((r = read(fd, buf, sizeof(buf))) > 0) {
+    str->append(buf, r);
+  }
+  if (r != 0) {
+    return nullptr;
+  }
+  return str;
+}
+
+}
+
+namespace android {
+namespace util {
+
+std::unique_ptr<ProcResult> ExecuteBinary(const std::vector<std::string>& argv) {
+  int stdout[2];  // stdout[0] read, stdout[1] write
+  if (pipe(stdout) != 0) {
+    PLOG(ERROR) << "pipe";
+    return nullptr;
+  }
+
+  int stderr[2];  // stdout[0] read, stdout[1] write
+  if (pipe(stderr) != 0) {
+    PLOG(ERROR) << "pipe";
+    close(stdout[0]);
+    close(stdout[1]);
+    return nullptr;
+  }
+
+  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();
+  }
+  argv0[argv.size()] = nullptr;
+  switch (fork()) {
+    case -1: // error
+      free(argv0);
+      PLOG(ERROR) << "fork";
+      return nullptr;
+    case 0: // child
+      close(stdout[0]);
+      if (dup2(stdout[1], STDOUT_FILENO) == -1) {
+        abort();
+      }
+      close(stderr[0]);
+      if (dup2(stderr[1], STDERR_FILENO) == -1) {
+        abort();
+      }
+      execvp(argv0[0], const_cast<char* const*>(argv0));
+      PLOG(ERROR) << "execv";
+      abort();
+    default: // parent
+      free(argv0);
+      close(stdout[1]);
+      close(stderr[1]);
+      int status;
+      wait(&status);
+      if (!WIFEXITED(status)) {
+          return nullptr;
+      }
+      std::unique_ptr<ProcResult> result(new ProcResult());
+      result->status = status;
+      const auto out = ReadFile(stdout[0]);
+      result->stdout = out ? *out : "";
+      close(stdout[0]);
+      const auto err = ReadFile(stderr[0]);
+      result->stderr = err ? *err : "";
+      close(stderr[0]);
+      return result;
+  }
+}
+
+} // namespace util
+} // namespace android
+#endif
diff --git a/libs/androidfw/Util.cpp b/libs/androidfw/Util.cpp
index 575cd18..59c9d64 100644
--- a/libs/androidfw/Util.cpp
+++ b/libs/androidfw/Util.cpp
@@ -16,6 +16,7 @@
 
 #include "androidfw/Util.h"
 
+#include <algorithm>
 #include <string>
 
 #include "utils/ByteOrder.h"
@@ -67,5 +68,28 @@
   return utf8;
 }
 
+static std::vector<std::string> SplitAndTransform(
+    const StringPiece& str, char sep, const std::function<char(char)>& f) {
+  std::vector<std::string> parts;
+  const StringPiece::const_iterator end = std::end(str);
+  StringPiece::const_iterator start = std::begin(str);
+  StringPiece::const_iterator current;
+  do {
+    current = std::find(start, end, sep);
+    parts.emplace_back(str.substr(start, current).to_string());
+    if (f) {
+      std::string& part = parts.back();
+      std::transform(part.begin(), part.end(), part.begin(), f);
+    }
+    start = current + 1;
+  } while (current != end);
+  return parts;
+}
+
+std::vector<std::string> SplitAndLowercase(const StringPiece& str, char sep) {
+  return SplitAndTransform(str, sep, ::tolower);
+}
+
+
 } // namespace util
 } // namespace android
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index 69702e3..db2d038 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -27,6 +27,9 @@
 #include "androidfw/LoadedArsc.h"
 #include "androidfw/misc.h"
 
+struct ZipArchive;
+typedef ZipArchive* ZipArchiveHandle;
+
 namespace android {
 
 class LoadedIdmap;
@@ -88,9 +91,9 @@
   // Creates an Asset from any file on the file system.
   static std::unique_ptr<Asset> CreateAssetFromFile(const std::string& path);
 
-  ApkAssets(void* unmanaged_handle, const std::string& path);
+  ApkAssets(ZipArchiveHandle unmanaged_handle, const std::string& path);
 
-  using ZipArchivePtr = std::unique_ptr<void, void(*)(void*)>;
+  using ZipArchivePtr = std::unique_ptr<ZipArchive, void(*)(ZipArchiveHandle)>;
 
   ZipArchivePtr zip_handle_;
   const std::string path_;
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index ad31f69..2f0ee01 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -96,7 +96,12 @@
   // Only pass invalidate_caches=false when it is known that the structure
   // change in ApkAssets is due to a safe addition of resources with completely
   // new resource IDs.
-  bool SetApkAssets(const std::vector<const ApkAssets*>& apk_assets, bool invalidate_caches = true);
+  //
+  // Only pass in filter_incompatible_configs=false when you want to load all
+  // configurations (including incompatible ones) such as when constructing an
+  // idmap.
+  bool SetApkAssets(const std::vector<const ApkAssets*>& apk_assets, bool invalidate_caches = true,
+          bool filter_incompatible_configs = true);
 
   inline const std::vector<const ApkAssets*> GetApkAssets() const {
     return apk_assets_;
@@ -274,7 +279,7 @@
 
   // Triggers the re-construction of lists of types that match the set configuration.
   // This should always be called when mutating the AssetManager's configuration or ApkAssets set.
-  void RebuildFilterList();
+  void RebuildFilterList(bool filter_incompatible_configs = true);
 
   // AssetManager2::GetBag(resid) wraps this function to track which resource ids have already
   // been seen while traversing bag parents.
diff --git a/tools/aapt2/ConfigDescription.h b/libs/androidfw/include/androidfw/ConfigDescription.h
similarity index 87%
rename from tools/aapt2/ConfigDescription.h
rename to libs/androidfw/include/androidfw/ConfigDescription.h
index b46a503..29424c4 100644
--- a/tools/aapt2/ConfigDescription.h
+++ b/libs/androidfw/include/androidfw/ConfigDescription.h
@@ -14,21 +14,52 @@
  * limitations under the License.
  */
 
-#ifndef AAPT_CONFIG_DESCRIPTION_H
-#define AAPT_CONFIG_DESCRIPTION_H
+#ifndef ANDROIDFW_CONFIG_DESCRIPTION_H
+#define ANDROIDFW_CONFIG_DESCRIPTION_H
 
 #include <ostream>
 
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
 
-namespace aapt {
+namespace android {
+
+using ApiVersion = int;
+
+enum : ApiVersion {
+  SDK_CUPCAKE = 3,
+  SDK_DONUT = 4,
+  SDK_ECLAIR = 5,
+  SDK_ECLAIR_0_1 = 6,
+  SDK_ECLAIR_MR1 = 7,
+  SDK_FROYO = 8,
+  SDK_GINGERBREAD = 9,
+  SDK_GINGERBREAD_MR1 = 10,
+  SDK_HONEYCOMB = 11,
+  SDK_HONEYCOMB_MR1 = 12,
+  SDK_HONEYCOMB_MR2 = 13,
+  SDK_ICE_CREAM_SANDWICH = 14,
+  SDK_ICE_CREAM_SANDWICH_MR1 = 15,
+  SDK_JELLY_BEAN = 16,
+  SDK_JELLY_BEAN_MR1 = 17,
+  SDK_JELLY_BEAN_MR2 = 18,
+  SDK_KITKAT = 19,
+  SDK_KITKAT_WATCH = 20,
+  SDK_LOLLIPOP = 21,
+  SDK_LOLLIPOP_MR1 = 22,
+  SDK_MARSHMALLOW = 23,
+  SDK_NOUGAT = 24,
+  SDK_NOUGAT_MR1 = 25,
+  SDK_O = 26,
+  SDK_O_MR1 = 27,
+  SDK_P = 28,
+};
 
 /*
  * Subclass of ResTable_config that adds convenient
  * initialization and comparison methods.
  */
-struct ConfigDescription : public android::ResTable_config {
+struct ConfigDescription : public ResTable_config {
   /**
    * Returns an immutable default config.
    */
@@ -180,6 +211,6 @@
   return out << o.toString().string();
 }
 
-}  // namespace aapt
+}  // namespace android
 
-#endif  // AAPT_CONFIG_DESCRIPTION_H
+#endif  // ANDROIDFW_CONFIG_DESCRIPTION_H
diff --git a/libs/androidfw/include/androidfw/LoadedArsc.h b/libs/androidfw/include/androidfw/LoadedArsc.h
index 35ae5fc..349b379 100644
--- a/libs/androidfw/include/androidfw/LoadedArsc.h
+++ b/libs/androidfw/include/androidfw/LoadedArsc.h
@@ -78,6 +78,55 @@
 
 class LoadedPackage {
  public:
+  class iterator {
+   public:
+    iterator& operator=(const iterator& rhs) {
+      loadedPackage_ = rhs.loadedPackage_;
+      typeIndex_ = rhs.typeIndex_;
+      entryIndex_ = rhs.entryIndex_;
+      return *this;
+    }
+
+    bool operator==(const iterator& rhs) const {
+      return loadedPackage_ == rhs.loadedPackage_ &&
+             typeIndex_ == rhs.typeIndex_ &&
+             entryIndex_ == rhs.entryIndex_;
+    }
+
+    bool operator!=(const iterator& rhs) const {
+      return !(*this == rhs);
+    }
+
+    iterator operator++(int) {
+      size_t prevTypeIndex_ = typeIndex_;
+      size_t prevEntryIndex_ = entryIndex_;
+      operator++();
+      return iterator(loadedPackage_, prevTypeIndex_, prevEntryIndex_);
+    }
+
+    iterator& operator++();
+
+    uint32_t operator*() const;
+
+   private:
+    friend class LoadedPackage;
+
+    iterator(const LoadedPackage* lp, size_t ti, size_t ei);
+
+    const LoadedPackage* loadedPackage_;
+    size_t typeIndex_;
+    size_t entryIndex_;
+    const size_t typeIndexEnd_;  // STL style end, so one past the last element
+  };
+
+  iterator begin() const {
+    return iterator(this, 0, 0);
+  }
+
+  iterator end() const {
+    return iterator(this, resource_ids_.size() + 1, 0);
+  }
+
   static std::unique_ptr<const LoadedPackage> Load(const Chunk& chunk,
                                                    const LoadedIdmap* loaded_idmap, bool system,
                                                    bool load_as_shared_library);
@@ -182,6 +231,7 @@
   bool overlay_ = false;
 
   ByteBucketArray<TypeSpecPtr> type_specs_;
+  ByteBucketArray<uint32_t> resource_ids_;
   std::vector<DynamicPackageEntry> dynamic_package_map_;
 };
 
diff --git a/tools/aapt2/Locale.h b/libs/androidfw/include/androidfw/Locale.h
similarity index 94%
rename from tools/aapt2/Locale.h
rename to libs/androidfw/include/androidfw/Locale.h
index 6d8b598..484ed79 100644
--- a/tools/aapt2/Locale.h
+++ b/libs/androidfw/include/androidfw/Locale.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef AAPT_LOCALE_VALUE_H
-#define AAPT_LOCALE_VALUE_H
+#ifndef ANDROIDFW_LOCALE_VALUE_H
+#define ANDROIDFW_LOCALE_VALUE_H
 
 #include <string>
 #include <vector>
@@ -23,7 +23,7 @@
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
 
-namespace aapt {
+namespace android {
 
 /**
  * A convenience class to build and parse locales.
@@ -112,6 +112,6 @@
   return compare(o) > 0;
 }
 
-}  // namespace aapt
+}  // namespace android
 
-#endif  // AAPT_LOCALE_VALUE_H
+#endif  // ANDROIDFW_LOCALE_VALUE_H
diff --git a/libs/androidfw/include/androidfw/PosixUtils.h b/libs/androidfw/include/androidfw/PosixUtils.h
new file mode 100644
index 0000000..8fc3ee2
--- /dev/null
+++ b/libs/androidfw/include/androidfw/PosixUtils.h
@@ -0,0 +1,36 @@
+/*
+ * 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 <memory>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace util {
+
+struct ProcResult {
+  int status;
+  std::string stdout;
+  std::string stderr;
+};
+
+// Fork, exec and wait for an external process. Return nullptr if the process could not be launched,
+// otherwise a ProcResult containing the external process' exit status and captured stdout and
+// stderr.
+std::unique_ptr<ProcResult> ExecuteBinary(const std::vector<std::string>& argv);
+
+} // namespace util
+} // namespace android
diff --git a/libs/androidfw/include/androidfw/Util.h b/libs/androidfw/include/androidfw/Util.h
index 6c9eee0..10d088e 100644
--- a/libs/androidfw/include/androidfw/Util.h
+++ b/libs/androidfw/include/androidfw/Util.h
@@ -19,6 +19,7 @@
 
 #include <cstdlib>
 #include <memory>
+#include <vector>
 
 #include "android-base/macros.h"
 
@@ -116,6 +117,8 @@
 // Converts a UTF-16 string to a UTF-8 string.
 std::string Utf16ToUtf8(const StringPiece16& utf16);
 
+std::vector<std::string> SplitAndLowercase(const android::StringPiece& str, char sep);
+
 }  // namespace util
 }  // namespace android
 
diff --git a/libs/androidfw/include/androidfw/ZipFileRO.h b/libs/androidfw/include/androidfw/ZipFileRO.h
index 03154d0..c221e3b 100644
--- a/libs/androidfw/include/androidfw/ZipFileRO.h
+++ b/libs/androidfw/include/androidfw/ZipFileRO.h
@@ -41,7 +41,8 @@
 #include <unistd.h>
 #include <time.h>
 
-typedef void* ZipArchiveHandle;
+struct ZipArchive;
+typedef ZipArchive* ZipArchiveHandle;
 
 namespace android {
 
diff --git a/tools/aapt2/ConfigDescription_test.cpp b/libs/androidfw/tests/ConfigDescription_test.cpp
similarity index 93%
rename from tools/aapt2/ConfigDescription_test.cpp
rename to libs/androidfw/tests/ConfigDescription_test.cpp
index 1f351bf..ce7f805 100644
--- a/tools/aapt2/ConfigDescription_test.cpp
+++ b/libs/androidfw/tests/ConfigDescription_test.cpp
@@ -14,18 +14,16 @@
  * limitations under the License.
  */
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
+#include "androidfw/StringPiece.h"
+
+#include "android-base/logging.h"
+
+#include "gtest/gtest.h"
 
 #include <string>
 
-#include "androidfw/StringPiece.h"
-
-#include "SdkConstants.h"
-#include "test/Test.h"
-
-using android::StringPiece;
-
-namespace aapt {
+namespace android {
 
 static ::testing::AssertionResult TestParse(
     const StringPiece& input, ConfigDescription* config = nullptr) {
@@ -140,9 +138,13 @@
   EXPECT_EQ(std::string("vrheadset-v26"), config.toString().string());
 }
 
-TEST(ConfigDescriptionTest, RangeQualifiersDoNotConflict) {
-  using test::ParseConfigOrDie;
+static inline ConfigDescription ParseConfigOrDie(const android::StringPiece& str) {
+  ConfigDescription config;
+  CHECK(ConfigDescription::Parse(str, &config)) << "invalid configuration: " << str;
+  return config;
+}
 
+TEST(ConfigDescriptionTest, RangeQualifiersDoNotConflict) {
   EXPECT_FALSE(ParseConfigOrDie("large").ConflictsWith(ParseConfigOrDie("normal-land")));
   EXPECT_FALSE(ParseConfigOrDie("long-hdpi").ConflictsWith(ParseConfigOrDie("xhdpi")));
   EXPECT_FALSE(ParseConfigOrDie("sw600dp").ConflictsWith(ParseConfigOrDie("sw700dp")));
@@ -152,4 +154,4 @@
   EXPECT_FALSE(ParseConfigOrDie("600x400").ConflictsWith(ParseConfigOrDie("300x200")));
 }
 
-}  // namespace aapt
+}  // namespace android
diff --git a/libs/androidfw/tests/LoadedArsc_test.cpp b/libs/androidfw/tests/LoadedArsc_test.cpp
index cae632d..ffa4836 100644
--- a/libs/androidfw/tests/LoadedArsc_test.cpp
+++ b/libs/androidfw/tests/LoadedArsc_test.cpp
@@ -278,4 +278,52 @@
 // sizeof(Res_value) might not be backwards compatible.
 TEST(LoadedArscTest, LoadingShouldBeForwardsAndBackwardsCompatible) { ASSERT_TRUE(false); }
 
+TEST(LoadedArscTest, ResourceIdentifierIterator) {
+  std::string contents;
+  ASSERT_TRUE(
+      ReadFileFromZipToString(GetTestDataPath() + "/basic/basic.apk", "resources.arsc", &contents));
+
+  std::unique_ptr<const LoadedArsc> loaded_arsc = LoadedArsc::Load(StringPiece(contents));
+  ASSERT_NE(nullptr, loaded_arsc);
+
+  const std::vector<std::unique_ptr<const LoadedPackage>>& packages = loaded_arsc->GetPackages();
+  ASSERT_EQ(1u, packages.size());
+  EXPECT_EQ(std::string("com.android.basic"), packages[0]->GetPackageName());
+
+  const auto& loaded_package = packages[0];
+  auto iter = loaded_package->begin();
+  auto end = loaded_package->end();
+
+  ASSERT_NE(end, iter);
+  ASSERT_EQ(0x7f010000u, *iter++);
+  ASSERT_EQ(0x7f010001u, *iter++);
+  ASSERT_EQ(0x7f020000u, *iter++);
+  ASSERT_EQ(0x7f020001u, *iter++);
+  ASSERT_EQ(0x7f030000u, *iter++);
+  ASSERT_EQ(0x7f030001u, *iter++);
+  ASSERT_EQ(0x7f030002u, *iter++);  // note: string without default, excluded by aapt2 dump
+  ASSERT_EQ(0x7f040000u, *iter++);
+  ASSERT_EQ(0x7f040001u, *iter++);
+  ASSERT_EQ(0x7f040002u, *iter++);
+  ASSERT_EQ(0x7f040003u, *iter++);
+  ASSERT_EQ(0x7f040004u, *iter++);
+  ASSERT_EQ(0x7f040005u, *iter++);
+  ASSERT_EQ(0x7f040006u, *iter++);
+  ASSERT_EQ(0x7f040007u, *iter++);
+  ASSERT_EQ(0x7f040008u, *iter++);
+  ASSERT_EQ(0x7f040009u, *iter++);
+  ASSERT_EQ(0x7f04000au, *iter++);
+  ASSERT_EQ(0x7f04000bu, *iter++);
+  ASSERT_EQ(0x7f04000cu, *iter++);
+  ASSERT_EQ(0x7f04000du, *iter++);
+  ASSERT_EQ(0x7f050000u, *iter++);
+  ASSERT_EQ(0x7f050001u, *iter++);
+  ASSERT_EQ(0x7f060000u, *iter++);
+  ASSERT_EQ(0x7f070000u, *iter++);
+  ASSERT_EQ(0x7f070001u, *iter++);
+  ASSERT_EQ(0x7f070002u, *iter++);
+  ASSERT_EQ(0x7f070003u, *iter++);
+  ASSERT_EQ(end, iter);
+}
+
 }  // namespace android
diff --git a/tools/aapt2/Locale_test.cpp b/libs/androidfw/tests/Locale_test.cpp
similarity index 96%
rename from tools/aapt2/Locale_test.cpp
rename to libs/androidfw/tests/Locale_test.cpp
index 68b4cae..6b2ef5f 100644
--- a/tools/aapt2/Locale_test.cpp
+++ b/libs/androidfw/tests/Locale_test.cpp
@@ -14,15 +14,14 @@
  * limitations under the License.
  */
 
-#include "Locale.h"
+#include "androidfw/Locale.h"
+#include "androidfw/Util.h"
 
 #include <string>
 
 #include "gtest/gtest.h"
 
-#include "util/Util.h"
-
-namespace aapt {
+namespace android {
 
 static ::testing::AssertionResult TestLanguage(const char* input,
                                                const char* lang) {
@@ -93,4 +92,4 @@
   EXPECT_TRUE(TestLanguageRegion("fr-rCA", "fr", "CA"));
 }
 
-}  // namespace aapt
+}  // namespace android
diff --git a/libs/androidfw/tests/PosixUtils_test.cpp b/libs/androidfw/tests/PosixUtils_test.cpp
new file mode 100644
index 0000000..cf97f87
--- /dev/null
+++ b/libs/androidfw/tests/PosixUtils_test.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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 <utility>
+
+#include "androidfw/PosixUtils.h"
+
+#include "TestHelpers.h"
+
+using ::testing::IsNull;
+using ::testing::NotNull;
+
+namespace android {
+namespace util {
+
+TEST(PosixUtilsTest, AbsolutePathToBinary) {
+  const auto result = ExecuteBinary({"/bin/date", "--help"});
+  ASSERT_THAT(result, NotNull());
+  ASSERT_EQ(result->status, 0);
+  ASSERT_EQ(result->stdout.find("usage: date "), 0);
+}
+
+TEST(PosixUtilsTest, RelativePathToBinary) {
+  const auto result = ExecuteBinary({"date", "--help"});
+  ASSERT_THAT(result, NotNull());
+  ASSERT_EQ(result->status, 0);
+  ASSERT_EQ(result->stdout.find("usage: date "), 0);
+}
+
+TEST(PosixUtilsTest, BadParameters) {
+  const auto result = ExecuteBinary({"/bin/date", "--this-parameter-is-not-supported"});
+  ASSERT_THAT(result, NotNull());
+  ASSERT_NE(result->status, 0);
+}
+
+TEST(PosixUtilsTest, NoSuchBinary) {
+  const auto result = ExecuteBinary({"/this/binary/does/not/exist"});
+  ASSERT_THAT(result, IsNull());
+}
+
+} // android
+} // util
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 494e513..f0053a4 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -61,6 +61,7 @@
     shared_libs: [
         "liblog",
         "libcutils",
+        "libstatslog",
         "libutils",
         "libEGL",
         "libGLESv2",
@@ -201,9 +202,7 @@
         "AnimationContext.cpp",
         "Animator.cpp",
         "AnimatorManager.cpp",
-        "CanvasState.cpp",
         "CanvasTransform.cpp",
-        "ClipArea.cpp",
         "DamageAccumulator.cpp",
         "DeferredLayerUpdater.cpp",
         "DeviceInfo.cpp",
@@ -226,14 +225,15 @@
         "RecordingCanvas.cpp",
         "RenderNode.cpp",
         "RenderProperties.cpp",
-        "ResourceCache.cpp",
         "SkiaCanvas.cpp",
-        "Snapshot.cpp",
         "TreeInfo.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,
     },
@@ -307,8 +307,6 @@
         "tests/unit/main.cpp",
         "tests/unit/CacheManagerTests.cpp",
         "tests/unit/CanvasContextTests.cpp",
-        "tests/unit/CanvasStateTests.cpp",
-        "tests/unit/ClipAreaTests.cpp",
         "tests/unit/DamageAccumulatorTests.cpp",
         "tests/unit/DeferredLayerUpdaterTests.cpp",
         "tests/unit/FatVectorTests.cpp",
@@ -327,7 +325,6 @@
         "tests/unit/SkiaPipelineTests.cpp",
         "tests/unit/SkiaRenderPropertiesTests.cpp",
         "tests/unit/SkiaCanvasTests.cpp",
-        "tests/unit/SnapshotTests.cpp",
         "tests/unit/StringUtilsTests.cpp",
         "tests/unit/TestUtilsTests.cpp",
         "tests/unit/ThreadBaseTests.cpp",
diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp
deleted file mode 100644
index d18c4ab..0000000
--- a/libs/hwui/CanvasState.cpp
+++ /dev/null
@@ -1,284 +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.
- */
-
-#include "CanvasState.h"
-#include "hwui/Canvas.h"
-#include "utils/MathUtils.h"
-
-namespace android {
-namespace uirenderer {
-
-CanvasState::CanvasState(CanvasStateClient& renderer)
-        : mWidth(-1), mHeight(-1), mSaveCount(1), mCanvas(renderer), mSnapshot(&mFirstSnapshot) {}
-
-CanvasState::~CanvasState() {
-    // First call freeSnapshot on all but mFirstSnapshot
-    // to invoke all the dtors
-    freeAllSnapshots();
-
-    // Now actually release the memory
-    while (mSnapshotPool) {
-        void* temp = mSnapshotPool;
-        mSnapshotPool = mSnapshotPool->previous;
-        free(temp);
-    }
-}
-
-void CanvasState::initializeRecordingSaveStack(int viewportWidth, int viewportHeight) {
-    if (mWidth != viewportWidth || mHeight != viewportHeight) {
-        mWidth = viewportWidth;
-        mHeight = viewportHeight;
-        mFirstSnapshot.initializeViewport(viewportWidth, viewportHeight);
-        mCanvas.onViewportInitialized();
-    }
-
-    freeAllSnapshots();
-    mSnapshot = allocSnapshot(&mFirstSnapshot, SaveFlags::MatrixClip);
-    mSnapshot->setRelativeLightCenter(Vector3());
-    mSaveCount = 1;
-}
-
-void CanvasState::initializeSaveStack(int viewportWidth, int viewportHeight, float clipLeft,
-                                      float clipTop, float clipRight, float clipBottom,
-                                      const Vector3& lightCenter) {
-    if (mWidth != viewportWidth || mHeight != viewportHeight) {
-        mWidth = viewportWidth;
-        mHeight = viewportHeight;
-        mFirstSnapshot.initializeViewport(viewportWidth, viewportHeight);
-        mCanvas.onViewportInitialized();
-    }
-
-    freeAllSnapshots();
-    mSnapshot = allocSnapshot(&mFirstSnapshot, SaveFlags::MatrixClip);
-    mSnapshot->setClip(clipLeft, clipTop, clipRight, clipBottom);
-    mSnapshot->fbo = mCanvas.getTargetFbo();
-    mSnapshot->setRelativeLightCenter(lightCenter);
-    mSaveCount = 1;
-}
-
-Snapshot* CanvasState::allocSnapshot(Snapshot* previous, int savecount) {
-    void* memory;
-    if (mSnapshotPool) {
-        memory = mSnapshotPool;
-        mSnapshotPool = mSnapshotPool->previous;
-        mSnapshotPoolCount--;
-    } else {
-        memory = malloc(sizeof(Snapshot));
-    }
-    return new (memory) Snapshot(previous, savecount);
-}
-
-void CanvasState::freeSnapshot(Snapshot* snapshot) {
-    snapshot->~Snapshot();
-    // Arbitrary number, just don't let this grown unbounded
-    if (mSnapshotPoolCount > 10) {
-        free((void*)snapshot);
-    } else {
-        snapshot->previous = mSnapshotPool;
-        mSnapshotPool = snapshot;
-        mSnapshotPoolCount++;
-    }
-}
-
-void CanvasState::freeAllSnapshots() {
-    while (mSnapshot != &mFirstSnapshot) {
-        Snapshot* temp = mSnapshot;
-        mSnapshot = mSnapshot->previous;
-        freeSnapshot(temp);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Save (layer)
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Guaranteed to save without side-effects
- *
- * This approach, here and in restoreSnapshot(), allows subclasses to directly manipulate the save
- * stack, and ensures restoreToCount() doesn't call back into subclass overrides.
- */
-int CanvasState::saveSnapshot(int flags) {
-    mSnapshot = allocSnapshot(mSnapshot, flags);
-    return mSaveCount++;
-}
-
-int CanvasState::save(int flags) {
-    return saveSnapshot(flags);
-}
-
-/**
- * Guaranteed to restore without side-effects.
- */
-void CanvasState::restoreSnapshot() {
-    Snapshot* toRemove = mSnapshot;
-    Snapshot* toRestore = mSnapshot->previous;
-
-    mSaveCount--;
-    mSnapshot = toRestore;
-
-    // subclass handles restore implementation
-    mCanvas.onSnapshotRestored(*toRemove, *toRestore);
-
-    freeSnapshot(toRemove);
-}
-
-void CanvasState::restore() {
-    if (mSaveCount > 1) {
-        restoreSnapshot();
-    }
-}
-
-void CanvasState::restoreToCount(int saveCount) {
-    if (saveCount < 1) saveCount = 1;
-
-    while (mSaveCount > saveCount) {
-        restoreSnapshot();
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Matrix
-///////////////////////////////////////////////////////////////////////////////
-
-void CanvasState::getMatrix(SkMatrix* matrix) const {
-    mSnapshot->transform->copyTo(*matrix);
-}
-
-void CanvasState::translate(float dx, float dy, float dz) {
-    mSnapshot->transform->translate(dx, dy, dz);
-}
-
-void CanvasState::rotate(float degrees) {
-    mSnapshot->transform->rotate(degrees, 0.0f, 0.0f, 1.0f);
-}
-
-void CanvasState::scale(float sx, float sy) {
-    mSnapshot->transform->scale(sx, sy, 1.0f);
-}
-
-void CanvasState::skew(float sx, float sy) {
-    mSnapshot->transform->skew(sx, sy);
-}
-
-void CanvasState::setMatrix(const SkMatrix& matrix) {
-    mSnapshot->transform->load(matrix);
-}
-
-void CanvasState::setMatrix(const Matrix4& matrix) {
-    *(mSnapshot->transform) = matrix;
-}
-
-void CanvasState::concatMatrix(const SkMatrix& matrix) {
-    mat4 transform(matrix);
-    mSnapshot->transform->multiply(transform);
-}
-
-void CanvasState::concatMatrix(const Matrix4& matrix) {
-    mSnapshot->transform->multiply(matrix);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Clip
-///////////////////////////////////////////////////////////////////////////////
-
-bool CanvasState::clipRect(float left, float top, float right, float bottom, SkClipOp op) {
-    mSnapshot->clip(Rect(left, top, right, bottom), op);
-    return !mSnapshot->clipIsEmpty();
-}
-
-bool CanvasState::clipPath(const SkPath* path, SkClipOp op) {
-    mSnapshot->clipPath(*path, op);
-    return !mSnapshot->clipIsEmpty();
-}
-
-void CanvasState::setClippingOutline(LinearAllocator& allocator, const Outline* outline) {
-    Rect bounds;
-    float radius;
-    if (!outline->getAsRoundRect(&bounds, &radius)) return;  // only RR supported
-
-    bool outlineIsRounded = MathUtils::isPositive(radius);
-    if (!outlineIsRounded || currentTransform()->isSimple()) {
-        // TODO: consider storing this rect separately, so that this can't be replaced with clip ops
-        clipRect(bounds.left, bounds.top, bounds.right, bounds.bottom, SkClipOp::kIntersect);
-    }
-    if (outlineIsRounded) {
-        setClippingRoundRect(allocator, bounds, radius, false);
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Quick Rejection
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Calculates whether content drawn within the passed bounds would be outside of, or intersect with
- * the clipRect. Does not modify the scissor.
- *
- * @param clipRequired if not null, will be set to true if element intersects clip
- *         (and wasn't rejected)
- *
- * @param snapOut if set, the geometry will be treated as having an AA ramp.
- *         See Rect::snapGeometryToPixelBoundaries()
- */
-bool CanvasState::calculateQuickRejectForScissor(float left, float top, float right, float bottom,
-                                                 bool* clipRequired, bool* roundRectClipRequired,
-                                                 bool snapOut) const {
-    if (bottom <= top || right <= left) {
-        return true;
-    }
-
-    Rect r(left, top, right, bottom);
-    currentTransform()->mapRect(r);
-    r.snapGeometryToPixelBoundaries(snapOut);
-
-    Rect clipRect(currentRenderTargetClip());
-    clipRect.snapToPixelBoundaries();
-
-    if (!clipRect.intersects(r)) return true;
-
-    // clip is required if geometry intersects clip rect
-    if (clipRequired) {
-        *clipRequired = !clipRect.contains(r);
-    }
-
-    // round rect clip is required if RR clip exists, and geometry intersects its corners
-    if (roundRectClipRequired) {
-        *roundRectClipRequired = mSnapshot->roundRectClipState != nullptr &&
-                                 mSnapshot->roundRectClipState->areaRequiresRoundRectClip(r);
-    }
-    return false;
-}
-
-bool CanvasState::quickRejectConservative(float left, float top, float right, float bottom) const {
-    if (bottom <= top || right <= left) {
-        return true;
-    }
-
-    Rect r(left, top, right, bottom);
-    currentTransform()->mapRect(r);
-    r.roundOut();  // rounded out to be conservative
-
-    Rect clipRect(currentRenderTargetClip());
-    clipRect.snapToPixelBoundaries();
-
-    if (!clipRect.intersects(r)) return true;
-
-    return false;
-}
-
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/CanvasState.h b/libs/hwui/CanvasState.h
deleted file mode 100644
index 9ac35ff..0000000
--- a/libs/hwui/CanvasState.h
+++ /dev/null
@@ -1,195 +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.
- */
-
-#pragma once
-
-#include "Snapshot.h"
-
-#include <SkClipOp.h>
-#include <SkMatrix.h>
-#include <SkPath.h>
-#include <SkRegion.h>
-
-namespace android {
-namespace uirenderer {
-
-/**
- * Abstract base class for any class containing CanvasState.
- * Defines three mandatory callbacks.
- */
-class CanvasStateClient {
-public:
-    CanvasStateClient() {}
-    virtual ~CanvasStateClient() {}
-
-    /**
-     * Callback allowing embedder to take actions in the middle of a
-     * setViewport() call.
-     */
-    virtual void onViewportInitialized() = 0;
-
-    /**
-     * Callback allowing embedder to take actions in the middle of a
-     * restore() call.  May be called several times sequentially.
-     */
-    virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) = 0;
-
-    /**
-     * Allows subclasses to control what value is stored in snapshot's
-     * fbo field in * initializeSaveStack.
-     */
-    virtual GLuint getTargetFbo() const = 0;
-
-};  // class CanvasStateClient
-
-/**
- * Implements Canvas state methods on behalf of Renderers.
- *
- * Manages the Snapshot stack, implementing matrix, save/restore, and clipping methods in the
- * Renderer interface. Drawing and recording classes that include a CanvasState will have
- * different use cases:
- *
- * Drawing code maintaining canvas state (e.g. FrameBuilder) can query attributes (such as
- * transform) or hook into changes (e.g. save/restore) with minimal surface area for manipulating
- * the stack itself.
- *
- * Recording code maintaining canvas state (e.g. RecordingCanvas) can both record and pass
- * through state operations to CanvasState, so that not only will querying operations work
- * (getClip/Matrix), but so that quickRejection can also be used.
- */
-
-class CanvasState {
-public:
-    explicit CanvasState(CanvasStateClient& renderer);
-    ~CanvasState();
-
-    /**
-     * Initializes the first snapshot, computing the projection matrix,
-     * and stores the dimensions of the render target.
-     */
-    void initializeRecordingSaveStack(int viewportWidth, int viewportHeight);
-
-    /**
-     * Initializes the first snapshot, computing the projection matrix,
-     * and stores the dimensions of the render target.
-     */
-    void initializeSaveStack(int viewportWidth, int viewportHeight, float clipLeft, float clipTop,
-                             float clipRight, float clipBottom, const Vector3& lightCenter);
-
-    bool hasRectToRectTransform() const { return CC_LIKELY(currentTransform()->rectToRect()); }
-
-    // Save (layer)
-    int getSaveCount() const { return mSaveCount; }
-    int save(int flags);
-    void restore();
-    void restoreToCount(int saveCount);
-
-    // Save/Restore without side-effects
-    int saveSnapshot(int flags);
-    void restoreSnapshot();
-
-    // Matrix
-    void getMatrix(SkMatrix* outMatrix) const;
-    void translate(float dx, float dy, float dz = 0.0f);
-    void rotate(float degrees);
-    void scale(float sx, float sy);
-    void skew(float sx, float sy);
-
-    void setMatrix(const SkMatrix& matrix);
-    void setMatrix(const Matrix4& matrix);  // internal only convenience method
-    void concatMatrix(const SkMatrix& matrix);
-    void concatMatrix(const Matrix4& matrix);  // internal only convenience method
-
-    // Clip
-    const Rect& getLocalClipBounds() const { return mSnapshot->getLocalClip(); }
-    const Rect& getRenderTargetClipBounds() const { return mSnapshot->getRenderTargetClip(); }
-
-    bool quickRejectConservative(float left, float top, float right, float bottom) const;
-
-    bool clipRect(float left, float top, float right, float bottom, SkClipOp op);
-    bool clipPath(const SkPath* path, SkClipOp op);
-
-    /**
-     * Sets a "clipping outline", which is independent from the regular clip.
-     * Currently only supports rectangles or rounded rectangles; passing in a
-     * more complicated outline fails silently. Replaces any previous clipping
-     * outline.
-     */
-    void setClippingOutline(LinearAllocator& allocator, const Outline* outline);
-    void setClippingRoundRect(LinearAllocator& allocator, const Rect& rect, float radius,
-                              bool highPriority = true) {
-        mSnapshot->setClippingRoundRect(allocator, rect, radius, highPriority);
-    }
-    void setProjectionPathMask(const SkPath* path) { mSnapshot->setProjectionPathMask(path); }
-
-    /**
-     * Returns true if drawing in the rectangle (left, top, right, bottom)
-     * will be clipped out. Is conservative: might return false when subpixel-
-     * perfect tests would return true.
-     */
-    bool calculateQuickRejectForScissor(float left, float top, float right, float bottom,
-                                        bool* clipRequired, bool* roundRectClipRequired,
-                                        bool snapOut) const;
-
-    void scaleAlpha(float alpha) { mSnapshot->alpha *= alpha; }
-
-    inline const mat4* currentTransform() const { return currentSnapshot()->transform; }
-    inline const Rect& currentRenderTargetClip() const {
-        return currentSnapshot()->getRenderTargetClip();
-    }
-    inline int currentFlags() const { return currentSnapshot()->flags; }
-    const Vector3& currentLightCenter() const {
-        return currentSnapshot()->getRelativeLightCenter();
-    }
-    int getViewportWidth() const { return currentSnapshot()->getViewportWidth(); }
-    int getViewportHeight() const { return currentSnapshot()->getViewportHeight(); }
-    int getWidth() const { return mWidth; }
-    int getHeight() const { return mHeight; }
-    bool clipIsSimple() const { return currentSnapshot()->clipIsSimple(); }
-
-    inline const Snapshot* currentSnapshot() const { return mSnapshot; }
-    inline Snapshot* writableSnapshot() { return mSnapshot; }
-    inline const Snapshot* firstSnapshot() const { return &mFirstSnapshot; }
-
-private:
-    Snapshot* allocSnapshot(Snapshot* previous, int savecount);
-    void freeSnapshot(Snapshot* snapshot);
-    void freeAllSnapshots();
-
-    /// Dimensions of the drawing surface
-    int mWidth, mHeight;
-
-    /// Number of saved states
-    int mSaveCount;
-
-    /// Base state
-    Snapshot mFirstSnapshot;
-
-    /// Host providing callbacks
-    CanvasStateClient& mCanvas;
-
-    /// Current state
-    Snapshot* mSnapshot;
-
-    // Pool of allocated snapshots to re-use
-    // NOTE: The dtors have already been invoked!
-    Snapshot* mSnapshotPool = nullptr;
-    int mSnapshotPoolCount = 0;
-
-};  // class CanvasState
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
deleted file mode 100644
index 27d93cf..0000000
--- a/libs/hwui/ClipArea.cpp
+++ /dev/null
@@ -1,534 +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 "ClipArea.h"
-
-#include "utils/LinearAllocator.h"
-
-#include <SkPath.h>
-#include <limits>
-#include <type_traits>
-
-namespace android {
-namespace uirenderer {
-
-static void handlePoint(Rect& transformedBounds, const Matrix4& transform, float x, float y) {
-    Vertex v = {x, y};
-    transform.mapPoint(v.x, v.y);
-    transformedBounds.expandToCover(v.x, v.y);
-}
-
-Rect transformAndCalculateBounds(const Rect& r, const Matrix4& transform) {
-    const float kMinFloat = std::numeric_limits<float>::lowest();
-    const float kMaxFloat = std::numeric_limits<float>::max();
-    Rect transformedBounds = {kMaxFloat, kMaxFloat, kMinFloat, kMinFloat};
-    handlePoint(transformedBounds, transform, r.left, r.top);
-    handlePoint(transformedBounds, transform, r.right, r.top);
-    handlePoint(transformedBounds, transform, r.left, r.bottom);
-    handlePoint(transformedBounds, transform, r.right, r.bottom);
-    return transformedBounds;
-}
-
-void ClipBase::dump() const {
-    ALOGD("mode %d" RECT_STRING, mode, RECT_ARGS(rect));
-}
-
-/*
- * TransformedRectangle
- */
-
-TransformedRectangle::TransformedRectangle() {}
-
-TransformedRectangle::TransformedRectangle(const Rect& bounds, const Matrix4& transform)
-        : mBounds(bounds), mTransform(transform) {}
-
-bool TransformedRectangle::canSimplyIntersectWith(const TransformedRectangle& other) const {
-    return mTransform == other.mTransform;
-}
-
-void TransformedRectangle::intersectWith(const TransformedRectangle& other) {
-    mBounds.doIntersect(other.mBounds);
-}
-
-bool TransformedRectangle::isEmpty() const {
-    return mBounds.isEmpty();
-}
-
-/*
- * RectangleList
- */
-
-RectangleList::RectangleList() : mTransformedRectanglesCount(0) {}
-
-bool RectangleList::isEmpty() const {
-    if (mTransformedRectanglesCount < 1) {
-        return true;
-    }
-
-    for (int i = 0; i < mTransformedRectanglesCount; i++) {
-        if (mTransformedRectangles[i].isEmpty()) {
-            return true;
-        }
-    }
-    return false;
-}
-
-int RectangleList::getTransformedRectanglesCount() const {
-    return mTransformedRectanglesCount;
-}
-
-const TransformedRectangle& RectangleList::getTransformedRectangle(int i) const {
-    return mTransformedRectangles[i];
-}
-
-void RectangleList::setEmpty() {
-    mTransformedRectanglesCount = 0;
-}
-
-void RectangleList::set(const Rect& bounds, const Matrix4& transform) {
-    mTransformedRectanglesCount = 1;
-    mTransformedRectangles[0] = TransformedRectangle(bounds, transform);
-}
-
-bool RectangleList::intersectWith(const Rect& bounds, const Matrix4& transform) {
-    TransformedRectangle newRectangle(bounds, transform);
-
-    // Try to find a rectangle with a compatible transformation
-    int index = 0;
-    for (; index < mTransformedRectanglesCount; index++) {
-        TransformedRectangle& tr(mTransformedRectangles[index]);
-        if (tr.canSimplyIntersectWith(newRectangle)) {
-            tr.intersectWith(newRectangle);
-            return true;
-        }
-    }
-
-    // Add it to the list if there is room
-    if (index < kMaxTransformedRectangles) {
-        mTransformedRectangles[index] = newRectangle;
-        mTransformedRectanglesCount += 1;
-        return true;
-    }
-
-    // This rectangle list is full
-    return false;
-}
-
-Rect RectangleList::calculateBounds() const {
-    Rect bounds;
-    for (int index = 0; index < mTransformedRectanglesCount; index++) {
-        const TransformedRectangle& tr(mTransformedRectangles[index]);
-        if (index == 0) {
-            bounds = tr.transformedBounds();
-        } else {
-            bounds.doIntersect(tr.transformedBounds());
-        }
-    }
-    return bounds;
-}
-
-static SkPath pathFromTransformedRectangle(const Rect& bounds, const Matrix4& transform) {
-    SkPath rectPath;
-    SkPath rectPathTransformed;
-    rectPath.addRect(bounds.left, bounds.top, bounds.right, bounds.bottom);
-    SkMatrix skTransform;
-    transform.copyTo(skTransform);
-    rectPath.transform(skTransform, &rectPathTransformed);
-    return rectPathTransformed;
-}
-
-SkRegion RectangleList::convertToRegion(const SkRegion& clip) const {
-    SkRegion rectangleListAsRegion;
-    for (int index = 0; index < mTransformedRectanglesCount; index++) {
-        const TransformedRectangle& tr(mTransformedRectangles[index]);
-        SkPath rectPathTransformed =
-                pathFromTransformedRectangle(tr.getBounds(), tr.getTransform());
-        if (index == 0) {
-            rectangleListAsRegion.setPath(rectPathTransformed, clip);
-        } else {
-            SkRegion rectRegion;
-            rectRegion.setPath(rectPathTransformed, clip);
-            rectangleListAsRegion.op(rectRegion, SkRegion::kIntersect_Op);
-        }
-    }
-    return rectangleListAsRegion;
-}
-
-void RectangleList::transform(const Matrix4& transform) {
-    for (int index = 0; index < mTransformedRectanglesCount; index++) {
-        mTransformedRectangles[index].transform(transform);
-    }
-}
-
-/*
- * ClipArea
- */
-
-ClipArea::ClipArea() : mMode(ClipMode::Rectangle) {}
-
-/*
- * Interface
- */
-
-void ClipArea::setViewportDimensions(int width, int height) {
-    mPostViewportClipObserved = false;
-    mViewportBounds.set(0, 0, width, height);
-    mClipRect = mViewportBounds;
-}
-
-void ClipArea::setEmpty() {
-    onClipUpdated();
-    mMode = ClipMode::Rectangle;
-    mClipRect.setEmpty();
-    mClipRegion.setEmpty();
-    mRectangleList.setEmpty();
-}
-
-void ClipArea::setClip(float left, float top, float right, float bottom) {
-    onClipUpdated();
-    mMode = ClipMode::Rectangle;
-    mClipRect.set(left, top, right, bottom);
-    mClipRegion.setEmpty();
-}
-
-void ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op) {
-    if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
-    if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
-    onClipUpdated();
-    switch (mMode) {
-        case ClipMode::Rectangle:
-            rectangleModeClipRectWithTransform(r, transform, op);
-            break;
-        case ClipMode::RectangleList:
-            rectangleListModeClipRectWithTransform(r, transform, op);
-            break;
-        case ClipMode::Region:
-            regionModeClipRectWithTransform(r, transform, op);
-            break;
-    }
-}
-
-void ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
-    if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
-    if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
-    onClipUpdated();
-    enterRegionMode();
-    mClipRegion.op(region, op);
-    onClipRegionUpdated();
-}
-
-void ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform, SkRegion::Op op) {
-    if (op == SkRegion::kReplace_Op) mReplaceOpObserved = true;
-    if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
-    onClipUpdated();
-    SkMatrix skTransform;
-    transform->copyTo(skTransform);
-    SkPath transformed;
-    path.transform(skTransform, &transformed);
-    SkRegion region;
-    regionFromPath(transformed, region);
-    enterRegionMode();
-    mClipRegion.op(region, op);
-    onClipRegionUpdated();
-}
-
-/*
- * Rectangle mode
- */
-
-void ClipArea::enterRectangleMode() {
-    // Entering rectangle mode discards any
-    // existing clipping information from the other modes.
-    // The only way this occurs is by a clip setting operation.
-    mMode = ClipMode::Rectangle;
-}
-
-void ClipArea::rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform,
-                                                  SkRegion::Op op) {
-    if (op == SkRegion::kReplace_Op && transform->rectToRect()) {
-        mClipRect = r;
-        transform->mapRect(mClipRect);
-        return;
-    } else if (op != SkRegion::kIntersect_Op) {
-        enterRegionMode();
-        regionModeClipRectWithTransform(r, transform, op);
-        return;
-    }
-
-    if (transform->rectToRect()) {
-        Rect transformed(r);
-        transform->mapRect(transformed);
-        mClipRect.doIntersect(transformed);
-        return;
-    }
-
-    enterRectangleListMode();
-    rectangleListModeClipRectWithTransform(r, transform, op);
-}
-
-/*
- * RectangleList mode implementation
- */
-
-void ClipArea::enterRectangleListMode() {
-    // Is is only legal to enter rectangle list mode from
-    // rectangle mode, since rectangle list mode cannot represent
-    // all clip areas that can be represented by a region.
-    ALOG_ASSERT(mMode == ClipMode::Rectangle);
-    mMode = ClipMode::RectangleList;
-    mRectangleList.set(mClipRect, Matrix4::identity());
-}
-
-void ClipArea::rectangleListModeClipRectWithTransform(const Rect& r, const mat4* transform,
-                                                      SkRegion::Op op) {
-    if (op != SkRegion::kIntersect_Op || !mRectangleList.intersectWith(r, *transform)) {
-        enterRegionMode();
-        regionModeClipRectWithTransform(r, transform, op);
-    }
-}
-
-/*
- * Region mode implementation
- */
-
-void ClipArea::enterRegionMode() {
-    ClipMode oldMode = mMode;
-    mMode = ClipMode::Region;
-    if (oldMode != ClipMode::Region) {
-        if (oldMode == ClipMode::Rectangle) {
-            mClipRegion.setRect(mClipRect.toSkIRect());
-        } else {
-            mClipRegion = mRectangleList.convertToRegion(createViewportRegion());
-            onClipRegionUpdated();
-        }
-    }
-}
-
-void ClipArea::regionModeClipRectWithTransform(const Rect& r, const mat4* transform,
-                                               SkRegion::Op op) {
-    SkPath transformedRect = pathFromTransformedRectangle(r, *transform);
-    SkRegion transformedRectRegion;
-    regionFromPath(transformedRect, transformedRectRegion);
-    mClipRegion.op(transformedRectRegion, op);
-    onClipRegionUpdated();
-}
-
-void ClipArea::onClipRegionUpdated() {
-    if (!mClipRegion.isEmpty()) {
-        mClipRect.set(mClipRegion.getBounds());
-
-        if (mClipRegion.isRect()) {
-            mClipRegion.setEmpty();
-            enterRectangleMode();
-        }
-    } else {
-        mClipRect.setEmpty();
-    }
-}
-
-/**
- * Clip serialization
- */
-
-const ClipBase* ClipArea::serializeClip(LinearAllocator& allocator) {
-    if (!mPostViewportClipObserved) {
-        // Only initial clip-to-viewport observed, so no serialization of clip necessary
-        return nullptr;
-    }
-
-    static_assert(std::is_trivially_destructible<Rect>::value,
-                  "expect Rect to be trivially destructible");
-    static_assert(std::is_trivially_destructible<RectangleList>::value,
-                  "expect RectangleList to be trivially destructible");
-
-    if (mLastSerialization == nullptr) {
-        ClipBase* serialization = nullptr;
-        switch (mMode) {
-            case ClipMode::Rectangle:
-                serialization = allocator.create<ClipRect>(mClipRect);
-                break;
-            case ClipMode::RectangleList:
-                serialization = allocator.create<ClipRectList>(mRectangleList);
-                serialization->rect = mRectangleList.calculateBounds();
-                break;
-            case ClipMode::Region:
-                serialization = allocator.create<ClipRegion>(mClipRegion);
-                serialization->rect.set(mClipRegion.getBounds());
-                break;
-        }
-        serialization->intersectWithRoot = mReplaceOpObserved;
-        // TODO: this is only done for draw time, should eventually avoid for record time
-        serialization->rect.snapToPixelBoundaries();
-        mLastSerialization = serialization;
-    }
-    return mLastSerialization;
-}
-
-inline static const RectangleList& getRectList(const ClipBase* scb) {
-    return reinterpret_cast<const ClipRectList*>(scb)->rectList;
-}
-
-inline static const SkRegion& getRegion(const ClipBase* scb) {
-    return reinterpret_cast<const ClipRegion*>(scb)->region;
-}
-
-// Conservative check for too many rectangles to fit in rectangle list.
-// For simplicity, doesn't account for rect merging
-static bool cannotFitInRectangleList(const ClipArea& clipArea, const ClipBase* scb) {
-    int currentRectCount = clipArea.isRectangleList()
-                                   ? clipArea.getRectangleList().getTransformedRectanglesCount()
-                                   : 1;
-    int recordedRectCount = (scb->mode == ClipMode::RectangleList)
-                                    ? getRectList(scb).getTransformedRectanglesCount()
-                                    : 1;
-    return currentRectCount + recordedRectCount > RectangleList::kMaxTransformedRectangles;
-}
-
-static const ClipRect sEmptyClipRect(Rect(0, 0));
-
-const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator,
-                                                   const ClipBase* recordedClip,
-                                                   const Matrix4& recordedClipTransform) {
-    // if no recordedClip passed, just serialize current state
-    if (!recordedClip) return serializeClip(allocator);
-
-    // if either is empty, clip is empty
-    if (CC_UNLIKELY(recordedClip->rect.isEmpty()) || mClipRect.isEmpty()) return &sEmptyClipRect;
-
-    if (!mLastResolutionResult || recordedClip != mLastResolutionClip ||
-        recordedClipTransform != mLastResolutionTransform) {
-        mLastResolutionClip = recordedClip;
-        mLastResolutionTransform = recordedClipTransform;
-
-        if (CC_LIKELY(mMode == ClipMode::Rectangle && recordedClip->mode == ClipMode::Rectangle &&
-                      recordedClipTransform.rectToRect())) {
-            // common case - result is a single rectangle
-            auto rectClip = allocator.create<ClipRect>(recordedClip->rect);
-            recordedClipTransform.mapRect(rectClip->rect);
-            rectClip->rect.doIntersect(mClipRect);
-            rectClip->rect.snapToPixelBoundaries();
-            mLastResolutionResult = rectClip;
-        } else if (CC_UNLIKELY(mMode == ClipMode::Region ||
-                               recordedClip->mode == ClipMode::Region ||
-                               cannotFitInRectangleList(*this, recordedClip))) {
-            // region case
-            SkRegion other;
-            switch (recordedClip->mode) {
-                case ClipMode::Rectangle:
-                    if (CC_LIKELY(recordedClipTransform.rectToRect())) {
-                        // simple transform, skip creating SkPath
-                        Rect resultClip(recordedClip->rect);
-                        recordedClipTransform.mapRect(resultClip);
-                        other.setRect(resultClip.toSkIRect());
-                    } else {
-                        SkPath transformedRect = pathFromTransformedRectangle(
-                                recordedClip->rect, recordedClipTransform);
-                        other.setPath(transformedRect, createViewportRegion());
-                    }
-                    break;
-                case ClipMode::RectangleList: {
-                    RectangleList transformedList(getRectList(recordedClip));
-                    transformedList.transform(recordedClipTransform);
-                    other = transformedList.convertToRegion(createViewportRegion());
-                    break;
-                }
-                case ClipMode::Region:
-                    other = getRegion(recordedClip);
-                    applyTransformToRegion(recordedClipTransform, &other);
-            }
-
-            ClipRegion* regionClip = allocator.create<ClipRegion>();
-            switch (mMode) {
-                case ClipMode::Rectangle:
-                    regionClip->region.op(mClipRect.toSkIRect(), other, SkRegion::kIntersect_Op);
-                    break;
-                case ClipMode::RectangleList:
-                    regionClip->region.op(mRectangleList.convertToRegion(createViewportRegion()),
-                                          other, SkRegion::kIntersect_Op);
-                    break;
-                case ClipMode::Region:
-                    regionClip->region.op(mClipRegion, other, SkRegion::kIntersect_Op);
-                    break;
-            }
-            // Don't need to snap, since region's in int bounds
-            regionClip->rect.set(regionClip->region.getBounds());
-            mLastResolutionResult = regionClip;
-        } else {
-            auto rectListClip = allocator.create<ClipRectList>(mRectangleList);
-            auto&& rectList = rectListClip->rectList;
-            if (mMode == ClipMode::Rectangle) {
-                rectList.set(mClipRect, Matrix4::identity());
-            }
-
-            if (recordedClip->mode == ClipMode::Rectangle) {
-                rectList.intersectWith(recordedClip->rect, recordedClipTransform);
-            } else {
-                const RectangleList& other = getRectList(recordedClip);
-                for (int i = 0; i < other.getTransformedRectanglesCount(); i++) {
-                    auto&& tr = other.getTransformedRectangle(i);
-                    Matrix4 totalTransform(recordedClipTransform);
-                    totalTransform.multiply(tr.getTransform());
-                    rectList.intersectWith(tr.getBounds(), totalTransform);
-                }
-            }
-            rectListClip->rect = rectList.calculateBounds();
-            rectListClip->rect.snapToPixelBoundaries();
-            mLastResolutionResult = rectListClip;
-        }
-    }
-    return mLastResolutionResult;
-}
-
-void ClipArea::applyClip(const ClipBase* clip, const Matrix4& transform) {
-    if (!clip) return;  // nothing to do
-
-    if (CC_LIKELY(clip->mode == ClipMode::Rectangle)) {
-        clipRectWithTransform(clip->rect, &transform, SkRegion::kIntersect_Op);
-    } else if (CC_LIKELY(clip->mode == ClipMode::RectangleList)) {
-        auto&& rectList = getRectList(clip);
-        for (int i = 0; i < rectList.getTransformedRectanglesCount(); i++) {
-            auto&& tr = rectList.getTransformedRectangle(i);
-            Matrix4 totalTransform(transform);
-            totalTransform.multiply(tr.getTransform());
-            clipRectWithTransform(tr.getBounds(), &totalTransform, SkRegion::kIntersect_Op);
-        }
-    } else {
-        SkRegion region(getRegion(clip));
-        applyTransformToRegion(transform, &region);
-        clipRegion(region, SkRegion::kIntersect_Op);
-    }
-}
-
-void ClipArea::applyTransformToRegion(const Matrix4& transform, SkRegion* region) {
-    if (transform.rectToRect() && !transform.isPureTranslate()) {
-        // handle matrices with scale manually by mapping each rect
-        SkRegion other;
-        SkRegion::Iterator it(*region);
-        while (!it.done()) {
-            Rect rect(it.rect());
-            transform.mapRect(rect);
-            rect.snapGeometryToPixelBoundaries(true);
-            other.op(rect.left, rect.top, rect.right, rect.bottom, SkRegion::kUnion_Op);
-            it.next();
-        }
-        region->swap(other);
-    } else {
-        // TODO: handle non-translate transforms properly!
-        region->translate(transform.getTranslateX(), transform.getTranslateY());
-    }
-}
-
-} /* namespace uirenderer */
-} /* namespace android */
diff --git a/libs/hwui/ClipArea.h b/libs/hwui/ClipArea.h
deleted file mode 100644
index a7a1180..0000000
--- a/libs/hwui/ClipArea.h
+++ /dev/null
@@ -1,212 +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.
- */
-#ifndef CLIPAREA_H
-#define CLIPAREA_H
-
-#include "Matrix.h"
-#include "Rect.h"
-#include "utils/Pair.h"
-
-#include <SkRegion.h>
-
-namespace android {
-namespace uirenderer {
-
-class LinearAllocator;
-
-Rect transformAndCalculateBounds(const Rect& r, const Matrix4& transform);
-
-class TransformedRectangle {
-public:
-    TransformedRectangle();
-    TransformedRectangle(const Rect& bounds, const Matrix4& transform);
-
-    bool canSimplyIntersectWith(const TransformedRectangle& other) const;
-    void intersectWith(const TransformedRectangle& other);
-
-    bool isEmpty() const;
-
-    const Rect& getBounds() const { return mBounds; }
-
-    Rect transformedBounds() const {
-        Rect transformedBounds(transformAndCalculateBounds(mBounds, mTransform));
-        return transformedBounds;
-    }
-
-    const Matrix4& getTransform() const { return mTransform; }
-
-    void transform(const Matrix4& transform) {
-        Matrix4 t;
-        t.loadMultiply(transform, mTransform);
-        mTransform = t;
-    }
-
-private:
-    Rect mBounds;
-    Matrix4 mTransform;
-};
-
-class RectangleList {
-public:
-    RectangleList();
-
-    bool isEmpty() const;
-    int getTransformedRectanglesCount() const;
-    const TransformedRectangle& getTransformedRectangle(int i) const;
-
-    void setEmpty();
-    void set(const Rect& bounds, const Matrix4& transform);
-    bool intersectWith(const Rect& bounds, const Matrix4& transform);
-    void transform(const Matrix4& transform);
-
-    SkRegion convertToRegion(const SkRegion& clip) const;
-    Rect calculateBounds() const;
-
-    enum { kMaxTransformedRectangles = 5 };
-
-private:
-    int mTransformedRectanglesCount;
-    TransformedRectangle mTransformedRectangles[kMaxTransformedRectangles];
-};
-
-enum class ClipMode {
-    Rectangle,
-    RectangleList,
-
-    // region and path - intersected. if either is empty, don't use
-    Region
-};
-
-struct ClipBase {
-    explicit ClipBase(ClipMode mode) : mode(mode) {}
-    explicit ClipBase(const Rect& rect) : mode(ClipMode::Rectangle), rect(rect) {}
-    const ClipMode mode;
-    bool intersectWithRoot = false;
-    // Bounds of the clipping area, used to define the scissor, and define which
-    // portion of the stencil is updated/used
-    Rect rect;
-
-    void dump() const;
-};
-
-struct ClipRect : ClipBase {
-    explicit ClipRect(const Rect& rect) : ClipBase(rect) {}
-};
-
-struct ClipRectList : ClipBase {
-    explicit ClipRectList(const RectangleList& rectList)
-            : ClipBase(ClipMode::RectangleList), rectList(rectList) {}
-    RectangleList rectList;
-};
-
-struct ClipRegion : ClipBase {
-    explicit ClipRegion(const SkRegion& region) : ClipBase(ClipMode::Region), region(region) {}
-    ClipRegion() : ClipBase(ClipMode::Region) {}
-    SkRegion region;
-};
-
-class ClipArea {
-public:
-    ClipArea();
-
-    void setViewportDimensions(int width, int height);
-
-    bool isEmpty() const { return mClipRect.isEmpty(); }
-
-    void setEmpty();
-    void setClip(float left, float top, float right, float bottom);
-    void clipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
-    void clipPathWithTransform(const SkPath& path, const mat4* transform, SkRegion::Op op);
-
-    const Rect& getClipRect() const { return mClipRect; }
-
-    const SkRegion& getClipRegion() const { return mClipRegion; }
-
-    const RectangleList& getRectangleList() const { return mRectangleList; }
-
-    bool isRegion() const { return ClipMode::Region == mMode; }
-
-    bool isSimple() const { return mMode == ClipMode::Rectangle; }
-
-    bool isRectangleList() const { return mMode == ClipMode::RectangleList; }
-
-    WARN_UNUSED_RESULT const ClipBase* serializeClip(LinearAllocator& allocator);
-    WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(
-            LinearAllocator& allocator, const ClipBase* recordedClip,
-            const Matrix4& recordedClipTransform);
-    void applyClip(const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
-
-    static void applyTransformToRegion(const Matrix4& transform, SkRegion* region);
-
-private:
-    void enterRectangleMode();
-    void rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
-
-    void enterRectangleListMode();
-    void rectangleListModeClipRectWithTransform(const Rect& r, const mat4* transform,
-                                                SkRegion::Op op);
-
-    void enterRegionModeFromRectangleMode();
-    void enterRegionModeFromRectangleListMode();
-    void enterRegionMode();
-    void regionModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
-
-    void clipRegion(const SkRegion& region, SkRegion::Op op);
-    void ensureClipRegion();
-    void onClipRegionUpdated();
-
-    // Called by every state modifying public method.
-    void onClipUpdated() {
-        mPostViewportClipObserved = true;
-        mLastSerialization = nullptr;
-        mLastResolutionResult = nullptr;
-    }
-
-    SkRegion createViewportRegion() { return SkRegion(mViewportBounds.toSkIRect()); }
-
-    void regionFromPath(const SkPath& path, SkRegion& pathAsRegion) {
-        // TODO: this should not mask every path to the viewport - this makes it impossible to use
-        // paths to clip to larger areas (which is valid e.g. with SkRegion::kReplace_Op)
-        pathAsRegion.setPath(path, createViewportRegion());
-    }
-
-    ClipMode mMode;
-    bool mPostViewportClipObserved = false;
-    bool mReplaceOpObserved = false;
-
-    /**
-     * If mLastSerialization is non-null, it represents an already serialized copy
-     * of the current clip state. If null, it has not been computed.
-     */
-    const ClipBase* mLastSerialization = nullptr;
-
-    /**
-     * This pair of pointers is a single entry cache of most recently seen
-     */
-    const ClipBase* mLastResolutionResult = nullptr;
-    const ClipBase* mLastResolutionClip = nullptr;
-    Matrix4 mLastResolutionTransform;
-
-    Rect mViewportBounds;
-    Rect mClipRect;
-    SkRegion mClipRegion;
-    RectangleList mRectangleList;
-};
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif /* CLIPAREA_H_ */
diff --git a/libs/hwui/FloatColor.h b/libs/hwui/FloatColor.h
deleted file mode 100644
index b424f97..0000000
--- a/libs/hwui/FloatColor.h
+++ /dev/null
@@ -1,71 +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.
- */
-#ifndef FLOATCOLOR_H
-#define FLOATCOLOR_H
-
-#include "utils/Color.h"
-#include "utils/Macros.h"
-#include "utils/MathUtils.h"
-
-#include <stdint.h>
-
-namespace android {
-namespace uirenderer {
-
-struct FloatColor {
-    // "color" is a gamma-encoded sRGB color
-    // After calling this method, the color is stored as a pre-multiplied linear color
-    // if linear blending is enabled. Otherwise, the color is stored as a pre-multiplied
-    // gamma-encoded sRGB color
-    void set(uint32_t color) {
-        a = ((color >> 24) & 0xff) / 255.0f;
-        r = a * EOCF(((color >> 16) & 0xff) / 255.0f);
-        g = a * EOCF(((color >> 8) & 0xff) / 255.0f);
-        b = a * EOCF(((color)&0xff) / 255.0f);
-    }
-
-    // "color" is a gamma-encoded sRGB color
-    // After calling this method, the color is stored as a un-premultiplied linear color
-    // if linear blending is enabled. Otherwise, the color is stored as a un-premultiplied
-    // gamma-encoded sRGB color
-    void setUnPreMultiplied(uint32_t color) {
-        a = ((color >> 24) & 0xff) / 255.0f;
-        r = EOCF(((color >> 16) & 0xff) / 255.0f);
-        g = EOCF(((color >> 8) & 0xff) / 255.0f);
-        b = EOCF(((color)&0xff) / 255.0f);
-    }
-
-    bool isNotBlack() { return a < 1.0f || r > 0.0f || g > 0.0f || b > 0.0f; }
-
-    bool operator==(const FloatColor& other) const {
-        return MathUtils::areEqual(r, other.r) && MathUtils::areEqual(g, other.g) &&
-               MathUtils::areEqual(b, other.b) && MathUtils::areEqual(a, other.a);
-    }
-
-    bool operator!=(const FloatColor& other) const { return !(*this == other); }
-
-    float r;
-    float g;
-    float b;
-    float a;
-};
-
-REQUIRE_COMPATIBLE_LAYOUT(FloatColor);
-
-} /* namespace uirenderer */
-} /* namespace android */
-
-#endif /* FLOATCOLOR_H */
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index f2d50cd..e7ae767 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <inttypes.h>
+#include <statslog.h>
 #include <sys/mman.h>
 
 #include <algorithm>
@@ -181,6 +182,7 @@
         ALOGI("%s", ss.str().c_str());
         // Just so we have something that counts up, the value is largely irrelevant
         ATRACE_INT(ss.str().c_str(), ++sDaveyCount);
+        android::util::stats_write(android::util::DAVEY_OCCURRED, getuid(), ns2ms(totalDuration));
     }
 }
 
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index c30af84..f928de9 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -23,6 +23,7 @@
 #include "SkDrawShadowInfo.h"
 #include "SkImage.h"
 #include "SkImageFilter.h"
+#include "SkLatticeIter.h"
 #include "SkMath.h"
 #include "SkPicture.h"
 #include "SkRSXform.h"
@@ -280,7 +281,8 @@
 
 struct DrawImage final : Op {
     static const auto kType = Type::DrawImage;
-    DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint, BitmapPalette palette)
+    DrawImage(sk_sp<const SkImage>&& image, SkScalar x, SkScalar y, const SkPaint* paint,
+              BitmapPalette palette)
             : image(std::move(image)), x(x), y(y), palette(palette) {
         if (paint) {
             this->paint = *paint;
@@ -312,7 +314,8 @@
 struct DrawImageRect final : Op {
     static const auto kType = Type::DrawImageRect;
     DrawImageRect(sk_sp<const SkImage>&& image, const SkRect* src, const SkRect& dst,
-                  const SkPaint* paint, SkCanvas::SrcRectConstraint constraint, BitmapPalette palette)
+                  const SkPaint* paint, SkCanvas::SrcRectConstraint constraint,
+                  BitmapPalette palette)
             : image(std::move(image)), dst(dst), constraint(constraint), palette(palette) {
         this->src = src ? *src : SkRect::MakeIWH(this->image->width(), this->image->height());
         if (paint) {
@@ -331,8 +334,14 @@
 struct DrawImageLattice final : Op {
     static const auto kType = Type::DrawImageLattice;
     DrawImageLattice(sk_sp<const SkImage>&& image, int xs, int ys, int fs, const SkIRect& src,
-                     const SkRect& dst, const SkPaint* paint)
-            : image(std::move(image)), xs(xs), ys(ys), fs(fs), src(src), dst(dst) {
+                     const SkRect& dst, const SkPaint* paint, BitmapPalette palette)
+            : image(std::move(image))
+            , xs(xs)
+            , ys(ys)
+            , fs(fs)
+            , src(src)
+            , dst(dst)
+            , palette(palette) {
         if (paint) {
             this->paint = *paint;
         }
@@ -342,6 +351,7 @@
     SkIRect src;
     SkRect dst;
     SkPaint paint;
+    BitmapPalette palette;
     void draw(SkCanvas* c, const SkMatrix&) const {
         auto xdivs = pod<int>(this, 0), ydivs = pod<int>(this, xs * sizeof(int));
         auto colors = (0 == fs) ? nullptr : pod<SkColor>(this, (xs + ys) * sizeof(int));
@@ -511,16 +521,13 @@
         tree->getPaintFor(&paint, tree->stagingProperties());
     }
 
-    void draw(SkCanvas* canvas, const SkMatrix&) const {
-        mRoot->draw(canvas, mBounds, paint);
-    }
+    void draw(SkCanvas* canvas, const SkMatrix&) const { mRoot->draw(canvas, mBounds, paint); }
 
     sp<VectorDrawableRoot> mRoot;
     SkRect mBounds;
     SkPaint paint;
     BitmapPalette palette;
 };
-
 }
 
 template <typename T, typename... Args>
@@ -647,14 +654,15 @@
     this->push<DrawImageRect>(0, std::move(image), src, dst, paint, constraint, palette);
 }
 void DisplayListData::drawImageLattice(sk_sp<const SkImage> image, const SkCanvas::Lattice& lattice,
-                                       const SkRect& dst, const SkPaint* paint) {
+                                       const SkRect& dst, const SkPaint* paint,
+                                       BitmapPalette palette) {
     int xs = lattice.fXCount, ys = lattice.fYCount;
     int fs = lattice.fRectTypes ? (xs + 1) * (ys + 1) : 0;
     size_t bytes = (xs + ys) * sizeof(int) + fs * sizeof(SkCanvas::Lattice::RectType) +
                    fs * sizeof(SkColor);
     SkASSERT(lattice.fBounds);
     void* pod = this->push<DrawImageLattice>(bytes, std::move(image), xs, ys, fs, *lattice.fBounds,
-                                             dst, paint);
+                                             dst, paint, palette);
     copy_v(pod, lattice.fXDivs, xs, lattice.fYDivs, ys, lattice.fColors, fs, lattice.fRectTypes,
            fs);
 }
@@ -779,22 +787,26 @@
 
 template <class T>
 constexpr color_transform_fn colorTransformForOp() {
-    if constexpr(has_paint<T> && has_palette<T>) {
-        // It's a bitmap
-        return [](const void* opRaw, ColorTransform transform) {
-            // TODO: We should be const. Or not. Or just use a different map
-            // Unclear, but this is the quick fix
-            const T* op = reinterpret_cast<const T*>(opRaw);
-            transformPaint(transform, const_cast<SkPaint*>(&(op->paint)), op->palette);
-        };
-    } else if constexpr(has_paint<T>) {
-        return [](const void* opRaw, ColorTransform transform) {
-            // TODO: We should be const. Or not. Or just use a different map
-            // Unclear, but this is the quick fix
-            const T* op = reinterpret_cast<const T*>(opRaw);
-            transformPaint(transform, const_cast<SkPaint*>(&(op->paint)));
-        };
-    } else {
+    if
+        constexpr(has_paint<T> && has_palette<T>) {
+            // It's a bitmap
+            return [](const void* opRaw, ColorTransform transform) {
+                // TODO: We should be const. Or not. Or just use a different map
+                // Unclear, but this is the quick fix
+                const T* op = reinterpret_cast<const T*>(opRaw);
+                transformPaint(transform, const_cast<SkPaint*>(&(op->paint)), op->palette);
+            };
+        }
+    else if
+        constexpr(has_paint<T>) {
+            return [](const void* opRaw, ColorTransform transform) {
+                // TODO: We should be const. Or not. Or just use a different map
+                // Unclear, but this is the quick fix
+                const T* op = reinterpret_cast<const T*>(opRaw);
+                transformPaint(transform, const_cast<SkPaint*>(&(op->paint)));
+            };
+        }
+    else {
         return nullptr;
     }
 }
@@ -931,11 +943,12 @@
 }
 void RecordingCanvas::onDrawBitmapRect(const SkBitmap& bm, const SkRect* src, const SkRect& dst,
                                        const SkPaint* paint, SrcRectConstraint constraint) {
-    fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint, BitmapPalette::Unknown);
+    fDL->drawImageRect(SkImage::MakeFromBitmap(bm), src, dst, paint, constraint,
+                       BitmapPalette::Unknown);
 }
 void RecordingCanvas::onDrawBitmapLattice(const SkBitmap& bm, const SkCanvas::Lattice& lattice,
                                           const SkRect& dst, const SkPaint* paint) {
-    fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint);
+    fDL->drawImageLattice(SkImage::MakeFromBitmap(bm), lattice, dst, paint, BitmapPalette::Unknown);
 }
 
 void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
@@ -943,11 +956,34 @@
     fDL->drawImage(image, x, y, paint, palette);
 }
 
-void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
-                   const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette) {
+void RecordingCanvas::drawImageRect(const sk_sp<SkImage>& image, const SkRect& src,
+                                    const SkRect& dst, const SkPaint* paint,
+                                    SrcRectConstraint constraint, BitmapPalette palette) {
     fDL->drawImageRect(image, &src, dst, paint, constraint, palette);
 }
 
+void RecordingCanvas::drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice,
+                                       const SkRect& dst, const SkPaint* paint,
+                                       BitmapPalette palette) {
+    if (!image || dst.isEmpty()) {
+        return;
+    }
+
+    SkIRect bounds;
+    Lattice latticePlusBounds = lattice;
+    if (!latticePlusBounds.fBounds) {
+        bounds = SkIRect::MakeWH(image->width(), image->height());
+        latticePlusBounds.fBounds = &bounds;
+    }
+
+    if (SkLatticeIter::Valid(image->width(), image->height(), latticePlusBounds)) {
+        fDL->drawImageLattice(image, latticePlusBounds, dst, paint, palette);
+    } else {
+        fDL->drawImageRect(image, nullptr, dst, paint, SrcRectConstraint::kFast_SrcRectConstraint,
+                           palette);
+    }
+}
+
 void RecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y,
                                   const SkPaint* paint) {
     fDL->drawImage(sk_ref_sp(img), x, y, paint, BitmapPalette::Unknown);
@@ -962,7 +998,7 @@
 }
 void RecordingCanvas::onDrawImageLattice(const SkImage* img, const SkCanvas::Lattice& lattice,
                                          const SkRect& dst, const SkPaint* paint) {
-    fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint);
+    fDL->drawImageLattice(sk_ref_sp(img), lattice, dst, paint, BitmapPalette::Unknown);
 }
 
 void RecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
@@ -975,8 +1011,8 @@
     fDL->drawPoints(mode, count, pts, paint);
 }
 void RecordingCanvas::onDrawVerticesObject(const SkVertices* vertices,
-                                          const SkVertices::Bone bones[], int boneCount,
-                                          SkBlendMode mode, const SkPaint& paint) {
+                                           const SkVertices::Bone bones[], int boneCount,
+                                           SkBlendMode mode, const SkPaint& paint) {
     fDL->drawVertices(vertices, bones, boneCount, mode, paint);
 }
 void RecordingCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xforms[],
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 80c80ca..099e0be 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -110,7 +110,7 @@
     void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkPaint*,
                        SkCanvas::SrcRectConstraint, BitmapPalette palette);
     void drawImageLattice(sk_sp<const SkImage>, const SkCanvas::Lattice&, const SkRect&,
-                          const SkPaint*);
+                          const SkPaint*, BitmapPalette);
 
     void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
                    const SkPaint&);
@@ -185,11 +185,13 @@
     void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
                           SrcRectConstraint) override;
 
-    void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top,
-                   const SkPaint* paint, BitmapPalette pallete);
+    void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top, const SkPaint* paint,
+                   BitmapPalette pallete);
 
     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
                        const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette);
+    void drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice, const SkRect& dst,
+                          const SkPaint* paint, BitmapPalette palette);
 
     void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
     void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override;
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index d9a7cc3..d2a8f02 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -282,25 +282,45 @@
     mStagingDisplayList = nullptr;
     if (mDisplayList) {
         mDisplayList->syncContents();
+        handleForceDark(info);
+    }
+}
 
-        if (CC_UNLIKELY(info && !info->disableForceDark)) {
-            auto usage = usageHint();
-            if (mDisplayList->hasText()) {
-                usage = UsageHint::Foreground;
-            }
-            if (usage == UsageHint::Unknown) {
-                if (mDisplayList->mChildNodes.size() > 1) {
-                    usage = UsageHint::Background;
-                } else if (mDisplayList->mChildNodes.size() == 1 &&
-                           mDisplayList->mChildNodes.front().getRenderNode()->usageHint() !=
-                                   UsageHint::Background) {
-                    usage = UsageHint::Background;
-                }
-            }
-            mDisplayList->mDisplayList.applyColorTransform(
-                    usage == UsageHint::Background ? ColorTransform::Dark : ColorTransform::Light);
+void RenderNode::handleForceDark(android::uirenderer::TreeInfo *info) {
+    if (CC_LIKELY(!info || info->disableForceDark)) {
+        return;
+    }
+    auto usage = usageHint();
+    const auto& children = mDisplayList->mChildNodes;
+    if (mDisplayList->hasText()) {
+        usage = UsageHint::Foreground;
+    }
+    if (usage == UsageHint::Unknown) {
+        if (children.size() > 1) {
+            usage = UsageHint::Background;
+        } else if (children.size() == 1 &&
+                children.front().getRenderNode()->usageHint() !=
+                        UsageHint::Background) {
+            usage = UsageHint::Background;
         }
     }
+    if (children.size() > 1) {
+        // Crude overlap check
+        SkRect drawn = SkRect::MakeEmpty();
+        for (auto iter = children.rbegin(); iter != children.rend(); ++iter) {
+            const auto& child = iter->getRenderNode();
+            // We use stagingProperties here because we haven't yet sync'd the children
+            SkRect bounds = SkRect::MakeXYWH(child->stagingProperties().getX(), child->stagingProperties().getY(),
+                    child->stagingProperties().getWidth(), child->stagingProperties().getHeight());
+            if (bounds.contains(drawn)) {
+                // This contains everything drawn after it, so make it a background
+                child->setUsageHint(UsageHint::Background);
+            }
+            drawn.join(bounds);
+        }
+    }
+    mDisplayList->mDisplayList.applyColorTransform(
+            usage == UsageHint::Background ? ColorTransform::Dark : ColorTransform::Light);
 }
 
 void RenderNode::pushStagingDisplayListChanges(TreeObserver& observer, TreeInfo& info) {
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 211dd2d..be0b46b 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -220,6 +220,7 @@
 
     void syncProperties();
     void syncDisplayList(TreeObserver& observer, TreeInfo* info);
+    void handleForceDark(TreeInfo* info);
 
     void prepareTreeImpl(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer);
     void pushStagingPropertiesChanges(TreeInfo& info);
diff --git a/libs/hwui/ResourceCache.cpp b/libs/hwui/ResourceCache.cpp
deleted file mode 100644
index 65bee47..0000000
--- a/libs/hwui/ResourceCache.cpp
+++ /dev/null
@@ -1,145 +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.
- */
-
-#include "ResourceCache.h"
-
-namespace android {
-
-using namespace uirenderer;
-ANDROID_SINGLETON_STATIC_INSTANCE(ResourceCache);
-
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Resource cache
-///////////////////////////////////////////////////////////////////////////////
-
-void ResourceCache::logCache() {
-    ALOGD("ResourceCache: cacheReport:");
-    for (size_t i = 0; i < mCache->size(); ++i) {
-        ResourceReference* ref = mCache->valueAt(i);
-        ALOGD("  ResourceCache: mCache(%zu): resource, ref = 0x%p, 0x%p", i, mCache->keyAt(i),
-              mCache->valueAt(i));
-        ALOGD("  ResourceCache: mCache(%zu): refCount, destroyed, type = %d, %d, %d", i,
-              ref->refCount, ref->destroyed, ref->resourceType);
-    }
-}
-
-ResourceCache::ResourceCache() {
-    Mutex::Autolock _l(mLock);
-    mCache = new KeyedVector<const void*, ResourceReference*>();
-}
-
-ResourceCache::~ResourceCache() {
-    Mutex::Autolock _l(mLock);
-    delete mCache;
-}
-
-void ResourceCache::lock() {
-    mLock.lock();
-}
-
-void ResourceCache::unlock() {
-    mLock.unlock();
-}
-
-void ResourceCache::incrementRefcount(void* resource, ResourceType resourceType) {
-    Mutex::Autolock _l(mLock);
-    incrementRefcountLocked(resource, resourceType);
-}
-
-void ResourceCache::incrementRefcount(const Res_png_9patch* patchResource) {
-    incrementRefcount((void*)patchResource, kNinePatch);
-}
-
-void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
-    ssize_t index = mCache->indexOfKey(resource);
-    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr;
-    if (ref == nullptr || mCache->size() == 0) {
-        ref = new ResourceReference(resourceType);
-        mCache->add(resource, ref);
-    }
-    ref->refCount++;
-}
-
-void ResourceCache::decrementRefcount(void* resource) {
-    Mutex::Autolock _l(mLock);
-    decrementRefcountLocked(resource);
-}
-
-void ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) {
-    decrementRefcount((void*)patchResource);
-}
-
-void ResourceCache::decrementRefcountLocked(void* resource) {
-    ssize_t index = mCache->indexOfKey(resource);
-    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr;
-    if (ref == nullptr) {
-        // Should not get here - shouldn't get a call to decrement if we're not yet tracking it
-        return;
-    }
-    ref->refCount--;
-    if (ref->refCount == 0) {
-        deleteResourceReferenceLocked(resource, ref);
-    }
-}
-
-void ResourceCache::decrementRefcountLocked(const Res_png_9patch* patchResource) {
-    decrementRefcountLocked((void*)patchResource);
-}
-
-void ResourceCache::destructor(Res_png_9patch* resource) {
-    Mutex::Autolock _l(mLock);
-    destructorLocked(resource);
-}
-
-void ResourceCache::destructorLocked(Res_png_9patch* resource) {
-    ssize_t index = mCache->indexOfKey(resource);
-    ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : nullptr;
-    if (ref == nullptr) {
-        // If we're not tracking this resource, just delete it
-        // A Res_png_9patch is actually an array of byte that's larger
-        // than sizeof(Res_png_9patch). It must be freed as an array.
-        delete[](int8_t*) resource;
-        return;
-    }
-    ref->destroyed = true;
-    if (ref->refCount == 0) {
-        deleteResourceReferenceLocked(resource, ref);
-    }
-}
-
-/**
- * This method should only be called while the mLock mutex is held (that mutex is grabbed
- * by the various destructor() and recycle() methods which call this method).
- */
-void ResourceCache::deleteResourceReferenceLocked(const void* resource, ResourceReference* ref) {
-    if (ref->destroyed) {
-        switch (ref->resourceType) {
-            case kNinePatch: {
-                // A Res_png_9patch is actually an array of byte that's larger
-                // than sizeof(Res_png_9patch). It must be freed as an array.
-                int8_t* patch = (int8_t*)resource;
-                delete[] patch;
-            } break;
-        }
-    }
-    mCache->removeItem(resource);
-    delete ref;
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/ResourceCache.h b/libs/hwui/ResourceCache.h
deleted file mode 100644
index fd3f9fd..0000000
--- a/libs/hwui/ResourceCache.h
+++ /dev/null
@@ -1,103 +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.
- */
-
-#ifndef ANDROID_HWUI_RESOURCE_CACHE_H
-#define ANDROID_HWUI_RESOURCE_CACHE_H
-
-#include <cutils/compiler.h>
-
-#include <SkBitmap.h>
-#include <SkPixelRef.h>
-
-#include <utils/KeyedVector.h>
-#include <utils/Singleton.h>
-
-#include <androidfw/ResourceTypes.h>
-
-namespace android {
-namespace uirenderer {
-
-class Layer;
-
-/**
- * Type of Resource being cached
- */
-enum ResourceType {
-    kNinePatch,
-};
-
-class ResourceReference {
-public:
-    explicit ResourceReference(ResourceType type) {
-        refCount = 0;
-        destroyed = false;
-        resourceType = type;
-    }
-
-    int refCount;
-    bool destroyed;
-    ResourceType resourceType;
-};
-
-class ANDROID_API ResourceCache : public Singleton<ResourceCache> {
-    ResourceCache();
-    ~ResourceCache();
-
-    friend class Singleton<ResourceCache>;
-
-public:
-    /**
-     * When using these two methods, make sure to only invoke the *Locked()
-     * variants of increment/decrementRefcount(), recyle() and destructor()
-     */
-    void lock();
-    void unlock();
-
-    void incrementRefcount(const Res_png_9patch* resource);
-
-    void decrementRefcount(const Res_png_9patch* resource);
-
-    void decrementRefcountLocked(const Res_png_9patch* resource);
-
-    void destructor(Res_png_9patch* resource);
-
-    void destructorLocked(Res_png_9patch* resource);
-
-private:
-    void deleteResourceReferenceLocked(const void* resource, ResourceReference* ref);
-
-    void incrementRefcount(void* resource, ResourceType resourceType);
-    void incrementRefcountLocked(void* resource, ResourceType resourceType);
-
-    void decrementRefcount(void* resource);
-    void decrementRefcountLocked(void* resource);
-
-    void logCache();
-
-    /**
-     * Used to increment, decrement, and destroy. Incrementing is generally accessed on the UI
-     * thread, but destroying resources may be called from the GC thread, the finalizer thread,
-     * or a reference queue finalization thread.
-     */
-    mutable Mutex mLock;
-
-    KeyedVector<const void*, ResourceReference*>* mCache;
-};
-
-};  // namespace uirenderer
-};  // namespace android
-
-#endif  // ANDROID_HWUI_RESOURCE_CACHE_H
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 17f1a3b..2e5aef5 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -504,6 +504,11 @@
     mCanvas->drawRoundRect(rect, rx, ry, *filterPaint(paint));
 }
 
+void SkiaCanvas::drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
+                                const SkPaint& paint) {
+    mCanvas->drawDRRect(outer, inner, *filterPaint(paint));
+}
+
 void SkiaCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
     if (CC_UNLIKELY(radius <= 0 || paint.nothingToDraw())) return;
     mCanvas->drawCircle(x, y, radius, *filterPaint(paint));
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 24b7ec6..3a877cf 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -107,6 +107,10 @@
     virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override;
     virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
                                const SkPaint& paint) override;
+
+   virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
+                               const SkPaint& paint) override;
+
     virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
     virtual void drawOval(float left, float top, float right, float bottom,
                           const SkPaint& paint) override;
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
deleted file mode 100644
index f1a1bef..0000000
--- a/libs/hwui/Snapshot.cpp
+++ /dev/null
@@ -1,209 +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 "Snapshot.h"
-
-#include "hwui/Canvas.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors
-///////////////////////////////////////////////////////////////////////////////
-
-Snapshot::Snapshot()
-        : flags(0)
-        , previous(nullptr)
-        , layer(nullptr)
-        , fbo(0)
-        , alpha(1.0f)
-        , roundRectClipState(nullptr)
-        , projectionPathMask(nullptr)
-        , mClipArea(&mClipAreaRoot) {
-    transform = &mTransformRoot;
-    mRelativeLightCenter.x = mRelativeLightCenter.y = mRelativeLightCenter.z = 0;
-}
-
-/**
- * Copies the specified snapshot/ The specified snapshot is stored as
- * the previous snapshot.
- */
-Snapshot::Snapshot(Snapshot* s, int saveFlags)
-        : flags(0)
-        , previous(s)
-        , layer(s->layer)
-        , fbo(s->fbo)
-        , alpha(s->alpha)
-        , roundRectClipState(s->roundRectClipState)
-        , projectionPathMask(s->projectionPathMask)
-        , mClipArea(nullptr)
-        , mViewportData(s->mViewportData)
-        , mRelativeLightCenter(s->mRelativeLightCenter) {
-    if (saveFlags & SaveFlags::Matrix) {
-        mTransformRoot = *s->transform;
-        transform = &mTransformRoot;
-    } else {
-        transform = s->transform;
-    }
-
-    if (saveFlags & SaveFlags::Clip) {
-        mClipAreaRoot = s->getClipArea();
-        mClipArea = &mClipAreaRoot;
-    } else {
-        mClipArea = s->mClipArea;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Clipping
-///////////////////////////////////////////////////////////////////////////////
-
-void Snapshot::clip(const Rect& localClip, SkClipOp op) {
-    flags |= Snapshot::kFlagClipSet;
-    mClipArea->clipRectWithTransform(localClip, transform, static_cast<SkRegion::Op>(op));
-}
-
-void Snapshot::clipPath(const SkPath& path, SkClipOp op) {
-    flags |= Snapshot::kFlagClipSet;
-    mClipArea->clipPathWithTransform(path, transform, static_cast<SkRegion::Op>(op));
-}
-
-void Snapshot::setClip(float left, float top, float right, float bottom) {
-    flags |= Snapshot::kFlagClipSet;
-    mClipArea->setClip(left, top, right, bottom);
-}
-
-bool Snapshot::hasPerspectiveTransform() const {
-    return transform->isPerspective();
-}
-
-const Rect& Snapshot::getLocalClip() {
-    mat4 inverse;
-    inverse.loadInverse(*transform);
-
-    mLocalClip.set(mClipArea->getClipRect());
-    inverse.mapRect(mLocalClip);
-
-    return mLocalClip;
-}
-
-void Snapshot::resetClip(float left, float top, float right, float bottom) {
-    // TODO: This is incorrect, when we start rendering into a new layer,
-    // we may have to modify the previous snapshot's clip rect and clip
-    // region if the previous restore() call did not restore the clip
-    mClipArea = &mClipAreaRoot;
-    setClip(left, top, right, bottom);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Clipping round rect
-///////////////////////////////////////////////////////////////////////////////
-
-void Snapshot::setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius,
-                                    bool highPriority) {
-    if (bounds.isEmpty()) {
-        mClipArea->setEmpty();
-        return;
-    }
-
-    if (roundRectClipState && roundRectClipState->highPriority) {
-        // ignore, don't replace, already have a high priority clip
-        return;
-    }
-
-    RoundRectClipState* state = new (allocator) RoundRectClipState;
-
-    state->highPriority = highPriority;
-
-    // store the inverse drawing matrix
-    Matrix4 roundRectDrawingMatrix = getOrthoMatrix();
-    roundRectDrawingMatrix.multiply(*transform);
-    state->matrix.loadInverse(roundRectDrawingMatrix);
-
-    // compute area under rounded corners - only draws overlapping these rects need to be clipped
-    for (int i = 0; i < 4; i++) {
-        state->dangerRects[i] = bounds;
-    }
-    state->dangerRects[0].bottom = state->dangerRects[1].bottom = bounds.top + radius;
-    state->dangerRects[0].right = state->dangerRects[2].right = bounds.left + radius;
-    state->dangerRects[1].left = state->dangerRects[3].left = bounds.right - radius;
-    state->dangerRects[2].top = state->dangerRects[3].top = bounds.bottom - radius;
-    for (int i = 0; i < 4; i++) {
-        transform->mapRect(state->dangerRects[i]);
-
-        // round danger rects out as though they are AA geometry (since they essentially are)
-        state->dangerRects[i].snapGeometryToPixelBoundaries(true);
-    }
-
-    // store RR area
-    state->innerRect = bounds;
-    state->innerRect.inset(radius);
-    state->radius = radius;
-
-    // store as immutable so, for this frame, pointer uniquely identifies this bundle of shader info
-    roundRectClipState = state;
-}
-
-void Snapshot::setProjectionPathMask(const SkPath* path) {
-    projectionPathMask = path;
-}
-
-static Snapshot* getClipRoot(Snapshot* target) {
-    while (target->previous && target->previous->previous) {
-        target = target->previous;
-    }
-    return target;
-}
-
-const ClipBase* Snapshot::serializeIntersectedClip(LinearAllocator& allocator,
-                                                   const ClipBase* recordedClip,
-                                                   const Matrix4& recordedClipTransform) {
-    auto target = this;
-    if (CC_UNLIKELY(recordedClip && recordedClip->intersectWithRoot)) {
-        // Clip must be intersected with root, instead of current clip.
-        target = getClipRoot(this);
-    }
-
-    return target->mClipArea->serializeIntersectedClip(allocator, recordedClip,
-                                                       recordedClipTransform);
-}
-
-void Snapshot::applyClip(const ClipBase* recordedClip, const Matrix4& transform) {
-    if (CC_UNLIKELY(recordedClip && recordedClip->intersectWithRoot)) {
-        // current clip is being replaced, but must intersect with clip root
-        *mClipArea = *(getClipRoot(this)->mClipArea);
-    }
-    mClipArea->applyClip(recordedClip, transform);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Queries
-///////////////////////////////////////////////////////////////////////////////
-
-void Snapshot::dump() const {
-    ALOGD("Snapshot %p, flags %x, prev %p, height %d, hasComplexClip %d", this, flags, previous,
-          getViewportHeight(), !mClipArea->isSimple());
-    const Rect& clipRect(mClipArea->getClipRect());
-    ALOGD("  ClipRect %.1f %.1f %.1f %.1f, clip simple %d", clipRect.left, clipRect.top,
-          clipRect.right, clipRect.bottom, mClipArea->isSimple());
-
-    ALOGD("  Transform (at %p):", transform);
-    transform->dump();
-}
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
deleted file mode 100644
index 655f819..0000000
--- a/libs/hwui/Snapshot.h
+++ /dev/null
@@ -1,279 +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.
- */
-
-#pragma once
-
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <ui/Region.h>
-#include <utils/LinearAllocator.h>
-#include <utils/RefBase.h>
-
-#include <SkClipOp.h>
-#include <SkRegion.h>
-
-#include "ClipArea.h"
-#include "Layer.h"
-#include "Matrix.h"
-#include "Outline.h"
-#include "Rect.h"
-#include "utils/Macros.h"
-
-namespace android {
-namespace uirenderer {
-
-/**
- * Temporary structure holding information for a single outline clip.
- *
- * These structures are treated as immutable once created, and only exist for a single frame, which
- * is why they may only be allocated with a LinearAllocator.
- */
-class RoundRectClipState {
-public:
-    static void* operator new(size_t size) = delete;
-    static void* operator new(size_t size, LinearAllocator& allocator) {
-        return allocator.alloc<RoundRectClipState>(size);
-    }
-
-    bool areaRequiresRoundRectClip(const Rect& rect) const {
-        return rect.intersects(dangerRects[0]) || rect.intersects(dangerRects[1]) ||
-               rect.intersects(dangerRects[2]) || rect.intersects(dangerRects[3]);
-    }
-
-    bool highPriority;
-    Matrix4 matrix;
-    Rect dangerRects[4];
-    Rect innerRect;
-    float radius;
-};
-
-/**
- * A snapshot holds information about the current state of the rendering
- * surface. A snapshot is usually created whenever the user calls save()
- * and discarded when the user calls restore(). Once a snapshot is created,
- * it can hold information for deferred rendering.
- *
- * Each snapshot has a link to a previous snapshot, indicating the previous
- * state of the renderer.
- */
-class Snapshot {
-public:
-    Snapshot();
-    Snapshot(Snapshot* s, int saveFlags);
-
-    /**
-     * Various flags set on ::flags.
-     */
-    enum Flags {
-        /**
-         * Indicates that the clip region was modified. When this
-         * snapshot is restored so must the clip.
-         */
-        kFlagClipSet = 0x1,
-        /**
-         * Indicates that this snapshot was created when saving
-         * a new layer.
-         */
-        kFlagIsLayer = 0x2,
-        /**
-         * Indicates that this snapshot is a special type of layer
-         * backed by an FBO. This flag only makes sense when the
-         * flag kFlagIsLayer is also set.
-         *
-         * Viewport has been modified to fit the new Fbo, and must be
-         * restored when this snapshot is restored.
-         */
-        kFlagIsFboLayer = 0x4,
-    };
-
-    /**
-     * Modifies the current clip with the new clip rectangle and
-     * the specified operation. The specified rectangle is transformed
-     * by this snapshot's trasnformation.
-     */
-    void clip(const Rect& localClip, SkClipOp op);
-
-    /**
-     * Modifies the current clip with the new clip rectangle and
-     * the specified operation. The specified rectangle is considered
-     * already transformed.
-     */
-    void clipTransformed(const Rect& r, SkClipOp op = SkClipOp::kIntersect);
-
-    /**
-     * Modifies the current clip with the specified path and operation.
-     */
-    void clipPath(const SkPath& path, SkClipOp op);
-
-    /**
-     * Sets the current clip.
-     */
-    void setClip(float left, float top, float right, float bottom);
-
-    /**
-     * Returns the current clip in local coordinates. The clip rect is
-     * transformed by the inverse transform matrix.
-     */
-    ANDROID_API const Rect& getLocalClip();
-
-    /**
-     * Returns the current clip in render target coordinates.
-     */
-    const Rect& getRenderTargetClip() const { return mClipArea->getClipRect(); }
-
-    /*
-     * Accessor functions so that the clip area can stay private
-     */
-    bool clipIsEmpty() const { return mClipArea->isEmpty(); }
-    const SkRegion& getClipRegion() const { return mClipArea->getClipRegion(); }
-    bool clipIsSimple() const { return mClipArea->isSimple(); }
-    const ClipArea& getClipArea() const { return *mClipArea; }
-    ClipArea& mutateClipArea() { return *mClipArea; }
-
-    WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(
-            LinearAllocator& allocator, const ClipBase* recordedClip,
-            const Matrix4& recordedClipTransform);
-    void applyClip(const ClipBase* clip, const Matrix4& transform);
-
-    /**
-     * Resets the clip to the specified rect.
-     */
-    void resetClip(float left, float top, float right, float bottom);
-
-    void initializeViewport(int width, int height) {
-        mViewportData.initialize(width, height);
-        mClipAreaRoot.setViewportDimensions(width, height);
-    }
-
-    int getViewportWidth() const { return mViewportData.mWidth; }
-    int getViewportHeight() const { return mViewportData.mHeight; }
-    const Matrix4& getOrthoMatrix() const { return mViewportData.mOrthoMatrix; }
-
-    const Vector3& getRelativeLightCenter() const { return mRelativeLightCenter; }
-    void setRelativeLightCenter(const Vector3& lightCenter) { mRelativeLightCenter = lightCenter; }
-
-    /**
-     * Sets (and replaces) the current clipping outline
-     *
-     * If the current round rect clip is high priority, the incoming clip is ignored.
-     */
-    void setClippingRoundRect(LinearAllocator& allocator, const Rect& bounds, float radius,
-                              bool highPriority);
-
-    /**
-     * Sets (and replaces) the current projection mask
-     */
-    void setProjectionPathMask(const SkPath* path);
-
-    /**
-     * Indicates whether the current transform has perspective components.
-     */
-    bool hasPerspectiveTransform() const;
-
-    /**
-     * Dirty flags.
-     */
-    int flags;
-
-    /**
-     * Previous snapshot.
-     */
-    Snapshot* previous;
-
-    /**
-     * A pointer to the currently active layer.
-     *
-     * This snapshot does not own the layer, this pointer must not be freed.
-     */
-    Layer* layer;
-
-    /**
-     * Target FBO used for rendering. Set to 0 when rendering directly
-     * into the framebuffer.
-     */
-    GLuint fbo;
-
-    /**
-     * Local transformation. Holds the current translation, scale and
-     * rotation values.
-     *
-     * This is a reference to a matrix owned by this snapshot or another
-     *  snapshot. This pointer must not be freed. See ::mTransformRoot.
-     */
-    mat4* transform;
-
-    /**
-     * Current alpha value. This value is 1 by default, but may be set by a DisplayList which
-     * has translucent rendering in a non-overlapping View. This value will be used by
-     * the renderer to set the alpha in the current color being used for ensuing drawing
-     * operations. The value is inherited by child snapshots because the same value should
-     * be applied to descendants of the current DisplayList (for example, a TextView contains
-     * the base alpha value which should be applied to the child DisplayLists used for drawing
-     * the actual text).
-     */
-    float alpha;
-
-    /**
-     * Current clipping round rect.
-     *
-     * Points to data not owned by the snapshot, and may only be replaced by subsequent RR clips,
-     * never modified.
-     */
-    const RoundRectClipState* roundRectClipState;
-
-    /**
-     * Current projection masking path - used exclusively to mask projected, tessellated circles.
-     */
-    const SkPath* projectionPathMask;
-
-    void dump() const;
-
-private:
-    struct ViewportData {
-        ViewportData() : mWidth(0), mHeight(0) {}
-        void initialize(int width, int height) {
-            mWidth = width;
-            mHeight = height;
-            mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
-        }
-
-        /*
-         * Width and height of current viewport.
-         *
-         * The viewport is always defined to be (0, 0, width, height).
-         */
-        int mWidth;
-        int mHeight;
-        /**
-         * Contains the current orthographic, projection matrix.
-         */
-        mat4 mOrthoMatrix;
-    };
-
-    mat4 mTransformRoot;
-
-    ClipArea mClipAreaRoot;
-    ClipArea* mClipArea;
-    Rect mLocalClip;
-
-    ViewportData mViewportData;
-    Vector3 mRelativeLightCenter;
-
-};  // class Snapshot
-
-};  // namespace uirenderer
-};  // namespace android
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index dbbe9f3..6cf04bf 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -470,10 +470,10 @@
 void Tree::getPaintFor(SkPaint* outPaint, const TreeProperties &prop) const {
     // HWUI always draws VD with bilinear filtering.
     outPaint->setFilterQuality(kLow_SkFilterQuality);
-    if (prop.getRootAlpha() < 1.0f || prop.getColorFilter() != nullptr) {
+    if (prop.getColorFilter() != nullptr) {
         outPaint->setColorFilter(sk_ref_sp(prop.getColorFilter()));
-        outPaint->setAlpha(prop.getRootAlpha() * 255);
     }
+    outPaint->setAlpha(prop.getRootAlpha() * 255);
 }
 
 Bitmap& Tree::getBitmapUpdateIfDirty() {
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index a6aae55..f091277 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -19,7 +19,6 @@
 
 #include "Vector.h"
 
-#include "FloatColor.h"
 #include "utils/Macros.h"
 
 namespace android {
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 9c28453..753557c 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -134,14 +134,15 @@
 }
 
 sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer) {
-    PixelFormat format = graphicBuffer->getPixelFormat();
-    if (!graphicBuffer.get() ||
-        (format != PIXEL_FORMAT_RGBA_8888 && format != PIXEL_FORMAT_RGBA_FP16)) {
-        return nullptr;
-    }
+    return createFrom(graphicBuffer, SkColorSpace::MakeSRGB());
+}
+
+sk_sp<Bitmap> Bitmap::createFrom(sp<GraphicBuffer> graphicBuffer, sk_sp<SkColorSpace> colorSpace) {
+    // As we will be effectively texture-sampling the buffer (using either EGL or Vulkan), we can
+    // view the colorspace as RGBA8888.
     SkImageInfo info = SkImageInfo::Make(graphicBuffer->getWidth(), graphicBuffer->getHeight(),
                                          kRGBA_8888_SkColorType, kPremul_SkAlphaType,
-                                         SkColorSpace::MakeSRGB());
+                                         colorSpace);
     return sk_sp<Bitmap>(new Bitmap(graphicBuffer.get(), info));
 }
 
@@ -223,6 +224,7 @@
             break;
         case PixelStorageType::Heap:
             free(mPixelStorage.heap.address);
+            mallopt(M_PURGE, 0);
             break;
         case PixelStorageType::Hardware:
             auto buffer = mPixelStorage.hardware.buffer;
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 43d457a..238c764 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -64,6 +64,8 @@
                                               size_t rowBytes);
 
     static sk_sp<Bitmap> createFrom(sp<GraphicBuffer> graphicBuffer);
+    static sk_sp<Bitmap> createFrom(sp<GraphicBuffer> graphicBuffer,
+                                    sk_sp<SkColorSpace> colorSpace);
 
     static sk_sp<Bitmap> createFrom(const SkImageInfo&, SkPixelRef&);
 
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index af7f013..e2ea2bc 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -178,6 +178,41 @@
     MinikinUtils::forFontRun(layout, &paint, f);
 }
 
+void Canvas::drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight,
+                            float outerBottom, float outerRx, float outerRy, float innerLeft,
+                            float innerTop, float innerRight, float innerBottom, float innerRx,
+                            float innerRy, const SkPaint& paint) {
+    if (CC_UNLIKELY(paint.nothingToDraw())) return;
+    SkRect outer = SkRect::MakeLTRB(outerLeft, outerTop, outerRight, outerBottom);
+    SkRect inner = SkRect::MakeLTRB(innerLeft, innerTop, innerRight, innerBottom);
+
+    SkRRect outerRRect;
+    outerRRect.setRectXY(outer, outerRx, outerRy);
+
+    SkRRect innerRRect;
+    innerRRect.setRectXY(inner, innerRx, innerRy);
+    drawDoubleRoundRect(outerRRect, innerRRect, paint);
+}
+
+void Canvas::drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight,
+                            float outerBottom, const float* outerRadii, float innerLeft,
+                            float innerTop, float innerRight, float innerBottom,
+                            const float* innerRadii, const SkPaint& paint) {
+    static_assert(sizeof(SkVector) == sizeof(float) * 2);
+    if (CC_UNLIKELY(paint.nothingToDraw())) return;
+    SkRect outer = SkRect::MakeLTRB(outerLeft, outerTop, outerRight, outerBottom);
+    SkRect inner = SkRect::MakeLTRB(innerLeft, innerTop, innerRight, innerBottom);
+
+    SkRRect outerRRect;
+    const SkVector* outerSkVector = reinterpret_cast<const SkVector*>(outerRadii);
+    outerRRect.setRectRadii(outer, outerSkVector);
+
+    SkRRect innerRRect;
+    const SkVector* innerSkVector = reinterpret_cast<const SkVector*>(innerRadii);
+    innerRRect.setRectRadii(inner, innerSkVector);
+    drawDoubleRoundRect(outerRRect, innerRRect, paint);
+}
+
 class DrawTextOnPathFunctor {
 public:
     DrawTextOnPathFunctor(const minikin::Layout& layout, Canvas* canvas, float hOffset,
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index b9af7de2..e99742b 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -236,6 +236,8 @@
     virtual void drawRegion(const SkRegion& region, const SkPaint& paint) = 0;
     virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
                                const SkPaint& paint) = 0;
+    virtual void drawDoubleRoundRect(const SkRRect& outer, const SkRRect& inner,
+                                const SkPaint& paint) = 0;
     virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) = 0;
     virtual void drawOval(float left, float top, float right, float bottom,
                           const SkPaint& paint) = 0;
@@ -284,6 +286,16 @@
                         const SkPath& path, float hOffset, float vOffset, const Paint& paint,
                         const Typeface* typeface);
 
+    void drawDoubleRoundRectXY(float outerLeft, float outerTop, float outerRight,
+                                float outerBottom, float outerRx, float outerRy, float innerLeft,
+                                float innerTop, float innerRight, float innerBottom, float innerRx,
+                                float innerRy, const SkPaint& paint);
+
+    void drawDoubleRoundRectRadii(float outerLeft, float outerTop, float outerRight,
+                                float outerBottom, const float* outerRadii, float innerLeft,
+                                float innerTop, float innerRight, float innerBottom,
+                                const float* innerRadii, const SkPaint& paint);
+
     static int GetApiLevel() { return sApiLevel; }
 
 protected:
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index 0022c93..c6e4c15 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -141,7 +141,7 @@
     // select only flags that might affect text layout
     flags &= (SkPaint::kAntiAlias_Flag | SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag |
               SkPaint::kSubpixelText_Flag | SkPaint::kEmbeddedBitmapText_Flag |
-              SkPaint::kAutoHinting_Flag | SkPaint::kVerticalText_Flag);
+              SkPaint::kAutoHinting_Flag);
     flags |= (hinting << 16);
     return flags;
 }
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index 3ca0f81..13d2dae 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -71,15 +71,12 @@
         paint.setAlpha(layer->getAlpha());
         paint.setBlendMode(layer->getMode());
         paint.setColorFilter(layer->getColorSpaceWithFilter());
-        if (layer->getForceFilter()) {
-            paint.setFilterQuality(kLow_SkFilterQuality);
-        }
-
         const bool nonIdentityMatrix = !matrix.isIdentity();
         if (nonIdentityMatrix) {
             canvas->save();
             canvas->concat(matrix);
         }
+        const SkMatrix& totalMatrix = canvas->getTotalMatrix();
         if (dstRect || srcRect) {
             SkMatrix matrixInv;
             if (!matrix.invert(&matrixInv)) {
@@ -99,9 +96,28 @@
                 skiaDestRect = SkRect::MakeIWH(layerWidth, layerHeight);
             }
             matrixInv.mapRect(&skiaDestRect);
+            // If (matrix is identity or an integer translation) and (src/dst buffers size match),
+            // 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 = totalMatrix.isTranslate()
+                    && SkScalarFraction(skiaDestRect.fLeft + totalMatrix[SkMatrix::kMTransX])
+                    == SkScalarFraction(skiaSrcRect.fLeft)
+                    && SkScalarFraction(skiaDestRect.fTop + totalMatrix[SkMatrix::kMTransY])
+                    == SkScalarFraction(skiaSrcRect.fTop);
+            if (layer->getForceFilter() || !isIntegerTranslate) {
+                paint.setFilterQuality(kLow_SkFilterQuality);
+            }
             canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, &paint,
                                   SkCanvas::kFast_SrcRectConstraint);
         } else {
+            bool isIntegerTranslate = totalMatrix.isTranslate()
+                    && SkScalarIsInt(totalMatrix[SkMatrix::kMTransX])
+                    && SkScalarIsInt(totalMatrix[SkMatrix::kMTransY]);
+            if (layer->getForceFilter() || !isIntegerTranslate) {
+                paint.setFilterQuality(kLow_SkFilterQuality);
+            }
             canvas->drawImage(layerImage.get(), 0, 0, &paint);
         }
         // restore the original matrix
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.h b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
index 6594bd22..d746978 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.h
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include "SkiaUtils.h"
+
 #include <SkCanvas.h>
 #include <SkDrawable.h>
 #include <SkMatrix.h>
@@ -89,7 +91,7 @@
     virtual SkRect onGetBounds() override {
         // We don't want to enable a record time quick reject because the properties
         // of the RenderNode may be updated on subsequent frames.
-        return SkRect::MakeLargest();
+        return SkRectMakeLargest();
     }
     /**
      * This function draws into a canvas as forceDraw, but does nothing if the render node has a
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
index 3c48d36..26cfa90 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include "RenderNodeDrawable.h"
+#include "SkiaUtils.h"
 
 #include <SkCanvas.h>
 #include <SkDrawable.h>
@@ -41,7 +42,7 @@
     explicit StartReorderBarrierDrawable(SkiaDisplayList* data);
 
 protected:
-    virtual SkRect onGetBounds() override { return SkRect::MakeLargest(); }
+    virtual SkRect onGetBounds() override { return SkRectMakeLargest(); }
     virtual void onDraw(SkCanvas* canvas) override;
 
 private:
@@ -65,7 +66,7 @@
     explicit EndReorderBarrierDrawable(StartReorderBarrierDrawable* startBarrier);
 
 protected:
-    virtual SkRect onGetBounds() override { return SkRect::MakeLargest(); }
+    virtual SkRect onGetBounds() override { return SkRectMakeLargest(); }
     virtual void onDraw(SkCanvas* canvas) override;
 
 private:
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index fac07d7..3fa73a4 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -245,8 +245,9 @@
     }
     sk_sp<SkColorFilter> colorFilter;
     sk_sp<SkImage> image = bitmap.makeImage(&colorFilter);
-    mRecorder.drawImageLattice(image.get(), lattice, dst,
-                               filterBitmap(std::move(filteredPaint), std::move(colorFilter)));
+    mRecorder.drawImageLattice(image, lattice, dst,
+                               filterBitmap(std::move(filteredPaint), std::move(colorFilter)),
+                               bitmap.palette());
     if (!bitmap.isImmutable() && image.get() && !image->unique() && !dst.isEmpty()) {
         mDisplayList->mMutableImages.push_back(image.get());
     }
diff --git a/proto/src/stats_enums.proto b/libs/hwui/pipeline/skia/SkiaUtils.h
similarity index 75%
copy from proto/src/stats_enums.proto
copy to libs/hwui/pipeline/skia/SkiaUtils.h
index 6c892cf..8344469 100644
--- a/proto/src/stats_enums.proto
+++ b/libs/hwui/pipeline/skia/SkiaUtils.h
@@ -14,13 +14,15 @@
  * limitations under the License.
  */
 
-syntax = "proto2";
+#pragma once
 
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "StatsEnums";
+#include <SkRect.h>
 
-enum EventType {
-  // Unknown.
-  TYPE_UNKNOWN = 0;
-}
+namespace android {
+
+static inline SkRect SkRectMakeLargest() {
+    const SkScalar v = SK_ScalarMax;
+    return { -v, -v, v, v };
+};
+
+} /* namespace android */
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index a2d8119..2ca110f 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -126,6 +126,12 @@
         mVkSurface = mVkManager.createSurface(surface, colorMode);
     }
 
+    if (colorMode == ColorMode::SRGB) {
+        mSurfaceColorType = SkColorType::kN32_SkColorType;
+    } else if (colorMode == ColorMode::WideColorGamut) {
+        mSurfaceColorType = SkColorType::kRGBA_F16_SkColorType;
+    }
+
     return mVkSurface != nullptr;
 }
 
diff --git a/libs/hwui/renderthread/VulkanManager.cpp b/libs/hwui/renderthread/VulkanManager.cpp
index 83e9db3..9e435a5 100644
--- a/libs/hwui/renderthread/VulkanManager.cpp
+++ b/libs/hwui/renderthread/VulkanManager.cpp
@@ -78,7 +78,7 @@
         0,                                  // applicationVersion
         "android framework",                // pEngineName
         0,                                  // engineVerison
-        VK_MAKE_VERSION(1, 0, 0),           // apiVersion
+        VK_MAKE_VERSION(1, 1, 0),           // apiVersion
     };
 
     std::vector<const char*> instanceExtensions;
@@ -133,6 +133,7 @@
 
     GET_INST_PROC(DestroyInstance);
     GET_INST_PROC(EnumeratePhysicalDevices);
+    GET_INST_PROC(GetPhysicalDeviceProperties);
     GET_INST_PROC(GetPhysicalDeviceQueueFamilyProperties);
     GET_INST_PROC(GetPhysicalDeviceFeatures2);
     GET_INST_PROC(CreateDevice);
@@ -164,6 +165,13 @@
         return false;
     }
 
+    VkPhysicalDeviceProperties physDeviceProperties;
+    mGetPhysicalDeviceProperties(mPhysicalDevice, &physDeviceProperties);
+    if (physDeviceProperties.apiVersion < VK_MAKE_VERSION(1, 1, 0)) {
+        this->destroy();
+        return false;
+    }
+
     // query to get the initial queue props size
     uint32_t queueCount;
     mGetPhysicalDeviceQueueFamilyProperties(mPhysicalDevice, &queueCount, nullptr);
@@ -488,13 +496,11 @@
     // set up layout transfer from initial to color attachment
     VkImageLayout layout = surface->mImageInfos[backbuffer->mImageIndex].mImageLayout;
     SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED == layout || VK_IMAGE_LAYOUT_PRESENT_SRC_KHR == layout);
-    VkPipelineStageFlags srcStageMask = (VK_IMAGE_LAYOUT_UNDEFINED == layout)
-                                                ? VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
-                                                : VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
     VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-    VkAccessFlags srcAccessMask =
-            (VK_IMAGE_LAYOUT_UNDEFINED == layout) ? 0 : VK_ACCESS_MEMORY_READ_BIT;
-    VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
+    VkAccessFlags srcAccessMask = 0;
+    VkAccessFlags dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
+                                  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
 
     VkImageMemoryBarrier imageMemoryBarrier = {
             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,     // sType
@@ -753,16 +759,8 @@
         return false;
     }
 
-    // If mailbox mode is available, use it, as it is the lowest-latency non-
-    // tearing mode. If not, fall back to FIFO which is always available.
+    // FIFO is always available and will match what we do on GL so just pick that here.
     VkPresentModeKHR mode = VK_PRESENT_MODE_FIFO_KHR;
-    for (uint32_t i = 0; i < presentModeCount; ++i) {
-        // use mailbox
-        if (VK_PRESENT_MODE_MAILBOX_KHR == presentModes[i]) {
-            mode = presentModes[i];
-            break;
-        }
-    }
 
     VkSwapchainCreateInfoKHR swapchainCreateInfo;
     memset(&swapchainCreateInfo, 0, sizeof(VkSwapchainCreateInfoKHR));
@@ -849,17 +847,19 @@
 }
 
 // Helper to know which src stage flags we need to set when transitioning to the present layout
-static VkPipelineStageFlags layoutToPipelineStageFlags(const VkImageLayout layout) {
+static VkPipelineStageFlags layoutToPipelineSrcStageFlags(const VkImageLayout layout) {
     if (VK_IMAGE_LAYOUT_GENERAL == layout) {
         return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
     } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout ||
                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) {
         return VK_PIPELINE_STAGE_TRANSFER_BIT;
-    } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout ||
-               VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout ||
-               VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL == layout ||
-               VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) {
-        return VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
+    } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout) {
+        return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+    } else if (VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout ||
+               VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL == layout) {
+        return VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT;
+    } else if (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) {
+        return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
     } else if (VK_IMAGE_LAYOUT_PREINITIALIZED == layout) {
         return VK_PIPELINE_STAGE_HOST_BIT;
     }
@@ -916,10 +916,10 @@
     // We need to transition the image to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR and make sure that all
     // previous work is complete for before presenting. So we first add the necessary barrier here.
     VkImageLayout layout = imageInfo.fImageLayout;
-    VkPipelineStageFlags srcStageMask = layoutToPipelineStageFlags(layout);
+    VkPipelineStageFlags srcStageMask = layoutToPipelineSrcStageFlags(layout);
     VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
     VkAccessFlags srcAccessMask = layoutToSrcAccessMask(layout);
-    VkAccessFlags dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+    VkAccessFlags dstAccessMask = 0;
 
     VkImageMemoryBarrier imageMemoryBarrier = {
             VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,     // sType
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index 7c59b6d..6702649 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -176,6 +176,7 @@
 
     VkPtr<PFN_vkDestroyInstance> mDestroyInstance;
     VkPtr<PFN_vkEnumeratePhysicalDevices> mEnumeratePhysicalDevices;
+    VkPtr<PFN_vkGetPhysicalDeviceProperties> mGetPhysicalDeviceProperties;
     VkPtr<PFN_vkGetPhysicalDeviceQueueFamilyProperties> mGetPhysicalDeviceQueueFamilyProperties;
     VkPtr<PFN_vkGetPhysicalDeviceFeatures2> mGetPhysicalDeviceFeatures2;
     VkPtr<PFN_vkCreateDevice> mCreateDevice;
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index a00b8db..c5db861d 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -21,7 +21,6 @@
 #include <Properties.h>
 #include <Rect.h>
 #include <RenderNode.h>
-#include <Snapshot.h>
 #include <hwui/Bitmap.h>
 #include <pipeline/skia/SkiaRecordingCanvas.h>
 #include <private/hwui/DrawGlInfo.h>
@@ -141,14 +140,6 @@
         return true;
     }
 
-    static std::unique_ptr<Snapshot> makeSnapshot(const Matrix4& transform, const Rect& clip) {
-        std::unique_ptr<Snapshot> snapshot(new Snapshot());
-        // store clip first, so it isn't transformed
-        snapshot->setClip(clip.left, clip.top, clip.right, clip.bottom);
-        *(snapshot->transform) = transform;
-        return snapshot;
-    }
-
     static sk_sp<Bitmap> createBitmap(int width, int height,
                                       SkColorType colorType = kN32_SkColorType) {
         SkImageInfo info = SkImageInfo::Make(width, height, colorType, kPremul_SkAlphaType);
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index e3c97ce..524dfb0 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -288,7 +288,7 @@
 
             case '?':
                 fprintf(stderr, "Unrecognized option '%s'\n", argv[optind - 1]);
-            // fall-through
+                [[fallthrough]];
             default:
                 error = true;
                 break;
diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
index 9388c20..70423a7 100644
--- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
+++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp
@@ -16,7 +16,6 @@
 
 #include <benchmark/benchmark.h>
 
-#include "CanvasState.h"
 #include "DisplayList.h"
 #include "hwui/Canvas.h"
 #include "pipeline/skia/SkiaDisplayList.h"
@@ -116,52 +115,6 @@
 }
 BENCHMARK(BM_DisplayListCanvas_record_simpleBitmapView);
 
-class NullClient : public CanvasStateClient {
-    void onViewportInitialized() override {}
-    void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
-    GLuint getTargetFbo() const override { return 0; }
-};
-
-void BM_CanvasState_saverestore(benchmark::State& benchState) {
-    NullClient client;
-    CanvasState state(client);
-    state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
-
-    while (benchState.KeepRunning()) {
-        state.save(SaveFlags::MatrixClip);
-        state.save(SaveFlags::MatrixClip);
-        benchmark::DoNotOptimize(&state);
-        state.restore();
-        state.restore();
-    }
-}
-BENCHMARK(BM_CanvasState_saverestore);
-
-void BM_CanvasState_init(benchmark::State& benchState) {
-    NullClient client;
-    CanvasState state(client);
-    state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
-
-    while (benchState.KeepRunning()) {
-        state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
-        benchmark::DoNotOptimize(&state);
-    }
-}
-BENCHMARK(BM_CanvasState_init);
-
-void BM_CanvasState_translate(benchmark::State& benchState) {
-    NullClient client;
-    CanvasState state(client);
-    state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3());
-
-    while (benchState.KeepRunning()) {
-        state.translate(5, 5, 0);
-        benchmark::DoNotOptimize(&state);
-        state.translate(-5, -5, 0);
-    }
-}
-BENCHMARK(BM_CanvasState_translate);
-
 void BM_DisplayListCanvas_basicViewGroupDraw(benchmark::State& benchState) {
     sp<RenderNode> child = TestUtils::createNode(50, 50, 100, 100, [](auto& props, auto& canvas) {
         canvas.drawColor(0xFFFFFFFF, SkBlendMode::kSrcOver);
diff --git a/libs/hwui/tests/unit/CanvasStateTests.cpp b/libs/hwui/tests/unit/CanvasStateTests.cpp
deleted file mode 100644
index 4c03811..0000000
--- a/libs/hwui/tests/unit/CanvasStateTests.cpp
+++ /dev/null
@@ -1,160 +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 "CanvasState.h"
-
-#include "Matrix.h"
-#include "Rect.h"
-#include "hwui/Canvas.h"
-#include "utils/LinearAllocator.h"
-
-#include <SkClipOp.h>
-#include <SkPath.h>
-#include <gtest/gtest.h>
-
-namespace android {
-namespace uirenderer {
-
-class NullClient : public CanvasStateClient {
-    void onViewportInitialized() override {}
-    void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
-    GLuint getTargetFbo() const override { return 0; }
-};
-
-static NullClient sNullClient;
-
-static bool approxEqual(const Matrix4& a, const Matrix4& b) {
-    for (int i = 0; i < 16; i++) {
-        if (!MathUtils::areEqual(a[i], b[i])) {
-            return false;
-        }
-    }
-    return true;
-}
-
-TEST(CanvasState, gettersAndSetters) {
-    CanvasState state(sNullClient);
-    state.initializeSaveStack(200, 200, 0, 0, 200, 200, Vector3());
-
-    ASSERT_EQ(state.getWidth(), 200);
-    ASSERT_EQ(state.getHeight(), 200);
-
-    Matrix4 simpleTranslate;
-    simpleTranslate.loadTranslate(10, 20, 0);
-    state.setMatrix(simpleTranslate);
-
-    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(200, 200));
-    ASSERT_EQ(state.getLocalClipBounds(), Rect(-10, -20, 190, 180));
-    EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));
-    EXPECT_TRUE(state.clipIsSimple());
-}
-
-TEST(CanvasState, simpleClipping) {
-    CanvasState state(sNullClient);
-    state.initializeSaveStack(200, 200, 0, 0, 200, 200, Vector3());
-
-    state.clipRect(0, 0, 100, 100, SkClipOp::kIntersect);
-    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(100, 100));
-
-    state.clipRect(10, 10, 200, 200, SkClipOp::kIntersect);
-    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10, 100, 100));
-
-    state.clipRect(50, 50, 150, 150, SkClipOp::kReplace_deprecated);
-    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(50, 50, 150, 150));
-}
-
-TEST(CanvasState, complexClipping) {
-    CanvasState state(sNullClient);
-    state.initializeSaveStack(200, 200, 0, 0, 200, 200, Vector3());
-
-    state.save(SaveFlags::MatrixClip);
-    {
-        // rotated clip causes complex clip
-        state.rotate(10);
-        EXPECT_TRUE(state.clipIsSimple());
-        state.clipRect(0, 0, 200, 200, SkClipOp::kIntersect);
-        EXPECT_FALSE(state.clipIsSimple());
-    }
-    state.restore();
-
-    state.save(SaveFlags::MatrixClip);
-    {
-        // subtracted clip causes complex clip
-        EXPECT_TRUE(state.clipIsSimple());
-        state.clipRect(50, 50, 150, 150, SkClipOp::kDifference);
-        EXPECT_FALSE(state.clipIsSimple());
-    }
-    state.restore();
-
-    state.save(SaveFlags::MatrixClip);
-    {
-        // complex path causes complex clip
-        SkPath path;
-        path.addOval(SkRect::MakeWH(200, 200));
-        EXPECT_TRUE(state.clipIsSimple());
-        state.clipPath(&path, SkClipOp::kDifference);
-        EXPECT_FALSE(state.clipIsSimple());
-    }
-    state.restore();
-}
-
-TEST(CanvasState, saveAndRestore) {
-    CanvasState state(sNullClient);
-    state.initializeSaveStack(200, 200, 0, 0, 200, 200, Vector3());
-
-    state.save(SaveFlags::Clip);
-    {
-        state.clipRect(0, 0, 10, 10, SkClipOp::kIntersect);
-        ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));
-    }
-    state.restore();
-    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(200, 200));  // verify restore
-
-    Matrix4 simpleTranslate;
-    simpleTranslate.loadTranslate(10, 10, 0);
-    state.save(SaveFlags::Matrix);
-    {
-        state.translate(10, 10, 0);
-        EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));
-    }
-    state.restore();
-    EXPECT_FALSE(approxEqual(*state.currentTransform(), simpleTranslate));
-}
-
-TEST(CanvasState, saveAndRestoreButNotTooMuch) {
-    CanvasState state(sNullClient);
-    state.initializeSaveStack(200, 200, 0, 0, 200, 200, Vector3());
-
-    state.save(SaveFlags::Matrix);  // NOTE: clip not saved
-    {
-        state.clipRect(0, 0, 10, 10, SkClipOp::kIntersect);
-        ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));
-    }
-    state.restore();
-    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));  // verify not restored
-
-    Matrix4 simpleTranslate;
-    simpleTranslate.loadTranslate(10, 10, 0);
-    state.save(SaveFlags::Clip);  // NOTE: matrix not saved
-    {
-        state.translate(10, 10, 0);
-        EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));
-    }
-    state.restore();
-    EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));  // verify not restored
-}
-}
-}
diff --git a/libs/hwui/tests/unit/ClipAreaTests.cpp b/libs/hwui/tests/unit/ClipAreaTests.cpp
deleted file mode 100644
index 450bb67..0000000
--- a/libs/hwui/tests/unit/ClipAreaTests.cpp
+++ /dev/null
@@ -1,353 +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 <SkPath.h>
-#include <SkRegion.h>
-#include <gtest/gtest.h>
-
-#include "ClipArea.h"
-
-#include "Matrix.h"
-#include "Rect.h"
-#include "utils/LinearAllocator.h"
-
-namespace android {
-namespace uirenderer {
-
-static Rect kViewportBounds(2048, 2048);
-
-static ClipArea createClipArea() {
-    ClipArea area;
-    area.setViewportDimensions(kViewportBounds.getWidth(), kViewportBounds.getHeight());
-    return area;
-}
-
-TEST(TransformedRectangle, basics) {
-    Rect r(0, 0, 100, 100);
-    Matrix4 minus90;
-    minus90.loadRotate(-90);
-    minus90.mapRect(r);
-    Rect r2(20, 40, 120, 60);
-
-    Matrix4 m90;
-    m90.loadRotate(90);
-    TransformedRectangle tr(r, m90);
-    EXPECT_TRUE(tr.canSimplyIntersectWith(tr));
-
-    Matrix4 m0;
-    TransformedRectangle tr0(r2, m0);
-    EXPECT_FALSE(tr.canSimplyIntersectWith(tr0));
-
-    Matrix4 m45;
-    m45.loadRotate(45);
-    TransformedRectangle tr2(r, m45);
-    EXPECT_FALSE(tr2.canSimplyIntersectWith(tr));
-}
-
-TEST(RectangleList, basics) {
-    RectangleList list;
-    EXPECT_TRUE(list.isEmpty());
-
-    Rect r(0, 0, 100, 100);
-    Matrix4 m45;
-    m45.loadRotate(45);
-    list.set(r, m45);
-    EXPECT_FALSE(list.isEmpty());
-
-    Rect r2(20, 20, 200, 200);
-    list.intersectWith(r2, m45);
-    EXPECT_FALSE(list.isEmpty());
-    EXPECT_EQ(1, list.getTransformedRectanglesCount());
-
-    Rect r3(20, 20, 200, 200);
-    Matrix4 m30;
-    m30.loadRotate(30);
-    list.intersectWith(r2, m30);
-    EXPECT_FALSE(list.isEmpty());
-    EXPECT_EQ(2, list.getTransformedRectanglesCount());
-
-    SkRegion clip;
-    clip.setRect(0, 0, 2000, 2000);
-    SkRegion rgn(list.convertToRegion(clip));
-    EXPECT_FALSE(rgn.isEmpty());
-}
-
-TEST(ClipArea, basics) {
-    ClipArea area(createClipArea());
-    EXPECT_FALSE(area.isEmpty());
-}
-
-TEST(ClipArea, paths) {
-    ClipArea area(createClipArea());
-    SkPath path;
-    SkScalar r = 100;
-    path.addCircle(r, r, r);
-    area.clipPathWithTransform(path, &Matrix4::identity(), SkRegion::kIntersect_Op);
-    EXPECT_FALSE(area.isEmpty());
-    EXPECT_FALSE(area.isSimple());
-    EXPECT_FALSE(area.isRectangleList());
-
-    Rect clipRect(area.getClipRect());
-    Rect expected(0, 0, r * 2, r * 2);
-    EXPECT_EQ(expected, clipRect);
-    SkRegion clipRegion(area.getClipRegion());
-    auto skRect(clipRegion.getBounds());
-    Rect regionBounds;
-    regionBounds.set(skRect);
-    EXPECT_EQ(expected, regionBounds);
-}
-
-TEST(ClipArea, replaceNegative) {
-    ClipArea area(createClipArea());
-    area.setClip(0, 0, 100, 100);
-
-    Rect expected(-50, -50, 50, 50);
-    area.clipRectWithTransform(expected, &Matrix4::identity(), SkRegion::kReplace_Op);
-    EXPECT_EQ(expected, area.getClipRect());
-}
-
-TEST(ClipArea, serializeClip) {
-    ClipArea area(createClipArea());
-    LinearAllocator allocator;
-
-    // unset clip
-    EXPECT_EQ(nullptr, area.serializeClip(allocator));
-
-    // rect clip
-    area.setClip(0, 0, 200, 200);
-    {
-        auto serializedClip = area.serializeClip(allocator);
-        ASSERT_NE(nullptr, serializedClip);
-        ASSERT_EQ(ClipMode::Rectangle, serializedClip->mode);
-        ASSERT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot";
-        EXPECT_EQ(Rect(200, 200), serializedClip->rect);
-        EXPECT_EQ(serializedClip, area.serializeClip(allocator))
-                << "Requery of clip on unmodified ClipArea must return same pointer.";
-    }
-
-    // rect list
-    Matrix4 rotate;
-    rotate.loadRotate(5.0f);
-    area.clipRectWithTransform(Rect(50, 50, 150, 150), &rotate, SkRegion::kIntersect_Op);
-    {
-        auto serializedClip = area.serializeClip(allocator);
-        ASSERT_NE(nullptr, serializedClip);
-        ASSERT_EQ(ClipMode::RectangleList, serializedClip->mode);
-        ASSERT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot";
-        auto clipRectList = reinterpret_cast<const ClipRectList*>(serializedClip);
-        EXPECT_EQ(2, clipRectList->rectList.getTransformedRectanglesCount());
-        EXPECT_EQ(Rect(37, 54, 145, 163), clipRectList->rect);
-        EXPECT_EQ(serializedClip, area.serializeClip(allocator))
-                << "Requery of clip on unmodified ClipArea must return same pointer.";
-    }
-
-    // region
-    SkPath circlePath;
-    circlePath.addCircle(100, 100, 100);
-    area.clipPathWithTransform(circlePath, &Matrix4::identity(), SkRegion::kReplace_Op);
-    {
-        auto serializedClip = area.serializeClip(allocator);
-        ASSERT_NE(nullptr, serializedClip);
-        ASSERT_EQ(ClipMode::Region, serializedClip->mode);
-        ASSERT_TRUE(serializedClip->intersectWithRoot) << "Replace op, so expect intersectWithRoot";
-        auto clipRegion = reinterpret_cast<const ClipRegion*>(serializedClip);
-        EXPECT_EQ(SkIRect::MakeWH(200, 200), clipRegion->region.getBounds())
-                << "Clip region should be 200x200";
-        EXPECT_EQ(Rect(200, 200), clipRegion->rect);
-        EXPECT_EQ(serializedClip, area.serializeClip(allocator))
-                << "Requery of clip on unmodified ClipArea must return same pointer.";
-    }
-}
-
-TEST(ClipArea, serializeClip_pathIntersectWithRoot) {
-    ClipArea area(createClipArea());
-    LinearAllocator allocator;
-    SkPath circlePath;
-    circlePath.addCircle(100, 100, 100);
-    area.clipPathWithTransform(circlePath, &Matrix4::identity(), SkRegion::kIntersect_Op);
-
-    auto serializedClip = area.serializeClip(allocator);
-    ASSERT_NE(nullptr, serializedClip);
-    EXPECT_FALSE(serializedClip->intersectWithRoot) << "No replace, so no intersectWithRoot";
-}
-
-TEST(ClipArea, serializeIntersectedClip) {
-    ClipArea area(createClipArea());
-    LinearAllocator allocator;
-
-    // simple state;
-    EXPECT_EQ(nullptr, area.serializeIntersectedClip(allocator, nullptr, Matrix4::identity()));
-    area.setClip(0, 0, 200, 200);
-    {
-        auto origRectClip = area.serializeClip(allocator);
-        ASSERT_NE(nullptr, origRectClip);
-        EXPECT_EQ(origRectClip,
-                  area.serializeIntersectedClip(allocator, nullptr, Matrix4::identity()));
-    }
-
-    // rect
-    {
-        ClipRect recordedClip(Rect(100, 100));
-        Matrix4 translateScale;
-        translateScale.loadTranslate(100, 100, 0);
-        translateScale.scale(2, 3, 1);
-        auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale);
-        ASSERT_NE(nullptr, resolvedClip);
-        ASSERT_EQ(ClipMode::Rectangle, resolvedClip->mode);
-        EXPECT_EQ(Rect(100, 100, 200, 200), resolvedClip->rect);
-
-        EXPECT_EQ(resolvedClip,
-                  area.serializeIntersectedClip(allocator, &recordedClip, translateScale))
-                << "Must return previous serialization, since input is same";
-
-        ClipRect recordedClip2(Rect(100, 100));
-        EXPECT_NE(resolvedClip,
-                  area.serializeIntersectedClip(allocator, &recordedClip2, translateScale))
-                << "Shouldn't return previous serialization, since matrix location is different";
-    }
-
-    // rect list
-    Matrix4 rotate;
-    rotate.loadRotate(2.0f);
-    area.clipRectWithTransform(Rect(200, 200), &rotate, SkRegion::kIntersect_Op);
-    {
-        ClipRect recordedClip(Rect(100, 100));
-        auto resolvedClip =
-                area.serializeIntersectedClip(allocator, &recordedClip, Matrix4::identity());
-        ASSERT_NE(nullptr, resolvedClip);
-        ASSERT_EQ(ClipMode::RectangleList, resolvedClip->mode);
-        auto clipRectList = reinterpret_cast<const ClipRectList*>(resolvedClip);
-        EXPECT_EQ(2, clipRectList->rectList.getTransformedRectanglesCount());
-    }
-
-    // region
-    SkPath circlePath;
-    circlePath.addCircle(100, 100, 100);
-    area.clipPathWithTransform(circlePath, &Matrix4::identity(), SkRegion::kReplace_Op);
-    {
-        SkPath ovalPath;
-        ovalPath.addOval(SkRect::MakeLTRB(50, 0, 150, 200));
-
-        ClipRegion recordedClip;
-        recordedClip.region.setPath(ovalPath, SkRegion(SkIRect::MakeWH(200, 200)));
-        recordedClip.rect = Rect(200, 200);
-
-        Matrix4 translate10x20;
-        translate10x20.loadTranslate(10, 20, 0);
-        auto resolvedClip = area.serializeIntersectedClip(
-                allocator, &recordedClip,
-                translate10x20);  // Note: only translate for now, others not handled correctly
-        ASSERT_NE(nullptr, resolvedClip);
-        ASSERT_EQ(ClipMode::Region, resolvedClip->mode);
-        auto clipRegion = reinterpret_cast<const ClipRegion*>(resolvedClip);
-        EXPECT_EQ(SkIRect::MakeLTRB(60, 20, 160, 200), clipRegion->region.getBounds());
-    }
-}
-
-TEST(ClipArea, serializeIntersectedClip_snap) {
-    ClipArea area(createClipArea());
-    area.setClip(100.2, 100.4, 500.6, 500.8);
-    LinearAllocator allocator;
-
-    {
-        // no recorded clip case
-        auto resolvedClip = area.serializeIntersectedClip(allocator, nullptr, Matrix4::identity());
-        EXPECT_EQ(Rect(100, 100, 501, 501), resolvedClip->rect);
-    }
-    {
-        // recorded clip case
-        ClipRect recordedClip(Rect(100.12, 100.74));
-        Matrix4 translateScale;
-        translateScale.loadTranslate(100, 100, 0);
-        translateScale.scale(2, 3,
-                             1);  // recorded clip will have non-int coords, even after transform
-        auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale);
-        ASSERT_NE(nullptr, resolvedClip);
-        EXPECT_EQ(ClipMode::Rectangle, resolvedClip->mode);
-        EXPECT_EQ(Rect(100, 100, 300, 402), resolvedClip->rect);
-    }
-}
-
-TEST(ClipArea, serializeIntersectedClip_scale) {
-    ClipArea area(createClipArea());
-    area.setClip(0, 0, 400, 400);
-    LinearAllocator allocator;
-
-    SkPath circlePath;
-    circlePath.addCircle(50, 50, 50);
-
-    ClipRegion recordedClip;
-    recordedClip.region.setPath(circlePath, SkRegion(SkIRect::MakeWH(100, 100)));
-    recordedClip.rect = Rect(100, 100);
-
-    Matrix4 translateScale;
-    translateScale.loadTranslate(100, 100, 0);
-    translateScale.scale(2, 2, 1);
-    auto resolvedClip = area.serializeIntersectedClip(allocator, &recordedClip, translateScale);
-
-    ASSERT_NE(nullptr, resolvedClip);
-    EXPECT_EQ(ClipMode::Region, resolvedClip->mode);
-    EXPECT_EQ(Rect(100, 100, 300, 300), resolvedClip->rect);
-    auto clipRegion = reinterpret_cast<const ClipRegion*>(resolvedClip);
-    EXPECT_EQ(SkIRect::MakeLTRB(100, 100, 300, 300), clipRegion->region.getBounds());
-}
-
-TEST(ClipArea, applyTransformToRegion_identity) {
-    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
-    ClipArea::applyTransformToRegion(Matrix4::identity(), &region);
-    EXPECT_TRUE(region.isRect());
-    EXPECT_EQ(SkIRect::MakeLTRB(1, 2, 3, 4), region.getBounds());
-}
-
-TEST(ClipArea, applyTransformToRegion_translate) {
-    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
-    Matrix4 transform;
-    transform.loadTranslate(10, 20, 0);
-    ClipArea::applyTransformToRegion(transform, &region);
-    EXPECT_TRUE(region.isRect());
-    EXPECT_EQ(SkIRect::MakeLTRB(11, 22, 13, 24), region.getBounds());
-}
-
-TEST(ClipArea, applyTransformToRegion_scale) {
-    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
-    Matrix4 transform;
-    transform.loadScale(2, 3, 1);
-    ClipArea::applyTransformToRegion(transform, &region);
-    EXPECT_TRUE(region.isRect());
-    EXPECT_EQ(SkIRect::MakeLTRB(2, 6, 6, 12), region.getBounds());
-}
-
-TEST(ClipArea, applyTransformToRegion_translateScale) {
-    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
-    Matrix4 transform;
-    transform.translate(10, 20);
-    transform.scale(2, 3, 1);
-    ClipArea::applyTransformToRegion(transform, &region);
-    EXPECT_TRUE(region.isRect());
-    EXPECT_EQ(SkIRect::MakeLTRB(12, 26, 16, 32), region.getBounds());
-}
-
-TEST(ClipArea, applyTransformToRegion_rotate90) {
-    SkRegion region(SkIRect::MakeLTRB(1, 2, 3, 4));
-    Matrix4 transform;
-    transform.loadRotate(90);
-    ClipArea::applyTransformToRegion(transform, &region);
-    EXPECT_TRUE(region.isRect());
-    EXPECT_EQ(SkIRect::MakeLTRB(-4, 1, -2, 3), region.getBounds());
-}
-
-}  // namespace uirenderer
-}  // namespace android
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index 2926ef3..2c73940 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -32,6 +32,7 @@
 #include "pipeline/skia/SkiaRecordingCanvas.h"
 #include "renderthread/CanvasContext.h"
 #include "tests/common/TestUtils.h"
+#include "utils/Color.h"
 
 using namespace android;
 using namespace android::uirenderer;
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index bc742b0..df5f456 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -35,23 +35,6 @@
     return bitmap;
 }
 
-/**
- * 1x1 bitmaps must not be optimized into solid color shaders, since HWUI can't
- * compose/render color shaders
- */
-TEST(SkiaBehavior, CreateBitmapShader1x1) {
-    SkBitmap origBitmap = createSkBitmap(1, 1);
-    sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(origBitmap, kNever_SkCopyPixelsMode);
-    sk_sp<SkShader> s =
-            image->makeShader(SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, nullptr);
-
-    SkBitmap bitmap;
-    SkShader::TileMode xy[2];
-    ASSERT_TRUE(s->isABitmap(&bitmap, nullptr, xy))
-            << "1x1 bitmap shader must query as bitmap shader";
-    EXPECT_EQ(origBitmap.pixelRef(), bitmap.pixelRef());
-}
-
 TEST(SkiaBehavior, genIds) {
     SkBitmap bitmap = createSkBitmap(100, 100);
     uint32_t genId = bitmap.getGenerationID();
diff --git a/libs/hwui/tests/unit/SkiaPipelineTests.cpp b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
index cdf31da..65b4e26 100644
--- a/libs/hwui/tests/unit/SkiaPipelineTests.cpp
+++ b/libs/hwui/tests/unit/SkiaPipelineTests.cpp
@@ -24,6 +24,7 @@
 #include "DamageAccumulator.h"
 #include "IContextFactory.h"
 #include "SkiaCanvas.h"
+#include "pipeline/skia/SkiaUtils.h"
 #include "pipeline/skia/SkiaDisplayList.h"
 #include "pipeline/skia/SkiaOpenGLPipeline.h"
 #include "pipeline/skia/SkiaRecordingCanvas.h"
@@ -41,7 +42,7 @@
                 redCanvas.drawColor(SK_ColorRED, SkBlendMode::kSrcOver);
             });
     LayerUpdateQueue layerUpdateQueue;
-    SkRect dirty = SkRect::MakeLargest();
+    SkRect dirty = SkRectMakeLargest();
     std::vector<sp<RenderNode>> renderNodes;
     renderNodes.push_back(redNode);
     bool opaque = true;
@@ -62,7 +63,7 @@
             });
 
     LayerUpdateQueue layerUpdateQueue;
-    SkRect dirty = SkRect::MakeLargest();
+    SkRect dirty = SkRectMakeLargest();
     std::vector<sp<RenderNode>> renderNodes;
     renderNodes.push_back(redNode);
     bool opaque = true;
@@ -97,7 +98,7 @@
                 bottomHalfGreenCanvas.drawRect(0, 1, 2, 2, greenPaint);
             });
     LayerUpdateQueue layerUpdateQueue;
-    SkRect dirty = SkRect::MakeLargest();
+    SkRect dirty = SkRectMakeLargest();
     std::vector<sp<RenderNode>> renderNodes;
     renderNodes.push_back(halfGreenNode);
     android::uirenderer::Rect contentDrawBounds(0, 0, 2, 2);
@@ -160,7 +161,7 @@
 
     // attach both layers to the update queue
     LayerUpdateQueue layerUpdateQueue;
-    SkRect dirty = SkRect::MakeLargest();
+    SkRect dirty = SkRectMakeLargest();
     layerUpdateQueue.enqueueLayerWithDamage(redNode.get(), dirty);
     layerUpdateQueue.enqueueLayerWithDamage(blueNode.get(), SkRect::MakeWH(2, 1));
     ASSERT_EQ(layerUpdateQueue.entries().size(), 2UL);
diff --git a/libs/hwui/tests/unit/SnapshotTests.cpp b/libs/hwui/tests/unit/SnapshotTests.cpp
deleted file mode 100644
index 9d673c8..0000000
--- a/libs/hwui/tests/unit/SnapshotTests.cpp
+++ /dev/null
@@ -1,74 +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 <gtest/gtest.h>
-
-#include <Snapshot.h>
-
-#include <tests/common/TestUtils.h>
-
-using namespace android::uirenderer;
-
-TEST(Snapshot, serializeIntersectedClip) {
-    auto actualRoot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 100));
-    auto root = TestUtils::makeSnapshot(Matrix4::identity(), Rect(10, 10, 90, 90));
-    auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
-    root->previous = actualRoot.get();
-    child->previous = root.get();
-
-    LinearAllocator allocator;
-    ClipRect rect(Rect(0, 0, 75, 75));
-    {
-        auto intersectWithChild =
-                child->serializeIntersectedClip(allocator, &rect, Matrix4::identity());
-        ASSERT_NE(nullptr, intersectWithChild);
-        EXPECT_EQ(Rect(50, 50, 75, 75), intersectWithChild->rect) << "Expect intersect with child";
-    }
-
-    rect.intersectWithRoot = true;
-    {
-        auto intersectWithRoot =
-                child->serializeIntersectedClip(allocator, &rect, Matrix4::identity());
-        ASSERT_NE(nullptr, intersectWithRoot);
-        EXPECT_EQ(Rect(10, 10, 75, 75), intersectWithRoot->rect) << "Expect intersect with root";
-    }
-}
-
-TEST(Snapshot, applyClip) {
-    auto actualRoot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(0, 0, 100, 100));
-    auto root = TestUtils::makeSnapshot(Matrix4::identity(), Rect(10, 10, 90, 90));
-    root->previous = actualRoot.get();
-
-    ClipRect rect(Rect(0, 0, 75, 75));
-    {
-        auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
-        child->previous = root.get();
-        child->applyClip(&rect, Matrix4::identity());
-
-        EXPECT_TRUE(child->getClipArea().isSimple());
-        EXPECT_EQ(Rect(50, 50, 75, 75), child->getRenderTargetClip());
-    }
-
-    {
-        rect.intersectWithRoot = true;
-        auto child = TestUtils::makeSnapshot(Matrix4::identity(), Rect(50, 50, 90, 90));
-        child->previous = root.get();
-        child->applyClip(&rect, Matrix4::identity());
-
-        EXPECT_TRUE(child->getClipArea().isSimple());
-        EXPECT_EQ(Rect(10, 10, 75, 75), child->getRenderTargetClip());
-    }
-}
diff --git a/libs/services/include/android/os/StatsLogEventWrapper.h b/libs/services/include/android/os/StatsLogEventWrapper.h
index 52cb75e..f60c338 100644
--- a/libs/services/include/android/os/StatsLogEventWrapper.h
+++ b/libs/services/include/android/os/StatsLogEventWrapper.h
@@ -58,6 +58,11 @@
     type = FLOAT;
   }
 
+  StatsLogValue(double v) {
+    double_value = v;
+    type = DOUBLE;
+  }
+
   StatsLogValue(const std::string& v) {
     str_value = v;
     type = STRING;
diff --git a/libs/services/src/os/StatsLogEventWrapper.cpp b/libs/services/src/os/StatsLogEventWrapper.cpp
index 04c4629..a1a6d9f 100644
--- a/libs/services/src/os/StatsLogEventWrapper.cpp
+++ b/libs/services/src/os/StatsLogEventWrapper.cpp
@@ -85,6 +85,9 @@
       case StatsLogValue::FLOAT:
         mElements.push_back(StatsLogValue(in->readFloat()));
         break;
+      case StatsLogValue::DOUBLE:
+        mElements.push_back(StatsLogValue(in->readDouble()));
+        break;
       case StatsLogValue::STORAGE:
         mElements.push_back(StatsLogValue());
         mElements.back().setType(StatsLogValue::STORAGE);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 6d10c2d..b1968ba 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -2380,10 +2380,12 @@
     }
 
     /**
+     * Return the package that implements the {@link #NETWORK_PROVIDER} functionality.
+     *
      * @hide
      */
     @SystemApi
-    public String getNetworkProviderPackage() {
+    public @Nullable String getNetworkProviderPackage() {
         try {
             return mService.getNetworkProviderPackage();
         } catch (RemoteException e) {
diff --git a/media/OWNERS b/media/OWNERS
index 1ae2a7b..0abf9ae 100644
--- a/media/OWNERS
+++ b/media/OWNERS
@@ -9,4 +9,4 @@
 wjia@google.com
 jaewan@google.com
 chz@google.com
-
+dwkang@google.com
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 38204a5..a02b6af 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -1068,6 +1068,7 @@
         ENCODING_E_AC3_JOC,
         ENCODING_DTS,
         ENCODING_DTS_HD,
+        ENCODING_MP3,
         ENCODING_IEC61937,
         ENCODING_AAC_HE_V1,
         ENCODING_AAC_HE_V2,
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 85eac4b..274da11 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -1379,14 +1379,20 @@
     //====================================================================
     // Offload query
     /**
-     * @hide
      * Returns whether offloaded playback of an audio format is supported on the device.
-     * Offloaded playback is where the decoding of an audio stream is not competing with other
-     * software resources. In general, it is supported by dedicated hardware, such as audio DSPs.
+     * <p>Offloaded playback is the feature where the decoding and playback of an audio stream
+     * is not competing with other software resources. In general, it is supported by dedicated
+     * hardware, such as audio DSPs.
+     * <p>Note that this query only provides information about the support of an audio format,
+     * it does not indicate whether the resources necessary for the offloaded playback are
+     * available at that instant.
      * @param format the audio format (codec, sample rate, channels) being checked.
      * @return true if the given audio format can be offloaded.
      */
-    public boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format) {
+    public static boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format) {
+        if (format == null) {
+            throw new IllegalArgumentException("Illegal null AudioFormat");
+        }
         return AudioSystem.isOffloadSupported(format);
     }
 
@@ -3942,18 +3948,31 @@
     }
 
      /**
-     * Indicate Hearing Aid connection state change.
+     * Indicate Hearing Aid connection state change and eventually suppress
+     * the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
      * @param device Bluetooth device connected/disconnected
      * @param state new connection state (BluetoothProfile.STATE_xxx)
+     * @param musicDevice Default get system volume for the connecting device.
+     * (either {@link android.bluetooth.BluetoothProfile.hearingaid} or
+     * {@link android.bluetooth.BluetoothProfile.HEARING_AID})
+     * @param suppressNoisyIntent if true the
+     * {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
+     * @return a delay in ms that the caller should wait before broadcasting
+     * BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED intent.
      * {@hide}
      */
-    public void setHearingAidDeviceConnectionState(BluetoothDevice device, int state) {
+    public int setBluetoothHearingAidDeviceConnectionState(
+                BluetoothDevice device, int state, boolean suppressNoisyIntent,
+                int musicDevice) {
         final IAudioService service = getService();
+        int delay = 0;
         try {
-            service.setHearingAidDeviceConnectionState(device, state);
+            delay = service.setBluetoothHearingAidDeviceConnectionState(device,
+                state, suppressNoisyIntent, musicDevice);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
+        return delay;
     }
 
      /**
@@ -4607,7 +4626,7 @@
 
     /**
      * The message sent to apps when the contents of the device list changes if they provide
-     * a {#link Handler} object to addOnAudioDeviceConnectionListener().
+     * a {@link Handler} object to addOnAudioDeviceConnectionListener().
      */
     private final static int MSG_DEVICES_CALLBACK_REGISTERED = 0;
     private final static int MSG_DEVICES_DEVICES_ADDED = 1;
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 452ba0f..2a575b6 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -473,7 +473,7 @@
      *                 .setSampleRate(32000)
      *                 .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
      *                 .build())
-     *         .setBufferSize(2*minBuffSize)
+     *         .setBufferSizeInBytes(2*minBuffSize)
      *         .build();
      * </pre>
      * <p>
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index e8fe9fe..67cc456 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.media.audiopolicy.AudioMix;
+import android.os.Build;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -864,9 +865,9 @@
     public static native int setMasterMono(boolean mono);
 
     // helpers for android.media.AudioManager.getProperty(), see description there for meaning
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 112561552)
     public static native int getPrimaryOutputSamplingRate();
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 112561552)
     public static native int getPrimaryOutputFrameCount();
     @UnsupportedAppUsage
     public static native int getOutputLatency(int stream);
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 62e58ca..3ec595d 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -23,7 +23,7 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.NioUtils;
-import java.util.Collection;
+import java.util.LinkedList;
 import java.util.concurrent.Executor;
 
 import android.annotation.CallbackExecutor;
@@ -31,16 +31,13 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.UnsupportedAppUsage;
-import android.app.ActivityThread;
-import android.content.Context;
+import android.os.Build;
+import android.os.Binder;
 import android.os.Handler;
-import android.os.IBinder;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.util.ArrayMap;
 import android.util.Log;
 
@@ -191,9 +188,8 @@
     private static final int NATIVE_EVENT_NEW_POS = 4;
     /**
      * Callback for more data
-     * TODO only for offload
      */
-    private static final int NATIVE_EVENT_MORE_DATA = 0;
+    private static final int NATIVE_EVENT_CAN_WRITE_MORE_DATA = 9;
     /**
      * IAudioTrack tear down for offloaded tracks
      * TODO: when received, java AudioTrack must be released
@@ -202,7 +198,6 @@
     /**
      * Event id denotes when all the buffers queued in AF and HW are played
      * back (after stop is called) for an offloaded track.
-     * TODO: not just for offload
      */
     private static final int NATIVE_EVENT_STREAM_END = 7;
 
@@ -392,6 +387,10 @@
      * Offset of the first sample of the audio in byte from start of HW_AV_SYNC track AV header.
      */
     private int mOffset = 0;
+    /**
+     * Indicates whether the track is intended to play in offload mode.
+     */
+    private boolean mOffloaded = false;
 
     //--------------------------------
     // Used exclusively by native code
@@ -614,6 +613,7 @@
             encoding = format.getEncoding();
         }
         audioParamCheck(rate, channelMask, channelIndexMask, encoding, mode);
+        mOffloaded = offload;
         mStreamType = AudioSystem.STREAM_DEFAULT;
 
         audioBuffSizeCheck(bufferSizeInBytes);
@@ -901,7 +901,6 @@
         }
 
         /**
-         * @hide
          * Sets whether this track will play through the offloaded audio path.
          * When set to true, at build time, the audio format will be checked against
          * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat)} to verify the audio format
@@ -960,8 +959,11 @@
                         .build();
             }
 
-            //TODO tie offload to PERFORMANCE_MODE_POWER_SAVING?    
             if (mOffload) {
+                if (mPerformanceMode == PERFORMANCE_MODE_LOW_LATENCY) {
+                    throw new UnsupportedOperationException(
+                            "Offload and low latency modes are incompatible");
+                }
                 if (mAttributes.getUsage() != AudioAttributes.USAGE_MEDIA) {
                     throw new UnsupportedOperationException(
                             "Cannot create AudioTrack, offload requires USAGE_MEDIA");
@@ -1223,6 +1225,9 @@
      * Releases the native AudioTrack resources.
      */
     public void release() {
+        synchronized (mStreamEventCbLock){
+            endStreamEventHandling();
+        }
         // even though native_release() stops the native AudioTrack, we need to stop
         // AudioTrack subclasses too.
         try {
@@ -1506,7 +1511,7 @@
      * a better solution.
      * @hide
      */
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 112561552)
     public int getLatency() {
         return native_get_latency();
     }
@@ -2282,7 +2287,8 @@
             return ERROR_BAD_VALUE;
         }
 
-        int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
+
+        final int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
                 writeMode == WRITE_BLOCKING);
 
         if ((mDataLoadMode == MODE_STATIC)
@@ -2391,7 +2397,7 @@
             return ERROR_BAD_VALUE;
         }
 
-        int ret = native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat,
+        final int ret = native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat,
                 writeMode == WRITE_BLOCKING);
 
         if ((mDataLoadMode == MODE_STATIC)
@@ -2479,7 +2485,7 @@
             return ERROR_BAD_VALUE;
         }
 
-        int ret = native_write_float(audioData, offsetInFloats, sizeInFloats, mAudioFormat,
+        final int ret = native_write_float(audioData, offsetInFloats, sizeInFloats, mAudioFormat,
                 writeMode == WRITE_BLOCKING);
 
         if ((mDataLoadMode == MODE_STATIC)
@@ -2986,68 +2992,205 @@
     }
 
     /**
-     * @hide
-     * Abstract class to receive event notification about the stream playback.
-     * See {@link AudioTrack#setStreamEventCallback(Executor, StreamEventCallback)} to register
+     * Abstract class to receive event notifications about the stream playback in offloaded mode.
+     * See {@link AudioTrack#registerStreamEventCallback(Executor, StreamEventCallback)} to register
      * the callback on the given {@link AudioTrack} instance.
      */
     public abstract static class StreamEventCallback {
-        /** @hide */ // add hidden empty constructor so it doesn't show in SDK
-        public StreamEventCallback() { }
         /**
          * Called when an offloaded track is no longer valid and has been discarded by the system.
          * An example of this happening is when an offloaded track has been paused too long, and
          * gets invalidated by the system to prevent any other offload.
-         * @param track the {@link AudioTrack} on which the event happened
+         * @param track the {@link AudioTrack} on which the event happened.
          */
         public void onTearDown(AudioTrack track) { }
         /**
          * Called when all the buffers of an offloaded track that were queued in the audio system
          * (e.g. the combination of the Android audio framework and the device's audio hardware)
          * have been played after {@link AudioTrack#stop()} has been called.
-         * @param track the {@link AudioTrack} on which the event happened
+         * @param track the {@link AudioTrack} on which the event happened.
          */
-        public void onStreamPresentationEnd(AudioTrack track) { }
+        public void onPresentationEnded(AudioTrack track) { }
         /**
          * Called when more audio data can be written without blocking on an offloaded track.
-         * @param track the {@link AudioTrack} on which the event happened
+         * @param track the {@link AudioTrack} on which the event happened.
+         * @param sizeInFrames the number of frames available to write without blocking.
+         *   Note that the frame size of a compressed stream is 1 byte.
          */
-        public void onStreamDataRequest(AudioTrack track) { }
+        public void onDataRequest(AudioTrack track, int sizeInFrames) { }
     }
 
-    private Executor mStreamEventExec;
-    private StreamEventCallback mStreamEventCb;
-    private final Object mStreamEventCbLock = new Object();
-
     /**
-     * @hide
-     * Sets the callback for the notification of stream events.
-     * @param executor {@link Executor} to handle the callbacks
-     * @param eventCallback the callback to receive the stream event notifications
+     * Registers a callback for the notification of stream events.
+     * This callback can only be registered for instances operating in offloaded mode
+     * (see {@link AudioTrack.Builder#setOffloadedPlayback(boolean)} and
+     * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat)} for more details).
+     * @param executor {@link Executor} to handle the callbacks.
+     * @param eventCallback the callback to receive the stream event notifications.
      */
-    public void setStreamEventCallback(@NonNull @CallbackExecutor Executor executor,
+    public void registerStreamEventCallback(@NonNull @CallbackExecutor Executor executor,
             @NonNull StreamEventCallback eventCallback) {
         if (eventCallback == null) {
             throw new IllegalArgumentException("Illegal null StreamEventCallback");
         }
+        if (!mOffloaded) {
+            throw new IllegalStateException(
+                    "Cannot register StreamEventCallback on non-offloaded AudioTrack");
+        }
         if (executor == null) {
             throw new IllegalArgumentException("Illegal null Executor for the StreamEventCallback");
         }
         synchronized (mStreamEventCbLock) {
-            mStreamEventExec = executor;
-            mStreamEventCb = eventCallback;
+            // check if eventCallback already in list
+            for (StreamEventCbInfo seci : mStreamEventCbInfoList) {
+                if (seci.mStreamEventCb == eventCallback) {
+                    throw new IllegalArgumentException(
+                            "StreamEventCallback already registered");
+                }
+            }
+            beginStreamEventHandling();
+            mStreamEventCbInfoList.add(new StreamEventCbInfo(executor, eventCallback));
         }
     }
 
     /**
-     * @hide
-     * Unregisters the callback for notification of stream events, previously set
-     * by {@link #setStreamEventCallback(Executor, StreamEventCallback)}.
+     * Unregisters the callback for notification of stream events, previously registered
+     * with {@link #registerStreamEventCallback(Executor, StreamEventCallback)}.
+     * @param eventCallback the callback to unregister.
      */
-    public void removeStreamEventCallback() {
+    public void unregisterStreamEventCallback(@NonNull StreamEventCallback eventCallback) {
+        if (eventCallback == null) {
+            throw new IllegalArgumentException("Illegal null StreamEventCallback");
+        }
+        if (!mOffloaded) {
+            throw new IllegalStateException("No StreamEventCallback on non-offloaded AudioTrack");
+        }
         synchronized (mStreamEventCbLock) {
-            mStreamEventExec = null;
-            mStreamEventCb = null;
+            StreamEventCbInfo seciToRemove = null;
+            for (StreamEventCbInfo seci : mStreamEventCbInfoList) {
+                if (seci.mStreamEventCb == eventCallback) {
+                    // ok to remove while iterating over list as we exit iteration
+                    mStreamEventCbInfoList.remove(seci);
+                    if (mStreamEventCbInfoList.size() == 0) {
+                        endStreamEventHandling();
+                    }
+                    return;
+                }
+            }
+            throw new IllegalArgumentException("StreamEventCallback was not registered");
+        }
+    }
+
+    //---------------------------------------------------------
+    // Offload
+    //--------------------
+    private static class StreamEventCbInfo {
+        final Executor mStreamEventExec;
+        final StreamEventCallback mStreamEventCb;
+
+        StreamEventCbInfo(Executor e, StreamEventCallback cb) {
+            mStreamEventExec = e;
+            mStreamEventCb = cb;
+        }
+    }
+
+    private final Object mStreamEventCbLock = new Object();
+    @GuardedBy("mStreamEventCbLock")
+    @NonNull private LinkedList<StreamEventCbInfo> mStreamEventCbInfoList =
+            new LinkedList<StreamEventCbInfo>();
+    /**
+     * Dedicated thread for handling the StreamEvent callbacks
+     */
+    private @Nullable HandlerThread mStreamEventHandlerThread;
+    private @Nullable volatile StreamEventHandler mStreamEventHandler;
+
+    /**
+     * Called from native AudioTrack callback thread, filter messages if necessary
+     * and repost event on AudioTrack message loop to prevent blocking native thread.
+     * @param what event code received from native
+     * @param arg optional argument for event
+     */
+    void handleStreamEventFromNative(int what, int arg) {
+        if (mStreamEventHandler == null) {
+            return;
+        }
+        switch (what) {
+            case NATIVE_EVENT_CAN_WRITE_MORE_DATA:
+                // replace previous CAN_WRITE_MORE_DATA messages with the latest value
+                mStreamEventHandler.removeMessages(NATIVE_EVENT_CAN_WRITE_MORE_DATA);
+                mStreamEventHandler.sendMessage(
+                        mStreamEventHandler.obtainMessage(
+                                NATIVE_EVENT_CAN_WRITE_MORE_DATA, arg, 0/*ignored*/));
+                break;
+            case NATIVE_EVENT_NEW_IAUDIOTRACK:
+                mStreamEventHandler.sendMessage(
+                        mStreamEventHandler.obtainMessage(NATIVE_EVENT_NEW_IAUDIOTRACK));
+                break;
+            case NATIVE_EVENT_STREAM_END:
+                mStreamEventHandler.sendMessage(
+                        mStreamEventHandler.obtainMessage(NATIVE_EVENT_STREAM_END));
+                break;
+        }
+    }
+
+    private class StreamEventHandler extends Handler {
+
+        StreamEventHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final LinkedList<StreamEventCbInfo> cbInfoList;
+            synchronized (mStreamEventCbLock) {
+                if (mStreamEventCbInfoList.size() == 0) {
+                    return;
+                }
+                cbInfoList = new LinkedList<StreamEventCbInfo>(mStreamEventCbInfoList);
+            }
+
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                for (StreamEventCbInfo cbi : cbInfoList) {
+                    switch (msg.what) {
+                        case NATIVE_EVENT_CAN_WRITE_MORE_DATA:
+                            cbi.mStreamEventExec.execute(() ->
+                                    cbi.mStreamEventCb.onDataRequest(AudioTrack.this, msg.arg1));
+                            break;
+                        case NATIVE_EVENT_NEW_IAUDIOTRACK:
+                            // TODO also release track as it's not longer usable
+                            cbi.mStreamEventExec.execute(() ->
+                                    cbi.mStreamEventCb.onTearDown(AudioTrack.this));
+                            break;
+                        case NATIVE_EVENT_STREAM_END:
+                            cbi.mStreamEventExec.execute(() ->
+                                    cbi.mStreamEventCb.onPresentationEnded(AudioTrack.this));
+                            break;
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+    }
+
+    @GuardedBy("mStreamEventCbLock")
+    private void beginStreamEventHandling() {
+        if (mStreamEventHandlerThread == null) {
+            mStreamEventHandlerThread = new HandlerThread(TAG + ".StreamEvent");
+            mStreamEventHandlerThread.start();
+            final Looper looper = mStreamEventHandlerThread.getLooper();
+            if (looper != null) {
+                mStreamEventHandler = new StreamEventHandler(looper);
+            }
+        }
+    }
+
+    @GuardedBy("mStreamEventCbLock")
+    private void endStreamEventHandling() {
+        if (mStreamEventHandlerThread != null) {
+            mStreamEventHandlerThread.quit();
+            mStreamEventHandlerThread = null;
         }
     }
 
@@ -3135,7 +3278,7 @@
     private static void postEventFromNative(Object audiotrack_ref,
             int what, int arg1, int arg2, Object obj) {
         //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
-        final AudioTrack track = (AudioTrack)((WeakReference)audiotrack_ref).get();
+        final AudioTrack track = (AudioTrack) ((WeakReference) audiotrack_ref).get();
         if (track == null) {
             return;
         }
@@ -3145,29 +3288,11 @@
             return;
         }
 
-        if (what == NATIVE_EVENT_MORE_DATA || what == NATIVE_EVENT_NEW_IAUDIOTRACK
+        if (what == NATIVE_EVENT_CAN_WRITE_MORE_DATA
+                || what == NATIVE_EVENT_NEW_IAUDIOTRACK
                 || what == NATIVE_EVENT_STREAM_END) {
-            final Executor exec;
-            final StreamEventCallback cb;
-            synchronized (track.mStreamEventCbLock) {
-                exec = track.mStreamEventExec;
-                cb = track.mStreamEventCb;
-            }
-            if ((exec == null) || (cb == null)) {
-                return;
-            }
-            switch (what) {
-                case NATIVE_EVENT_MORE_DATA:
-                    exec.execute(() -> cb.onStreamDataRequest(track));
-                    return;
-                case NATIVE_EVENT_NEW_IAUDIOTRACK:
-                    // TODO also release track as it's not longer usable
-                    exec.execute(() -> cb.onTearDown(track));
-                    return;
-                case NATIVE_EVENT_STREAM_END:
-                    exec.execute(() -> cb.onStreamPresentationEnd(track));
-                    return;
-            }
+            track.handleStreamEventFromNative(what, arg1);
+            return;
         }
 
         NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate;
@@ -3180,7 +3305,6 @@
         }
     }
 
-
     //---------------------------------------------------------
     // Native methods called from the Java side
     //--------------------
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 2395b24..b96a585 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -3252,7 +3252,7 @@
             int thumbnailLength = jpegInterchangeFormatLengthAttribute.getIntValue(mExifByteOrder);
 
             // The following code limits the size of thumbnail size not to overflow EXIF data area.
-            thumbnailLength = Math.min(thumbnailLength, in.available() - thumbnailOffset);
+            thumbnailLength = Math.min(thumbnailLength, in.getLength() - thumbnailOffset);
             if (mMimeType == IMAGE_TYPE_JPEG || mMimeType == IMAGE_TYPE_RAF
                     || mMimeType == IMAGE_TYPE_RW2) {
                 thumbnailOffset += mExifOffset;
@@ -3981,6 +3981,10 @@
         public double readDouble() throws IOException {
             return Double.longBitsToDouble(readLong());
         }
+
+        public int getLength() {
+            return mLength;
+        }
     }
 
     // An output stream to write EXIF data area, which can be written in either little or big endian
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index 569db16..abd6411 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -151,8 +151,6 @@
     void setWiredDeviceConnectionState(int type, int state, String address, String name,
             String caller);
 
-    void setHearingAidDeviceConnectionState(in BluetoothDevice device, int state);
-
     int setBluetoothA2dpDeviceConnectionState(in BluetoothDevice device, int state, int profile);
 
     void handleBluetoothA2dpDeviceConfigChange(in BluetoothDevice device);
@@ -210,6 +208,9 @@
 
     oneway void playerHasOpPlayAudio(in int piid, in boolean hasOpPlayAudio);
 
+    int setBluetoothHearingAidDeviceConnectionState(in BluetoothDevice device,
+            int state, boolean suppressNoisyIntent, int musicDevice);
+
     int setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(in BluetoothDevice device,
             int state, int profile, boolean suppressNoisyIntent, int a2dpVolume);
 
diff --git a/media/java/android/media/Image.java b/media/java/android/media/Image.java
index dff5e9a..26b9b8c 100644
--- a/media/java/android/media/Image.java
+++ b/media/java/android/media/Image.java
@@ -75,7 +75,7 @@
     /**
      * Get the format for this image. This format determines the number of
      * ByteBuffers needed to represent the image, and the general layout of the
-     * pixel data in each in ByteBuffer.
+     * pixel data in each ByteBuffer.
      *
      * <p>
      * The format is one of the values from
diff --git a/media/java/android/media/Media2HTTPService.java b/media/java/android/media/Media2HTTPService.java
index 957acec..0d46ce4 100644
--- a/media/java/android/media/Media2HTTPService.java
+++ b/media/java/android/media/Media2HTTPService.java
@@ -18,9 +18,6 @@
 
 import android.util.Log;
 
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.CookieStore;
 import java.net.HttpCookie;
 import java.util.List;
 
@@ -38,45 +35,8 @@
     public Media2HTTPConnection makeHTTPConnection() {
 
         synchronized (mCookieStoreInitialized) {
-            // Only need to do it once for all connections
-            if ( !mCookieStoreInitialized )  {
-                CookieHandler cookieHandler = CookieHandler.getDefault();
-                if (cookieHandler == null) {
-                    cookieHandler = new CookieManager();
-                    CookieHandler.setDefault(cookieHandler);
-                    Log.v(TAG, "makeHTTPConnection: CookieManager created: " + cookieHandler);
-                } else {
-                    Log.v(TAG, "makeHTTPConnection: CookieHandler (" + cookieHandler + ") exists.");
-                }
-
-                // Applying the bootstrapping cookies
-                if ( mCookies != null ) {
-                    if ( cookieHandler instanceof CookieManager ) {
-                        CookieManager cookieManager = (CookieManager)cookieHandler;
-                        CookieStore store = cookieManager.getCookieStore();
-                        for ( HttpCookie cookie : mCookies ) {
-                            try {
-                                store.add(null, cookie);
-                            } catch ( Exception e ) {
-                                Log.v(TAG, "makeHTTPConnection: CookieStore.add" + e);
-                            }
-                            //for extended debugging when needed
-                            //Log.v(TAG, "MediaHTTPConnection adding Cookie[" + cookie.getName() +
-                            //        "]: " + cookie);
-                        }
-                    } else {
-                        Log.w(TAG, "makeHTTPConnection: The installed CookieHandler is not a "
-                                + "CookieManager. Can’t add the provided cookies to the cookie "
-                                + "store.");
-                    }
-                }   // mCookies
-
-                mCookieStoreInitialized = true;
-
-                Log.v(TAG, "makeHTTPConnection(" + this + "): cookieHandler: " + cookieHandler +
-                        " Cookies: " + mCookies);
-            }   // mCookieStoreInitialized
-        }   // synchronized
+            Media2Utils.storeCookies(mCookies);
+        }
 
         return new Media2HTTPConnection();
     }
diff --git a/media/java/android/media/Media2Utils.java b/media/java/android/media/Media2Utils.java
new file mode 100644
index 0000000..066233d
--- /dev/null
+++ b/media/java/android/media/Media2Utils.java
@@ -0,0 +1,65 @@
+/*
+ * 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.media;
+
+import android.util.Log;
+
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.util.List;
+
+/** @hide */
+public class Media2Utils {
+    private static final String TAG = "Media2Utils";
+
+    private Media2Utils() {
+    }
+
+    public static synchronized void storeCookies(List<HttpCookie> cookies) {
+        CookieHandler cookieHandler = CookieHandler.getDefault();
+        if (cookieHandler == null) {
+            cookieHandler = new CookieManager();
+            CookieHandler.setDefault(cookieHandler);
+            Log.v(TAG, "storeCookies: CookieManager created: " + cookieHandler);
+        } else {
+            Log.v(TAG, "storeCookies: CookieHandler (" + cookieHandler + ") exists.");
+        }
+
+        if (cookies != null) {
+            if (cookieHandler instanceof CookieManager) {
+                CookieManager cookieManager = (CookieManager)cookieHandler;
+                CookieStore store = cookieManager.getCookieStore();
+                for (HttpCookie cookie : cookies) {
+                    try {
+                        store.add(null, cookie);
+                    } catch (Exception e) {
+                        Log.v(TAG, "storeCookies: CookieStore.add" + cookie, e);
+                    }
+                }
+            } else {
+                Log.w(TAG, "storeCookies: The installed CookieHandler is not a CookieManager."
+                        + " Can’t add the provided cookies to the cookie store.");
+            }
+        }   // cookies
+
+        Log.v(TAG, "storeCookies: cookieHandler: " + cookieHandler + " Cookies: " + cookies);
+
+    }
+
+}
diff --git a/media/java/android/media/MediaCrypto.java b/media/java/android/media/MediaCrypto.java
index 474d8b9..889a5f7 100644
--- a/media/java/android/media/MediaCrypto.java
+++ b/media/java/android/media/MediaCrypto.java
@@ -56,13 +56,15 @@
     private static final native boolean isCryptoSchemeSupportedNative(@NonNull byte[] uuid);
 
     /**
-     * Instantiate a MediaCrypto object using opaque, crypto scheme specific
-     * data.
+     * Instantiate a MediaCrypto object and associate it with a MediaDrm session
+     *
      * @param uuid The UUID of the crypto scheme.
-     * @param initData Opaque initialization data specific to the crypto scheme.
+     * @param sessionId The MediaDrm sessionId to associate with this
+     * MediaCrypto session. The sessionId may be changed after the MediaCrypto
+     * is created using {@link #setMediaDrmSession}
      */
-    public MediaCrypto(@NonNull UUID uuid, @NonNull byte[] initData) throws MediaCryptoException {
-        native_setup(getByteArrayFromUUID(uuid), initData);
+    public MediaCrypto(@NonNull UUID uuid, @NonNull byte[] sessionId) throws MediaCryptoException {
+        native_setup(getByteArrayFromUUID(uuid), sessionId);
     }
 
     /**
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 850be78..ee12b91 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -1192,17 +1192,18 @@
     public static final int SECURITY_LEVEL_HW_SECURE_ALL = 5;
 
     /**
-     * The maximum security level supported by the device. This is the default
-     * security level when a session is opened.
+     * Indicates that the maximum security level supported by the device should
+     * be used when opening a session. This is the default security level
+     * selected when a session is opened.
      * @hide
      */
     public static final int SECURITY_LEVEL_MAX = 6;
 
     /**
-     * The maximum security level supported by the device. This is the default
-     * security level when a session is opened.
+     * Returns a value that may be passed as a parameter to {@link #openSession(int)}
+     * requesting that the session be opened at the maximum security level of
+     * the device.
      */
-    @SecurityLevel
     public static final int getMaxSecurityLevel() {
         return SECURITY_LEVEL_MAX;
     }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 340f279..18d36eb 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -227,7 +227,7 @@
  *         transfers the object to the <em>Prepared</em> state once the method call
  *         returns, or a call to {@link #prepareAsync()} (asynchronous) which
  *         first transfers the object to the <em>Preparing</em> state after the
- *         call returns (which occurs almost right way) while the internal
+ *         call returns (which occurs almost right away) while the internal
  *         player engine continues working on the rest of preparation work
  *         until the preparation work completes. When the preparation completes or when {@link #prepare()} call returns,
  *         the internal player engine then calls a user supplied callback method,
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 7492aa6..e94413c 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -30,441 +30,215 @@
 import android.view.Surface;
 import android.view.SurfaceHolder;
 
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
+import dalvik.system.CloseGuard;
+
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.UUID;
 import java.util.concurrent.Executor;
 
 
 /**
  * @hide
- * MediaPlayer2 class can be used to control playback
- * of audio/video files and streams. An example on how to use the methods in
- * this class can be found in {@link android.widget.VideoView}.
+ *
+ * MediaPlayer2 class can be used to control playback of audio/video files and streams.
  *
  * <p>Topics covered here are:
  * <ol>
- * <li><a href="#StateDiagram">State Diagram</a>
- * <li><a href="#Valid_and_Invalid_States">Valid and Invalid States</a>
+ * <li><a href="#PlayerStates">Player states</a>
+ * <li><a href="#InvalidStates">Invalid method calls</a>
  * <li><a href="#Permissions">Permissions</a>
- * <li><a href="#Callbacks">Register informational and error callbacks</a>
+ * <li><a href="#Callbacks">Callbacks</a>
  * </ol>
  *
- * <div class="special reference">
- * <h3>Developer Guides</h3>
- * <p>For more information about how to use MediaPlayer2, read the
- * <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a> developer guide.</p>
- * </div>
  *
- * <a name="StateDiagram"></a>
- * <h3>State Diagram</h3>
+ * <h3 id="PlayerStates">Player states</h3>
  *
- * <p>Playback control of audio/video files and streams is managed as a state
- * machine. The following diagram shows the life cycle and the states of a
- * MediaPlayer2 object driven by the supported playback control operations.
- * The ovals represent the states a MediaPlayer2 object may reside
- * in. The arcs represent the playback control operations that drive the object
- * state transition. There are two types of arcs. The arcs with a single arrow
- * head represent synchronous method calls, while those with
- * a double arrow head represent asynchronous method calls.</p>
+ * <p>The playback control of audio/video files is managed as a state machine.</p>
+ * <p><div style="text-align:center;"><img src="../../../images/mediaplayer2_state_diagram.png"
+ *         alt="MediaPlayer2 State diagram"
+ *         border="0" /></div></p>
+ * <p>The MediaPlayer2 object has five states:</p>
+ * <ol>
+ *     <li><p>{@link #PLAYER_STATE_IDLE}: MediaPlayer2 is in the <strong>Idle</strong>
+ *         state after you create it using
+ *         {@link #create()}, or after calling {@link #reset()}.</p>
  *
- * <p><img src="../../../images/mediaplayer_state_diagram.gif"
- *         alt="MediaPlayer State diagram"
- *         border="0" /></p>
+ *         <p>While in this state, you should call
+ *         {@link #setDataSource(DataSourceDesc2) setDataSource()}. It is a good
+ *         programming practice to register an {@link EventCallback#onCallCompleted onCallCompleted}
+ *         <a href="#Callbacks">callback</a> and watch for {@link #CALL_STATUS_BAD_VALUE} and
+ *         {@link #CALL_STATUS_ERROR_IO}, which might be caused by <code>setDataSource</code>.
+ *         </p>
  *
- * <p>From this state diagram, one can see that a MediaPlayer2 object has the
- *    following states:</p>
+ *         <p>Calling {@link #prepare()} transfers a MediaPlayer2 object to
+ *         the <strong>Prepared</strong> state. Note
+ *         that {@link #prepare()} is asynchronous. When the preparation completes,
+ *         if you register an {@link EventCallback#onInfo onInfo} <a href="#Callbacks">callback</a>,
+ *         the player executes the callback
+ *         with {@link #MEDIA_INFO_PREPARED} and transitions to the
+ *         <strong>Prepared</strong> state.</p>
+ *         </li>
+ *
+ *     <li>{@link #PLAYER_STATE_PREPARED}: A MediaPlayer object must be in the
+ *         <strong>Prepared</strong> state before playback can be started for the first time.
+ *         While in this state, you can set player properties
+ *         such as audio/sound volume and looping by invoking the corresponding set methods.
+ *         Calling {@link #play()} transfers a MediaPlayer2 object to
+ *         the <strong>Playing</strong> state.
+ *      </li>
+ *
+ *     <li>{@link #PLAYER_STATE_PLAYING}:
+ *         <p>The player plays the data source while in this state.
+ *         If you register an {@link EventCallback#onInfo onInfo} <a href="#Callbacks">callback</a>,
+ *         the player regularly executes the callback with
+ *         {@link #MEDIA_INFO_BUFFERING_UPDATE}.
+ *         This allows applications to keep track of the buffering status
+ *         while streaming audio/video.</p>
+ *
+ *         <p> When the playback reaches the end of stream, the behavior depends on whether or
+ *         not you've enabled looping by calling {@link #loopCurrent(boolean) loopCurrent}:</p>
+ *         <ul>
+ *         <li>If the looping mode was set to <code>false</code>, the player will transfer
+ *         to the <strong>Paused</strong> state. If you registered an {@link EventCallback#onInfo
+ *         onInfo} <a href="#Callbacks">callback</a>
+ *         the player calls the callback with {@link #MEDIA_INFO_DATA_SOURCE_END} and enters
+ *         the <strong>Paused</strong> state.
+ *         </li>
+ *         <li>If the looping mode was set to <code>true</code>,
+ *         the MediaPlayer2 object remains in the <strong>Playing</strong> state and replays its
+ *         data source from the beginning.</li>
+ *         </ul>
+ *         </li>
+ *
+ *     <li>{@link #PLAYER_STATE_PAUSED}: Audio/video playback pauses while in this state.
+ *         Call {@link #play()} to resume playback from the position where it paused.</li>
+ *
+ *     <li>{@link #PLAYER_STATE_ERROR}: <p>In general, playback might fail due to various
+ *          reasons such as unsupported audio/video format, poorly interleaved
+ *          audio/video, resolution too high, streaming timeout, and others.
+ *          In addition, due to programming errors, a playback
+ *          control operation might be performed from an <a href="#InvalidStates">invalid state</a>.
+ *          In these cases the player transitions to the <strong>Error</strong> state.</p>
+ *
+ *          <p>If you register an {@link EventCallback#onError onError}}
+ *          <a href="#Callbacks">callback</a>,
+ *          the callback will be performed when entering the state. When programming errors happen,
+ *          such as calling {@link #prepare() prepare} and
+ *          {@link #setDataSource(DataSourceDesc) setDataSource} methods
+ *          from an <a href="#InvalidStates">invalid state</a>, the callback is called with
+ *          {@link #CALL_STATUS_INVALID_OPERATION}. The MediaPlayer2 object enters the
+ *          <strong>Error</strong> state whether or not a callback exists. </p>
+ *
+ *          <p>To recover from an error and reuse a MediaPlayer2 object that is in the <strong>
+ *          Error</strong> state,
+ *          call {@link #reset() reset}. The object will return to the <strong>Idle</strong>
+ *          state and all state information will be lost.</p>
+ *          </li>
+ * </ol>
+ *
+ * <p>You should follow these best practices when coding an app that uses MediaPlayer2:</p>
+ *
  * <ul>
- *     <li>When a MediaPlayer2 object is just created using <code>create</code> or
- *         after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
- *         {@link #close()} is called, it is in the <em>End</em> state. Between these
- *         two states is the life cycle of the MediaPlayer2 object.
- *         <ul>
- *         <li> It is a programming error to invoke methods such
- *         as {@link #getCurrentPosition()},
- *         {@link #getDuration()}, {@link #getVideoHeight()},
- *         {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
- *         {@link #setPlayerVolume(float)}, {@link #pause()}, {@link #play()},
- *         {@link #seekTo(long, int)} or
- *         {@link #prepare()} in the <em>Idle</em> state.
- *         <li>It is also recommended that once
- *         a MediaPlayer2 object is no longer being used, call {@link #close()} immediately
- *         so that resources used by the internal player engine associated with the
- *         MediaPlayer2 object can be released immediately. Resource may include
- *         singleton resources such as hardware acceleration components and
- *         failure to call {@link #close()} may cause subsequent instances of
- *         MediaPlayer2 objects to fallback to software implementations or fail
- *         altogether. Once the MediaPlayer2
- *         object is in the <em>End</em> state, it can no longer be used and
- *         there is no way to bring it back to any other state. </li>
- *         <li>Furthermore,
- *         the MediaPlayer2 objects created using <code>new</code> is in the
- *         <em>Idle</em> state.
- *         </li>
- *         </ul>
- *         </li>
- *     <li>In general, some playback control operation may fail due to various
- *         reasons, such as unsupported audio/video format, poorly interleaved
- *         audio/video, resolution too high, streaming timeout, and the like.
- *         Thus, error reporting and recovery is an important concern under
- *         these circumstances. Sometimes, due to programming errors, invoking a playback
- *         control operation in an invalid state may also occur. Under all these
- *         error conditions, the internal player engine invokes a user supplied
- *         EventCallback.onError() method if an EventCallback has been
- *         registered beforehand via
- *         {@link #setEventCallback(Executor, EventCallback)}.
- *         <ul>
- *         <li>It is important to note that once an error occurs, the
- *         MediaPlayer2 object enters the <em>Error</em> state (except as noted
- *         above), even if an error listener has not been registered by the application.</li>
- *         <li>In order to reuse a MediaPlayer2 object that is in the <em>
- *         Error</em> state and recover from the error,
- *         {@link #reset()} can be called to restore the object to its <em>Idle</em>
- *         state.</li>
- *         <li>It is good programming practice to have your application
- *         register a OnErrorListener to look out for error notifications from
- *         the internal player engine.</li>
- *         <li>IllegalStateException is
- *         thrown to prevent programming errors such as calling
- *         {@link #prepare()}, {@link #setDataSource(DataSourceDesc)}
- *         methods in an invalid state. </li>
- *         </ul>
- *         </li>
- *     <li>Calling
- *         {@link #setDataSource(DataSourceDesc)} transfers a
- *         MediaPlayer2 object in the <em>Idle</em> state to the
- *         <em>Initialized</em> state.
- *         <ul>
- *         <li>An IllegalStateException is thrown if
- *         setDataSource() is called in any other state.</li>
- *         <li>It is good programming
- *         practice to always look out for <code>IllegalArgumentException</code>
- *         and <code>IOException</code> that may be thrown from
- *         <code>setDataSource</code>.</li>
- *         </ul>
- *         </li>
- *     <li>A MediaPlayer2 object must first enter the <em>Prepared</em> state
- *         before playback can be started.
- *         <ul>
- *         <li>There are an asynchronous way that the <em>Prepared</em> state can be reached:
- *         a call to {@link #prepare()} (asynchronous) which
- *         first transfers the object to the <em>Preparing</em> state after the
- *         call returns (which occurs almost right way) while the internal
- *         player engine continues working on the rest of preparation work
- *         until the preparation work completes. When the preparation completes,
- *         the internal player engine then calls a user supplied callback method,
- *         onInfo() of the EventCallback interface with {@link #MEDIA_INFO_PREPARED},
- *         if an EventCallback is registered beforehand via
- *         {@link #setEventCallback(Executor, EventCallback)}.</li>
- *         <li>It is important to note that
- *         the <em>Preparing</em> state is a transient state, and the behavior
- *         of calling any method with side effect while a MediaPlayer2 object is
- *         in the <em>Preparing</em> state is undefined.</li>
- *         <li>An IllegalStateException is
- *         thrown if {@link #prepare()} is called in
- *         any other state.</li>
- *         <li>While in the <em>Prepared</em> state, properties
- *         such as audio/sound volume, screenOnWhilePlaying, looping can be
- *         adjusted by invoking the corresponding set methods.</li>
- *         </ul>
- *         </li>
- *     <li>To start the playback, {@link #play()} must be called. After
- *         {@link #play()} returns successfully, the MediaPlayer2 object is in the
- *         <em>Started</em> state. {@link #getPlayerState()} can be called to test
- *         whether the MediaPlayer2 object is in the <em>Started</em> state.
- *         <ul>
- *         <li>While in the <em>Started</em> state, the internal player engine calls
- *         a user supplied callback method EventCallback.onInfo() with
- *         {@link #MEDIA_INFO_BUFFERING_UPDATE} if an EventCallback has been
- *         registered beforehand via
- *         {@link #setEventCallback(Executor, EventCallback)}.
- *         This callback allows applications to keep track of the buffering status
- *         while streaming audio/video.</li>
- *         <li>Calling {@link #play()} has not effect
- *         on a MediaPlayer2 object that is already in the <em>Started</em> state.</li>
- *         </ul>
- *         </li>
- *     <li>Playback can be paused and stopped, and the current playback position
- *         can be adjusted. Playback can be paused via {@link #pause()}. When the call to
- *         {@link #pause()} returns, the MediaPlayer2 object enters the
- *         <em>Paused</em> state. Note that the transition from the <em>Started</em>
- *         state to the <em>Paused</em> state and vice versa happens
- *         asynchronously in the player engine. It may take some time before
- *         the state is updated in calls to {@link #getPlayerState()}, and it can be
- *         a number of seconds in the case of streamed content.
- *         <ul>
- *         <li>Calling {@link #play()} to resume playback for a paused
- *         MediaPlayer2 object, and the resumed playback
- *         position is the same as where it was paused. When the call to
- *         {@link #play()} returns, the paused MediaPlayer2 object goes back to
- *         the <em>Started</em> state.</li>
- *         <li>Calling {@link #pause()} has no effect on
- *         a MediaPlayer2 object that is already in the <em>Paused</em> state.</li>
- *         </ul>
- *         </li>
- *     <li>The playback position can be adjusted with a call to
- *         {@link #seekTo(long, int)}.
- *         <ul>
- *         <li>Although the asynchronuous {@link #seekTo(long, int)}
- *         call returns right away, the actual seek operation may take a while to
- *         finish, especially for audio/video being streamed. When the actual
- *         seek operation completes, the internal player engine calls a user
- *         supplied EventCallback.onCallCompleted() with
- *         {@link #CALL_COMPLETED_SEEK_TO}
- *         if an EventCallback has been registered beforehand via
- *         {@link #setEventCallback(Executor, EventCallback)}.</li>
- *         <li>Please
- *         note that {@link #seekTo(long, int)} can also be called in the other states,
- *         such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
- *         </em> state. When {@link #seekTo(long, int)} is called in those states,
- *         one video frame will be displayed if the stream has video and the requested
- *         position is valid.
- *         </li>
- *         <li>Furthermore, the actual current playback position
- *         can be retrieved with a call to {@link #getCurrentPosition()}, which
- *         is helpful for applications such as a Music player that need to keep
- *         track of the playback progress.</li>
- *         </ul>
- *         </li>
- *     <li>When the playback reaches the end of stream, the playback completes.
- *         <ul>
- *         <li>If current source is set to loop by {@link #loopCurrent(boolean)},
- *         the MediaPlayer2 object shall remain in the <em>Started</em> state.</li>
- *         <li>If the looping mode was set to <var>false
- *         </var>, the player engine calls a user supplied callback method,
- *         EventCallback.onCompletion(), if an EventCallback is
- *         registered beforehand via
- *         {@link #setEventCallback(Executor, EventCallback)}.
- *         The invoke of the callback signals that the object is now in the <em>
- *         PlaybackCompleted</em> state.</li>
- *         <li>While in the <em>PlaybackCompleted</em>
- *         state, calling {@link #play()} can restart the playback from the
- *         beginning of the audio/video source.</li>
+ *
+ * <li>Use <a href="#Callbacks">callbacks</a> to respond to state changes and errors.</li>
+ *
+ * <li>When  a MediaPlayer2 object is no longer being used, call {@link #close() close} as soon as
+ * possible to release the resources used by the internal player engine associated with the
+ * MediaPlayer2. Failure to call {@link #close() close} may cause subsequent instances of
+ * MediaPlayer2 objects to fallback to software implementations or fail altogether.
+ * You cannot use MediaPlayer2
+ * after you call {@link #close() close}. There is no way to bring it back to any other state.</li>
+ *
+ * <li>The current playback position can be retrieved with a call to
+ * {@link #getCurrentPosition() getCurrentPosition},
+ * which is helpful for applications such as a Music player that need to keep track of the playback
+ * progress.</li>
+ *
+ * <li>The playback position can be adjusted with a call to {@link #seekTo seekTo}. Although the
+ * asynchronous {@link #seekTo seekTo} call returns right away, the actual seek operation may take a
+ * while to finish, especially for audio/video being streamed. If you register an
+ * {@link EventCallback#onCallCompleted onCallCompleted} <a href="#Callbacks">callback</a>,
+ * the callback is
+ * called When the seek operation completes with {@link #CALL_COMPLETED_SEEK_TO}.</li>
+ *
+ * <li>You can call {@link #seekTo seekTo} from the <strong>Paused</strong> state.
+ * In this case, if you are playing a video stream and
+ * the requested position is valid  one video frame is displayed.</li>
+ *
  * </ul>
  *
+ * <h3 id="InvalidStates">Invalid method calls</h3>
  *
- * <a name="Valid_and_Invalid_States"></a>
- * <h3>Valid and invalid states</h3>
+ * <p>The only methods you safely call from the <strong>Error</strong> state are
+ * {@link #close() close},
+ * {@link #reset() reset},
+ * {@link #notifyWhenCommandLabelReached notifyWhenCommandLabelReached},
+ * {@link #clearPendingCommands() clearPendingCommands},
+ * {@link #setEventCallback setEventCallback},
+ * {@link #clearEventCallback() clearEventCallback}
+ * and {@link #getState() getState}.
+ * Any other methods might throw an exception, return meaningless data, or invoke a
+ * {@link EventCallback#onCallCompleted onCallCompleted} with an error code.</p>
+ *
+ * <p>Most methods can be called from any non-Error state. They will either perform their work or
+ * silently have no effect. The following table lists the methods that will invoke a
+ * {@link EventCallback#onCallCompleted onCallCompleted} with an error code
+ * or throw an exception when they are called from the associated invalid states.</p>
  *
  * <table border="0" cellspacing="0" cellpadding="0">
- * <tr><td>Method Name </p></td>
- *     <td>Valid Sates </p></td>
- *     <td>Invalid States </p></td>
- *     <td>Comments </p></td></tr>
- * <tr><td>attachAuxEffect </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
- *     <td>{Idle, Error} </p></td>
- *     <td>This method must be called after setDataSource.
- *     Calling it does not change the object state. </p></td></tr>
- * <tr><td>getAudioSessionId </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>getCurrentPosition </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted} </p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state. </p></td></tr>
- * <tr><td>getDuration </p></td>
- *     <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
- *     <td>{Idle, Initialized, Error} </p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state. </p></td></tr>
- * <tr><td>getVideoHeight </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change the
- *         state. Calling this method in an invalid state transfers the object
- *         to the <em>Error</em> state.  </p></td></tr>
- * <tr><td>getVideoWidth </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>getPlayerState </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>pause </p></td>
- *     <td>{Started, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Prepared, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Paused</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>prepare </p></td>
- *     <td>{Initialized, Stopped} </p></td>
- *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Preparing</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>release </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>After {@link #close()}, the object is no longer available. </p></td></tr>
- * <tr><td>reset </p></td>
- *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
- *         PlaybackCompleted, Error}</p></td>
- *     <td>{}</p></td>
- *     <td>After {@link #reset()}, the object is like being just created.</p></td></tr>
- * <tr><td>seekTo </p></td>
- *     <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td>
- *     <td>{Idle, Initialized, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an invalid state transfers the
- *         object to the <em>Error</em> state. </p></td></tr>
- * <tr><td>setAudioAttributes </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state. In order for the
- *         target audio attributes type to become effective, this method must be called before
- *         prepare().</p></td></tr>
- * <tr><td>setAudioSessionId </p></td>
- *     <td>{Idle} </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
- *          Error} </p></td>
- *     <td>This method must be called in idle state as the audio session ID must be known before
- *         calling setDataSource. Calling it does not change the object
- *         state. </p></td></tr>
- * <tr><td>setAudioStreamType (deprecated)</p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state. In order for the
- *         target audio stream type to become effective, this method must be called before
- *         prepare().</p></td></tr>
- * <tr><td>setAuxEffectSendLevel </p></td>
- *     <td>any</p></td>
- *     <td>{} </p></td>
- *     <td>Calling this method does not change the object state. </p></td></tr>
- * <tr><td>setDataSource </p></td>
- *     <td>{Idle} </p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
- *          Error} </p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Initialized</em> state. Calling this method in an
- *         invalid state throws an IllegalStateException.</p></td></tr>
- * <tr><td>setDisplay </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setSurface </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>loopCurrent </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *         PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method in a valid state does not change
- *         the state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>isLooping </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setDrmEventCallback </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setEventCallback </p></td>
- *     <td>any </p></td>
- *     <td>{} </p></td>
- *     <td>This method can be called in any state and calling it does not change
- *         the object state. </p></td></tr>
- * <tr><td>setPlaybackParams</p></td>
- *     <td>{Initialized, Prepared, Started, Paused, PlaybackCompleted, Error}</p></td>
- *     <td>{Idle, Stopped} </p></td>
- *     <td>This method will change state in some cases, depending on when it's called.
- *         </p></td></tr>
- * <tr><td>setPlayerVolume </p></td>
- *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
- *          PlaybackCompleted}</p></td>
- *     <td>{Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.
- * <tr><td>play </p></td>
- *     <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Stopped, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Started</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>stop </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method in a valid state transfers the
- *         object to the <em>Stopped</em> state. Calling this method in an
- *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
- * <tr><td>getTrackInfo </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>selectTrack </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
- * <tr><td>deselectTrack </p></td>
- *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
- *     <td>{Idle, Initialized, Error}</p></td>
- *     <td>Successful invoke of this method does not change the state.</p></td></tr>
+ * <tr><th>Method Name</th>
+ * <th>Invalid States</th></tr>
  *
+ * <tr><td>setDataSource</td> <td>{Prepared, Paused, Playing}</td></tr>
+ * <tr><td>prepare</td> <td>{Prepared, Paused, Playing}</td></tr>
+ * <tr><td>play</td> <td>{Idle}</td></tr>
+ * <tr><td>pause</td> <td>{Idle}</td></tr>
+ * <tr><td>seekTo</td> <td>{Idle}</td></tr>
+ * <tr><td>getCurrentPosition</td> <td>{Idle}</td></tr>
+ * <tr><td>getDuration</td> <td>{Idle}</td></tr>
+ * <tr><td>getBufferedPosition</td> <td>{Idle}</td></tr>
+ * <tr><td>getTrackInfo</td> <td>{Idle}</td></tr>
+ * <tr><td>getSelectedTrack</td> <td>{Idle}</td></tr>
+ * <tr><td>selectTrack</td> <td>{Idle}</td></tr>
+ * <tr><td>deselectTrack</td> <td>{Idle}</td></tr>
  * </table>
  *
- * <a name="Permissions"></a>
- * <h3>Permissions</h3>
- * <p>One may need to declare a corresponding WAKE_LOCK permission {@link
- * android.R.styleable#AndroidManifestUsesPermission &lt;uses-permission&gt;}
- * element.
- *
+ * <h3 id="Permissions">Permissions</h3>
  * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
  * when used with network-based content.
  *
- * <a name="Callbacks"></a>
- * <h3>Callbacks</h3>
- * <p>Applications may want to register for informational and error
- * events in order to be informed of some internal state update and
- * possible runtime errors during playback or streaming. Registration for
- * these events is done by properly setting the appropriate listeners (via calls
- * to
- * {@link #setEventCallback(Executor, EventCallback)},
- * {@link #setDrmEventCallback(Executor, DrmEventCallback)}).
- * In order to receive the respective callback
- * associated with these listeners, applications are required to create
- * MediaPlayer2 objects on a thread with its own Looper running (main UI
- * thread by default has a Looper running).
+ * <h3 id="Callbacks">Callbacks</h3>
+ * <p>Many errors do not result in a transition to the  <strong>Error</strong> state.
+ * It is good programming practice to register callback listeners using
+ * {@link #setEventCallback(Executor, EventCallback) setEventCallback} and
+ * {@link #setDrmEventCallback(Executor, DrmEventCallback) setDrmEventCallback}).
+ * You can receive a callback at any time and from any state.</p>
  *
+ * <p>If it's important for your app to respond to state changes (for instance, to update the
+ * controls on a transport UI), you should register an
+ * {@link EventCallback#onCallCompleted onCallCompleted} and
+ * detect state change commands by testing the <code>what</code> parameter for a callback from one
+ * of the state transition methods: {@link #CALL_COMPLETED_PREPARE}, {@link #CALL_COMPLETED_PLAY},
+ * and {@link #CALL_COMPLETED_PAUSE}.
+ * Then check the <code>status</code> parameter. The value {@link #CALL_STATUS_NO_ERROR} indicates a
+ * successful transition. Any other value will be an error. Call {@link #getState()} to
+ * determine the current state. </p>
  */
-public abstract class MediaPlayer2 implements SubtitleController.Listener
-                                            , AutoCloseable
+public abstract class MediaPlayer2 implements AutoCloseable
                                             , AudioRouting {
+    private final CloseGuard mGuard = CloseGuard.get();
+
     /**
      * Create a MediaPlayer2 object.
      *
      * @return A MediaPlayer2 object created
      */
-    public static final MediaPlayer2 create() {
-        // TODO: load MediaUpdate APK
-        return new MediaPlayer2Impl();
+    public static final MediaPlayer2 create(Context context) {
+        return new MediaPlayer2Impl(context);
     }
 
     private static final String[] decodeMediaPlayer2Uri(String location) {
@@ -512,7 +286,9 @@
      * @hide
      */
     // add hidden empty constructor so it doesn't show in SDK
-    public MediaPlayer2() { }
+    public MediaPlayer2() {
+        mGuard.open("close");
+    }
 
     /**
      * Returns a {@link MediaPlayerBase} implementation which runs based on
@@ -545,7 +321,22 @@
      */
     // This is a synchronous call.
     @Override
-    public abstract void close();
+    public void close() {
+        synchronized (mGuard) {
+            mGuard.close();
+        }
+    }
+
+    // Have to declare protected for finalize() since it is protected
+    // in the base class Object.
+    @Override
+    protected void finalize() throws Throwable {
+        if (mGuard != null) {
+            mGuard.warnIfOpen();
+        }
+
+        close();
+    }
 
     /**
      * Starts or resumes playback. If playback had previously been paused,
@@ -1233,50 +1024,6 @@
     public abstract MediaTimestamp getTimestamp();
 
     /**
-     * Gets the media metadata.
-     *
-     * @param update_only controls whether the full set of available
-     * metadata is returned or just the set that changed since the
-     * last call. See {@see #METADATA_UPDATE_ONLY} and {@see
-     * #METADATA_ALL}.
-     *
-     * @param apply_filter if true only metadata that matches the
-     * filter is returned. See {@see #APPLY_METADATA_FILTER} and {@see
-     * #BYPASS_METADATA_FILTER}.
-     *
-     * @return The metadata, possibly empty. null if an error occured.
-     // FIXME: unhide.
-     * {@hide}
-     */
-    public Metadata getMetadata(final boolean update_only,
-            final boolean apply_filter) {
-        return null;
-    }
-
-    /**
-     * Set a filter for the metadata update notification and update
-     * retrieval. The caller provides 2 set of metadata keys, allowed
-     * and blocked. The blocked set always takes precedence over the
-     * allowed one.
-     * Metadata.MATCH_ALL and Metadata.MATCH_NONE are 2 sets available as
-     * shorthands to allow/block all or no metadata.
-     *
-     * By default, there is no filter set.
-     *
-     * @param allow Is the set of metadata the client is interested
-     *              in receiving new notifications for.
-     * @param block Is the set of metadata the client is not interested
-     *              in receiving new notifications for.
-     * @return The call status code.
-     *
-     // FIXME: unhide.
-     * {@hide}
-     */
-    public int setMetadataFilter(Set<Integer> allow, Set<Integer> block) {
-        return 0;
-    }
-
-    /**
      * Resets the MediaPlayer2 to its uninitialized state. After calling
      * this method, you will have to initialize it again by setting the
      * data source and calling prepare().
@@ -1285,16 +1032,6 @@
     public abstract void reset();
 
     /**
-     * Set up a timer for {@link #TimeProvider}. {@link #TimeProvider} will be
-     * notified when the presentation time reaches (becomes greater than or equal to)
-     * the value specified.
-     *
-     * @param mediaTimeUs presentation time to get timed event callback at
-     * @hide
-     */
-    public void notifyAt(long mediaTimeUs) { }
-
-    /**
      * Checks whether the MediaPlayer2 is looping or non-looping.
      *
      * @return true if the MediaPlayer2 is currently looping, false otherwise
@@ -1441,95 +1178,6 @@
      */
     public static final String MEDIA_MIMETYPE_TEXT_CEA_708 = "text/cea-708";
 
-    /** @hide */
-    public void setSubtitleAnchor(
-            SubtitleController controller,
-            SubtitleController.Anchor anchor) { }
-
-    /** @hide */
-    @Override
-    public void onSubtitleTrackSelected(SubtitleTrack track) { }
-
-    /** @hide */
-    public void addSubtitleSource(InputStream is, MediaFormat format) { }
-
-    /* TODO: Limit the total number of external timed text source to a reasonable number.
-     */
-    /**
-     * Adds an external timed text source file.
-     *
-     * Currently supported format is SubRip with the file extension .srt, case insensitive.
-     * Note that a single external timed text source may contain multiple tracks in it.
-     * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
-     * additional tracks become available after this method call.
-     *
-     * @param path The file path of external timed text source file.
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
-     * @throws IOException if the file cannot be accessed or is corrupted.
-     * @throws IllegalArgumentException if the mimeType is not supported.
-     * @throws IllegalStateException if called in an invalid state.
-     * @hide
-     */
-    public void addTimedTextSource(String path, String mimeType) throws IOException { }
-
-    /**
-     * Adds an external timed text source file (Uri).
-     *
-     * Currently supported format is SubRip with the file extension .srt, case insensitive.
-     * Note that a single external timed text source may contain multiple tracks in it.
-     * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
-     * additional tracks become available after this method call.
-     *
-     * @param context the Context to use when resolving the Uri
-     * @param uri the Content URI of the data you want to play
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
-     * @throws IOException if the file cannot be accessed or is corrupted.
-     * @throws IllegalArgumentException if the mimeType is not supported.
-     * @throws IllegalStateException if called in an invalid state.
-     * @hide
-     */
-    public void addTimedTextSource(Context context, Uri uri, String mimeType) throws IOException { }
-
-    /**
-     * Adds an external timed text source file (FileDescriptor).
-     *
-     * It is the caller's responsibility to close the file descriptor.
-     * It is safe to do so as soon as this call returns.
-     *
-     * Currently supported format is SubRip. Note that a single external timed text source may
-     * contain multiple tracks in it. One can find the total number of available tracks
-     * using {@link #getTrackInfo()} to see what additional tracks become available
-     * after this method call.
-     *
-     * @param fd the FileDescriptor for the file you want to play
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
-     * @throws IllegalArgumentException if the mimeType is not supported.
-     * @throws IllegalStateException if called in an invalid state.
-     * @hide
-     */
-    public void addTimedTextSource(FileDescriptor fd, String mimeType) { }
-
-    /**
-     * Adds an external timed text file (FileDescriptor).
-     *
-     * It is the caller's responsibility to close the file descriptor.
-     * It is safe to do so as soon as this call returns.
-     *
-     * Currently supported format is SubRip. Note that a single external timed text source may
-     * contain multiple tracks in it. One can find the total number of available tracks
-     * using {@link #getTrackInfo()} to see what additional tracks become available
-     * after this method call.
-     *
-     * @param fd the FileDescriptor for the file you want to play
-     * @param offset the offset into the file where the data to be played starts, in bytes
-     * @param length the length in bytes of the data to be played
-     * @param mime The mime type of the file. Must be one of the mime types listed above.
-     * @throws IllegalArgumentException if the mimeType is not supported.
-     * @throws IllegalStateException if called in an invalid state.
-     * @hide
-     */
-    public abstract void addTimedTextSource(FileDescriptor fd, long offset, long length, String mime);
-
     /**
      * Returns the index of the audio, video, or subtitle track currently selected for playback,
      * The return value is an index into the array returned by {@link #getTrackInfo()}, and can
@@ -1597,11 +1245,6 @@
     // This is an asynchronous call.
     public abstract void deselectTrack(int index);
 
-    /** @hide */
-    public MediaTimeProvider getMediaTimeProvider() {
-        return null;
-    }
-
     /**
      * Interface definition for callbacks to be invoked when the player has the corresponding
      * events.
@@ -1883,12 +1526,6 @@
      */
     public static final int MEDIA_INFO_METADATA_UPDATE = 802;
 
-    /** A new set of external-only metadata is available.  Used by
-     *  JAVA framework to avoid triggering track scanning.
-     * @hide
-     */
-    public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
-
     /** Informs that audio is not playing. Note that playback of the video
      * is not interrupted.
      * @see EventCallback#onInfo
@@ -1937,7 +1574,6 @@
             MEDIA_INFO_BAD_INTERLEAVING,
             MEDIA_INFO_NOT_SEEKABLE,
             MEDIA_INFO_METADATA_UPDATE,
-            MEDIA_INFO_EXTERNAL_METADATA_UPDATE,
             MEDIA_INFO_AUDIO_NOT_PLAYING,
             MEDIA_INFO_VIDEO_NOT_PLAYING,
             MEDIA_INFO_TIMED_TEXT_ERROR,
@@ -2585,38 +2221,4 @@
         public static final String ERROR_CODE = "android.media.mediaplayer.errcode";
 
     }
-
-    /**
-       Constant to retrieve only the new metadata since the last
-       call.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
-     */
-    public static final boolean METADATA_UPDATE_ONLY = true;
-
-    /**
-       Constant to retrieve all the metadata.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
-     */
-    public static final boolean METADATA_ALL = false;
-
-    /**
-       Constant to enable the metadata filter during retrieval.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
-     */
-    public static final boolean APPLY_METADATA_FILTER = true;
-
-    /**
-       Constant to disable the metadata filter during retrieval.
-       // FIXME: unhide.
-       // FIXME: add link to getMetadata(boolean, boolean)
-       {@hide}
-     */
-    public static final boolean BYPASS_METADATA_FILTER = false;
-
 }
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index dfcbabe..6263e5d 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -19,18 +19,14 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.app.ActivityThread;
 import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.graphics.SurfaceTexture;
 import android.graphics.Rect;
-import android.media.MediaPlayer2Proto;
 import android.media.MediaPlayer2Proto.PlayerMessage;
 import android.media.MediaPlayer2Proto.Value;
-import android.media.SubtitleController.Anchor;
-import android.media.SubtitleTrack.RenderingWidget;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -38,26 +34,17 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.PowerManager;
-import android.os.Process;
 import android.os.SystemProperties;
 import android.provider.Settings;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Pair;
 import android.view.Surface;
 import android.view.SurfaceHolder;
-import android.widget.VideoView;
 
 import com.android.framework.protobuf.InvalidProtocolBufferException;
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.util.Preconditions;
 
-import dalvik.system.CloseGuard;
-
-import libcore.io.IoBridge;
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
@@ -72,16 +59,12 @@
 import java.nio.ByteOrder;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.BitSet;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
-import java.util.Scanner;
-import java.util.Set;
 import java.util.UUID;
-import java.util.Vector;
 import java.util.concurrent.Executor;
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -97,6 +80,8 @@
 
     private final static String TAG = "MediaPlayer2Impl";
 
+    private Context mContext;
+
     private long mNativeContext; // accessed by native methods
     private long mNativeSurfaceTexture;  // accessed by native methods
     private int mListenerContext; // accessed by native methods
@@ -105,7 +90,6 @@
     private boolean mScreenOnWhilePlaying;
     private boolean mStayAwake;
     private int mStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
-    private final CloseGuard mGuard = CloseGuard.get();
 
     private final Object mSrcLock = new Object();
     //--- guarded by |mSrcLock| start
@@ -145,22 +129,22 @@
     @GuardedBy("mTaskLock")
     private Task mCurrentTask;
 
+    @GuardedBy("this")
+    private boolean mReleased;
+
     /**
      * Default constructor.
      * <p>When done with the MediaPlayer2Impl, you should call  {@link #close()},
      * to free the resources. If not released, too many MediaPlayer2Impl instances may
      * result in an exception.</p>
      */
-    public MediaPlayer2Impl() {
+    public MediaPlayer2Impl(Context context) {
+        mContext = context;
         mHandlerThread = new HandlerThread("MediaPlayer2TaskThread");
         mHandlerThread.start();
         Looper looper = mHandlerThread.getLooper();
         mTaskHandler = new TaskHandler(this, looper);
 
-        mTimeProvider = new TimeProvider(this);
-        mOpenSubtitleSources = new Vector<InputStream>();
-        mGuard.open("close");
-
         /* Native setup requires a weak reference to our object.
          * It's easier to create it here than in C++.
          */
@@ -197,9 +181,8 @@
      */
     @Override
     public void close() {
-        synchronized (mGuard) {
-            release();
-        }
+        super.close();
+        release();
     }
 
     /**
@@ -353,7 +336,7 @@
         addTask(new Task(CALL_COMPLETED_SET_DATA_SOURCE, false) {
             @Override
             void process() throws IOException {
-                Preconditions.checkArgument(dsd != null, "the DataSourceDesc cannot be null");
+                checkArgument(dsd != null, "the DataSourceDesc cannot be null");
                 int state = getState();
                 if (state != PLAYER_STATE_ERROR && state != PLAYER_STATE_IDLE) {
                     throw new IllegalStateException("called in wrong state " + state);
@@ -379,7 +362,7 @@
         addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCE, false) {
             @Override
             void process() {
-                Preconditions.checkArgument(dsd != null, "the DataSourceDesc cannot be null");
+                checkArgument(dsd != null, "the DataSourceDesc cannot be null");
                 synchronized (mSrcLock) {
                     mNextDSDs = new ArrayList<DataSourceDesc>(1);
                     mNextDSDs.add(dsd);
@@ -477,12 +460,12 @@
             @Override
             void process() {
                 mVolume = volume;
-                _setVolume(volume, volume);
+                _setVolume(volume);
             }
         });
     }
 
-    private native void _setVolume(float leftVolume, float rightVolume);
+    private native void _setVolume(float volume);
 
     /**
      * Returns the current volume of this player to this player.
@@ -693,13 +676,15 @@
 
     private void handleDataSource(boolean isCurrent, @NonNull DataSourceDesc dsd, long srcId)
             throws IOException {
-        Preconditions.checkNotNull(dsd, "the DataSourceDesc cannot be null");
+        checkArgument(dsd != null, "the DataSourceDesc cannot be null");
 
         switch (dsd.getType()) {
             case DataSourceDesc.TYPE_CALLBACK:
                 handleDataSource(isCurrent,
                                  srcId,
-                                 dsd.getMedia2DataSource());
+                                 dsd.getMedia2DataSource(),
+                                 dsd.getStartPosition(),
+                                 dsd.getEndPosition());
                 break;
 
             case DataSourceDesc.TYPE_FD:
@@ -707,7 +692,9 @@
                                  srcId,
                                  dsd.getFileDescriptor(),
                                  dsd.getFileDescriptorOffset(),
-                                 dsd.getFileDescriptorLength());
+                                 dsd.getFileDescriptorLength(),
+                                 dsd.getStartPosition(),
+                                 dsd.getEndPosition());
                 break;
 
             case DataSourceDesc.TYPE_URI:
@@ -716,7 +703,9 @@
                                  dsd.getUriContext(),
                                  dsd.getUri(),
                                  dsd.getUriHeaders(),
-                                 dsd.getUriCookies());
+                                 dsd.getUriCookies(),
+                                 dsd.getStartPosition(),
+                                 dsd.getEndPosition());
                 break;
 
             default:
@@ -746,67 +735,77 @@
     private void handleDataSource(
             boolean isCurrent, long srcId,
             @NonNull Context context, @NonNull Uri uri,
-            @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies)
+            @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies,
+            long startPos, long endPos)
             throws IOException {
-        // The context and URI usually belong to the calling user. Get a resolver for that user
-        // and strip out the userId from the URI if present.
+        // The context and URI usually belong to the calling user. Get a resolver for that user.
         final ContentResolver resolver = context.getContentResolver();
         final String scheme = uri.getScheme();
-        final String authority = ContentProvider.getAuthorityWithoutUserId(uri.getAuthority());
         if (ContentResolver.SCHEME_FILE.equals(scheme)) {
-            handleDataSource(isCurrent, srcId, uri.getPath(), null, null);
+            handleDataSource(isCurrent, srcId, uri.getPath(), null, null, startPos, endPos);
             return;
         }
 
-        if (ContentResolver.SCHEME_CONTENT.equals(scheme)
-                && Settings.AUTHORITY.equals(authority)) {
-            // Try cached ringtone first since the actual provider may not be
-            // encryption aware, or it may be stored on CE media storage
-            final int type = RingtoneManager.getDefaultType(uri);
-            final Uri cacheUri = RingtoneManager.getCacheForType(type, context.getUserId());
-            final Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(context, type);
-            if (attemptDataSource(isCurrent, srcId, resolver, cacheUri)) {
+        final int ringToneType = RingtoneManager.getDefaultType(uri);
+        try {
+            AssetFileDescriptor afd;
+            // Try requested Uri locally first
+            if (ContentResolver.SCHEME_CONTENT.equals(scheme) && ringToneType != -1) {
+                afd = RingtoneManager.openDefaultRingtoneUri(context, uri);
+                if (attemptDataSource(isCurrent, srcId, afd, startPos, endPos)) {
+                    return;
+                }
+                final Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(
+                        context, ringToneType);
+                afd = resolver.openAssetFileDescriptor(actualUri, "r");
+            } else {
+                afd = resolver.openAssetFileDescriptor(uri, "r");
+            }
+            if (attemptDataSource(isCurrent, srcId, afd, startPos, endPos)) {
                 return;
             }
-            if (attemptDataSource(isCurrent, srcId, resolver, actualUri)) {
-                return;
-            }
-            handleDataSource(isCurrent, srcId, uri.toString(), headers, cookies);
-        } else {
-            // Try requested Uri locally first, or fallback to media server
-            if (attemptDataSource(isCurrent, srcId, resolver, uri)) {
-                return;
-            }
-            handleDataSource(isCurrent, srcId, uri.toString(), headers, cookies);
+        } catch (NullPointerException | SecurityException | IOException ex) {
+            Log.w(TAG, "Couldn't open " + uri + ": " + ex);
+            // Fallback to media server
         }
+        handleDataSource(isCurrent, srcId, uri.toString(), headers, cookies, startPos, endPos);
     }
 
-    private boolean attemptDataSource(
-            boolean isCurrent, long srcId, ContentResolver resolver, Uri uri) {
-        try (AssetFileDescriptor afd = resolver.openAssetFileDescriptor(uri, "r")) {
+    private boolean attemptDataSource(boolean isCurrent, long srcId, AssetFileDescriptor afd,
+            long startPos, long endPos) throws IOException {
+        try {
             if (afd.getDeclaredLength() < 0) {
                 handleDataSource(isCurrent,
-                                 srcId,
-                                 afd.getFileDescriptor(),
-                                 0,
-                                 DataSourceDesc.LONG_MAX);
+                        srcId,
+                        afd.getFileDescriptor(),
+                        0,
+                        DataSourceDesc.LONG_MAX,
+                        startPos,
+                        endPos);
             } else {
                 handleDataSource(isCurrent,
-                                 srcId,
-                                 afd.getFileDescriptor(),
-                                 afd.getStartOffset(),
-                                 afd.getDeclaredLength());
+                        srcId,
+                        afd.getFileDescriptor(),
+                        afd.getStartOffset(),
+                        afd.getDeclaredLength(),
+                        startPos,
+                        endPos);
             }
             return true;
         } catch (NullPointerException | SecurityException | IOException ex) {
-            Log.w(TAG, "Couldn't open " + uri + ": " + ex);
+            Log.w(TAG, "Couldn't open srcId:" + srcId + ": " + ex);
             return false;
+        } finally {
+            if (afd != null) {
+                afd.close();
+            }
         }
     }
 
     private void handleDataSource(
             boolean isCurrent, long srcId,
-            String path, Map<String, String> headers, List<HttpCookie> cookies)
+            String path, Map<String, String> headers, List<HttpCookie> cookies,
+            long startPos, long endPos)
             throws IOException {
         String[] keys = null;
         String[] values = null;
@@ -822,11 +821,12 @@
                 ++i;
             }
         }
-        handleDataSource(isCurrent, srcId, path, keys, values, cookies);
+        handleDataSource(isCurrent, srcId, path, keys, values, cookies, startPos, endPos);
     }
 
     private void handleDataSource(boolean isCurrent, long srcId,
-            String path, String[] keys, String[] values, List<HttpCookie> cookies)
+            String path, String[] keys, String[] values, List<HttpCookie> cookies,
+            long startPos, long endPos)
             throws IOException {
         final Uri uri = Uri.parse(path);
         final String scheme = uri.getScheme();
@@ -834,13 +834,16 @@
             path = uri.getPath();
         } else if (scheme != null) {
             // handle non-file sources
+            Media2Utils.storeCookies(cookies);
             nativeHandleDataSourceUrl(
                 isCurrent,
                 srcId,
-                Media2HTTPService.createHTTPService(path, cookies),
+                Media2HTTPService.createHTTPService(path),
                 path,
                 keys,
-                values);
+                values,
+                startPos,
+                endPos);
             return;
         }
 
@@ -848,7 +851,7 @@
         if (file.exists()) {
             FileInputStream is = new FileInputStream(file);
             FileDescriptor fd = is.getFD();
-            handleDataSource(isCurrent, srcId, fd, 0, DataSourceDesc.LONG_MAX);
+            handleDataSource(isCurrent, srcId, fd, 0, DataSourceDesc.LONG_MAX, startPos, endPos);
             is.close();
         } else {
             throw new IOException("handleDataSource failed.");
@@ -857,7 +860,8 @@
 
     private native void nativeHandleDataSourceUrl(
             boolean isCurrent, long srcId,
-            Media2HTTPService httpService, String path, String[] keys, String[] values)
+            Media2HTTPService httpService, String path, String[] keys, String[] values,
+            long startPos, long endPos)
             throws IOException;
 
     /**
@@ -871,23 +875,27 @@
      */
     private void handleDataSource(
             boolean isCurrent, long srcId,
-            FileDescriptor fd, long offset, long length) throws IOException {
-        nativeHandleDataSourceFD(isCurrent, srcId, fd, offset, length);
+            FileDescriptor fd, long offset, long length,
+            long startPos, long endPos) throws IOException {
+        nativeHandleDataSourceFD(isCurrent, srcId, fd, offset, length, startPos, endPos);
     }
 
     private native void nativeHandleDataSourceFD(boolean isCurrent, long srcId,
-            FileDescriptor fd, long offset, long length) throws IOException;
+            FileDescriptor fd, long offset, long length,
+            long startPos, long endPos) throws IOException;
 
     /**
      * @throws IllegalStateException if it is called in an invalid state
      * @throws IllegalArgumentException if dataSource is not a valid Media2DataSource
      */
-    private void handleDataSource(boolean isCurrent, long srcId, Media2DataSource dataSource) {
-        nativeHandleDataSourceCallback(isCurrent, srcId, dataSource);
+    private void handleDataSource(boolean isCurrent, long srcId, Media2DataSource dataSource,
+            long startPos, long endPos) {
+        nativeHandleDataSourceCallback(isCurrent, srcId, dataSource, startPos, endPos);
     }
 
     private native void nativeHandleDataSourceCallback(
-            boolean isCurrent, long srcId, Media2DataSource dataSource);
+            boolean isCurrent, long srcId, Media2DataSource dataSource,
+            long startPos, long endPos);
 
     /**
      * @return true if there is a next data source, false otherwise.
@@ -1293,7 +1301,7 @@
         addTask(new Task(CALL_COMPLETED_SET_BUFFERING_PARAMS, false) {
             @Override
             void process() {
-                Preconditions.checkArgument(params != null, "the BufferingParams cannot be null");
+                checkArgument(params != null, "the BufferingParams cannot be null");
                 _setBufferingParams(params);
             }
         });
@@ -1357,7 +1365,7 @@
         addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_PARAMS, false) {
             @Override
             void process() {
-                Preconditions.checkArgument(params != null, "the PlaybackParams cannot be null");
+                checkArgument(params != null, "the PlaybackParams cannot be null");
                 _setPlaybackParams(params);
             }
         });
@@ -1390,7 +1398,7 @@
         addTask(new Task(CALL_COMPLETED_SET_SYNC_PARAMS, false) {
             @Override
             void process() {
-                Preconditions.checkArgument(params != null, "the SyncParams cannot be null");
+                checkArgument(params != null, "the SyncParams cannot be null");
                 _setSyncParams(params);
             }
         });
@@ -1507,24 +1515,6 @@
      */
     @Override
     public void reset() {
-        mSelectedSubtitleTrackIndex = -1;
-        synchronized(mOpenSubtitleSources) {
-            for (final InputStream is: mOpenSubtitleSources) {
-                try {
-                    is.close();
-                } catch (IOException e) {
-                }
-            }
-            mOpenSubtitleSources.clear();
-        }
-        if (mSubtitleController != null) {
-            mSubtitleController.reset();
-        }
-        if (mTimeProvider != null) {
-            mTimeProvider.close();
-            mTimeProvider = null;
-        }
-
         synchronized (mEventCbLock) {
             mEventCallbackRecords.clear();
         }
@@ -1547,31 +1537,11 @@
             mTaskHandler.removeCallbacksAndMessages(null);
         }
 
-        synchronized (mIndexTrackPairs) {
-            mIndexTrackPairs.clear();
-            mInbandTrackIndices.clear();
-        };
-
         resetDrmState();
     }
 
     private native void _reset();
 
-    /**
-     * Set up a timer for {@link #TimeProvider}. {@link #TimeProvider} will be
-     * notified when the presentation time reaches (becomes greater than or equal to)
-     * the value specified.
-     *
-     * @param mediaTimeUs presentation time to get timed event callback at
-     * @hide
-     */
-    @Override
-    public void notifyAt(long mediaTimeUs) {
-        _notifyAt(mediaTimeUs);
-    }
-
-    private native void _notifyAt(long mediaTimeUs);
-
     // Keep KEY_PARAMETER_* in sync with include/media/mediaplayer2.h
     private final static int KEY_PARAMETER_AUDIO_ATTRIBUTES = 1400;
     /**
@@ -1785,16 +1755,6 @@
         }
     };
 
-    // We would like domain specific classes with more informative names than the `first` and `second`
-    // in generic Pair, but we would also like to avoid creating new/trivial classes. As a compromise
-    // we document the meanings of `first` and `second` here:
-    //
-    // Pair.first - inband track index; non-null iff representing an inband track.
-    // Pair.second - a SubtitleTrack registered with mSubtitleController; non-null iff representing
-    //               an inband subtitle track or any out-of-band track (subtitle or timedtext).
-    private Vector<Pair<Integer, SubtitleTrack>> mIndexTrackPairs = new Vector<>();
-    private BitSet mInbandTrackIndices = new BitSet();
-
     /**
      * Returns a List of track information.
      *
@@ -1806,21 +1766,7 @@
     @Override
     public List<TrackInfo> getTrackInfo() {
         TrackInfoImpl trackInfo[] = getInbandTrackInfoImpl();
-        // add out-of-band tracks
-        synchronized (mIndexTrackPairs) {
-            TrackInfoImpl allTrackInfo[] = new TrackInfoImpl[mIndexTrackPairs.size()];
-            for (int i = 0; i < allTrackInfo.length; i++) {
-                Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
-                if (p.first != null) {
-                    // inband track
-                    allTrackInfo[i] = trackInfo[p.first];
-                } else {
-                    SubtitleTrack track = p.second;
-                    allTrackInfo[i] = new TrackInfoImpl(track.getTrackType(), track.getFormat());
-                }
-            }
-            return Arrays.asList(allTrackInfo);
-        }
+        return Arrays.asList(trackInfo);
     }
 
     private TrackInfoImpl[] getInbandTrackInfoImpl() throws IllegalStateException {
@@ -1853,419 +1799,6 @@
         return false;
     }
 
-    private SubtitleController mSubtitleController;
-
-    /** @hide */
-    @Override
-    public void setSubtitleAnchor(
-            SubtitleController controller,
-            SubtitleController.Anchor anchor) {
-        // TODO: create SubtitleController in MediaPlayer2
-        mSubtitleController = controller;
-        mSubtitleController.setAnchor(anchor);
-    }
-
-    /**
-     * The private version of setSubtitleAnchor is used internally to set mSubtitleController if
-     * necessary when clients don't provide their own SubtitleControllers using the public version
-     * {@link #setSubtitleAnchor(SubtitleController, Anchor)} (e.g. {@link VideoView} provides one).
-     */
-    private synchronized void setSubtitleAnchor() {
-        if ((mSubtitleController == null) && (ActivityThread.currentApplication() != null)) {
-            final HandlerThread thread = new HandlerThread("SetSubtitleAnchorThread");
-            thread.start();
-            Handler handler = new Handler(thread.getLooper());
-            handler.post(new Runnable() {
-                @Override
-                public void run() {
-                    Context context = ActivityThread.currentApplication();
-                    mSubtitleController = new SubtitleController(context, mTimeProvider, MediaPlayer2Impl.this);
-                    mSubtitleController.setAnchor(new Anchor() {
-                        @Override
-                        public void setSubtitleWidget(RenderingWidget subtitleWidget) {
-                        }
-
-                        @Override
-                        public Looper getSubtitleLooper() {
-                            return Looper.getMainLooper();
-                        }
-                    });
-                    thread.getLooper().quitSafely();
-                }
-            });
-            try {
-                thread.join();
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-                Log.w(TAG, "failed to join SetSubtitleAnchorThread");
-            }
-        }
-    }
-
-    private int mSelectedSubtitleTrackIndex = -1;
-    private Vector<InputStream> mOpenSubtitleSources;
-
-    private EventCallback mSubtitleDataCallback = new EventCallback() {
-        @Override
-        public void onSubtitleData(MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) {
-            int index = data.getTrackIndex();
-            synchronized (mIndexTrackPairs) {
-                for (Pair<Integer, SubtitleTrack> p : mIndexTrackPairs) {
-                    if (p.first != null && p.first == index && p.second != null) {
-                        // inband subtitle track that owns data
-                        SubtitleTrack track = p.second;
-                        track.onData(data);
-                    }
-                }
-            }
-        }
-    };
-
-    /** @hide */
-    @Override
-    public void onSubtitleTrackSelected(SubtitleTrack track) {
-        if (mSelectedSubtitleTrackIndex >= 0) {
-            try {
-                selectOrDeselectInbandTrack(mSelectedSubtitleTrackIndex, false);
-            } catch (IllegalStateException e) {
-            }
-            mSelectedSubtitleTrackIndex = -1;
-        }
-        unregisterEventCallback(mSubtitleDataCallback);
-        if (track == null) {
-            return;
-        }
-
-        synchronized (mIndexTrackPairs) {
-            for (Pair<Integer, SubtitleTrack> p : mIndexTrackPairs) {
-                if (p.first != null && p.second == track) {
-                    // inband subtitle track that is selected
-                    mSelectedSubtitleTrackIndex = p.first;
-                    break;
-                }
-            }
-        }
-
-        if (mSelectedSubtitleTrackIndex >= 0) {
-            try {
-                selectOrDeselectInbandTrack(mSelectedSubtitleTrackIndex, true);
-            } catch (IllegalStateException e) {
-            }
-            final Executor executor = (runnable) -> mTaskHandler.post(runnable);
-            registerEventCallback(executor, mSubtitleDataCallback);
-        }
-        // no need to select out-of-band tracks
-    }
-
-    /** @hide */
-    @Override
-    public void addSubtitleSource(InputStream is, MediaFormat format)
-            throws IllegalStateException
-    {
-        final InputStream fIs = is;
-        final MediaFormat fFormat = format;
-
-        if (is != null) {
-            // Ensure all input streams are closed.  It is also a handy
-            // way to implement timeouts in the future.
-            synchronized(mOpenSubtitleSources) {
-                mOpenSubtitleSources.add(is);
-            }
-        } else {
-            Log.w(TAG, "addSubtitleSource called with null InputStream");
-        }
-
-        getMediaTimeProvider();
-
-        // process each subtitle in its own thread
-        final HandlerThread thread = new HandlerThread("SubtitleReadThread",
-              Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
-        thread.start();
-        Handler handler = new Handler(thread.getLooper());
-        handler.post(new Runnable() {
-            private int addTrack() {
-                if (fIs == null || mSubtitleController == null) {
-                    return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
-                }
-
-                SubtitleTrack track = mSubtitleController.addTrack(fFormat);
-                if (track == null) {
-                    return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
-                }
-
-                // TODO: do the conversion in the subtitle track
-                Scanner scanner = new Scanner(fIs, "UTF-8");
-                String contents = scanner.useDelimiter("\\A").next();
-                synchronized(mOpenSubtitleSources) {
-                    mOpenSubtitleSources.remove(fIs);
-                }
-                scanner.close();
-                synchronized (mIndexTrackPairs) {
-                    mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
-                }
-                Handler h = mTimeProvider.mEventHandler;
-                int what = TimeProvider.NOTIFY;
-                int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
-                Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, contents.getBytes());
-                Message m = h.obtainMessage(what, arg1, 0, trackData);
-                h.sendMessage(m);
-                return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
-            }
-
-            public void run() {
-                int res = addTrack();
-                if (mTaskHandler != null) {
-                    Message m = mTaskHandler.obtainMessage(MEDIA_INFO, res, 0, null);
-                    mTaskHandler.sendMessage(m);
-                }
-                thread.getLooper().quitSafely();
-            }
-        });
-    }
-
-    private void scanInternalSubtitleTracks() {
-        setSubtitleAnchor();
-
-        populateInbandTracks();
-
-        if (mSubtitleController != null) {
-            mSubtitleController.selectDefaultTrack();
-        }
-    }
-
-    private void populateInbandTracks() {
-        TrackInfoImpl[] tracks = getInbandTrackInfoImpl();
-        synchronized (mIndexTrackPairs) {
-            for (int i = 0; i < tracks.length; i++) {
-                if (mInbandTrackIndices.get(i)) {
-                    continue;
-                } else {
-                    mInbandTrackIndices.set(i);
-                }
-
-                // newly appeared inband track
-                if (tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
-                    SubtitleTrack track = mSubtitleController.addTrack(
-                            tracks[i].getFormat());
-                    mIndexTrackPairs.add(Pair.create(i, track));
-                } else {
-                    mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(i, null));
-                }
-            }
-        }
-    }
-
-    /* TODO: Limit the total number of external timed text source to a reasonable number.
-     */
-    /**
-     * Adds an external timed text source file.
-     *
-     * Currently supported format is SubRip with the file extension .srt, case insensitive.
-     * Note that a single external timed text source may contain multiple tracks in it.
-     * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
-     * additional tracks become available after this method call.
-     *
-     * @param path The file path of external timed text source file.
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
-     * @throws IOException if the file cannot be accessed or is corrupted.
-     * @throws IllegalArgumentException if the mimeType is not supported.
-     * @throws IllegalStateException if called in an invalid state.
-     * @hide
-     */
-    @Override
-    public void addTimedTextSource(String path, String mimeType)
-            throws IOException {
-        if (!availableMimeTypeForExternalSource(mimeType)) {
-            final String msg = "Illegal mimeType for timed text source: " + mimeType;
-            throw new IllegalArgumentException(msg);
-        }
-
-        File file = new File(path);
-        if (file.exists()) {
-            FileInputStream is = new FileInputStream(file);
-            FileDescriptor fd = is.getFD();
-            addTimedTextSource(fd, mimeType);
-            is.close();
-        } else {
-            // We do not support the case where the path is not a file.
-            throw new IOException(path);
-        }
-    }
-
-
-    /**
-     * Adds an external timed text source file (Uri).
-     *
-     * Currently supported format is SubRip with the file extension .srt, case insensitive.
-     * Note that a single external timed text source may contain multiple tracks in it.
-     * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
-     * additional tracks become available after this method call.
-     *
-     * @param context the Context to use when resolving the Uri
-     * @param uri the Content URI of the data you want to play
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
-     * @throws IOException if the file cannot be accessed or is corrupted.
-     * @throws IllegalArgumentException if the mimeType is not supported.
-     * @throws IllegalStateException if called in an invalid state.
-     * @hide
-     */
-    @Override
-    public void addTimedTextSource(Context context, Uri uri, String mimeType)
-            throws IOException {
-        String scheme = uri.getScheme();
-        if(scheme == null || scheme.equals("file")) {
-            addTimedTextSource(uri.getPath(), mimeType);
-            return;
-        }
-
-        AssetFileDescriptor fd = null;
-        try {
-            ContentResolver resolver = context.getContentResolver();
-            fd = resolver.openAssetFileDescriptor(uri, "r");
-            if (fd == null) {
-                return;
-            }
-            addTimedTextSource(fd.getFileDescriptor(), mimeType);
-            return;
-        } catch (SecurityException ex) {
-        } catch (IOException ex) {
-        } finally {
-            if (fd != null) {
-                fd.close();
-            }
-        }
-    }
-
-    /**
-     * Adds an external timed text source file (FileDescriptor).
-     *
-     * It is the caller's responsibility to close the file descriptor.
-     * It is safe to do so as soon as this call returns.
-     *
-     * Currently supported format is SubRip. Note that a single external timed text source may
-     * contain multiple tracks in it. One can find the total number of available tracks
-     * using {@link #getTrackInfo()} to see what additional tracks become available
-     * after this method call.
-     *
-     * @param fd the FileDescriptor for the file you want to play
-     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
-     * @throws IllegalArgumentException if the mimeType is not supported.
-     * @throws IllegalStateException if called in an invalid state.
-     * @hide
-     */
-    @Override
-    public void addTimedTextSource(FileDescriptor fd, String mimeType) {
-        // intentionally less than LONG_MAX
-        addTimedTextSource(fd, 0, 0x7ffffffffffffffL, mimeType);
-    }
-
-    /**
-     * Adds an external timed text file (FileDescriptor).
-     *
-     * It is the caller's responsibility to close the file descriptor.
-     * It is safe to do so as soon as this call returns.
-     *
-     * Currently supported format is SubRip. Note that a single external timed text source may
-     * contain multiple tracks in it. One can find the total number of available tracks
-     * using {@link #getTrackInfo()} to see what additional tracks become available
-     * after this method call.
-     *
-     * @param fd the FileDescriptor for the file you want to play
-     * @param offset the offset into the file where the data to be played starts, in bytes
-     * @param length the length in bytes of the data to be played
-     * @param mime The mime type of the file. Must be one of the mime types listed above.
-     * @throws IllegalArgumentException if the mimeType is not supported.
-     * @throws IllegalStateException if called in an invalid state.
-     * @hide
-     */
-    @Override
-    public void addTimedTextSource(FileDescriptor fd, long offset, long length, String mime) {
-        if (!availableMimeTypeForExternalSource(mime)) {
-            throw new IllegalArgumentException("Illegal mimeType for timed text source: " + mime);
-        }
-
-        final FileDescriptor dupedFd;
-        try {
-            dupedFd = Os.dup(fd);
-        } catch (ErrnoException ex) {
-            Log.e(TAG, ex.getMessage(), ex);
-            throw new RuntimeException(ex);
-        }
-
-        final MediaFormat fFormat = new MediaFormat();
-        fFormat.setString(MediaFormat.KEY_MIME, mime);
-        fFormat.setInteger(MediaFormat.KEY_IS_TIMED_TEXT, 1);
-
-        // A MediaPlayer2 created by a VideoView should already have its mSubtitleController set.
-        if (mSubtitleController == null) {
-            setSubtitleAnchor();
-        }
-
-        if (!mSubtitleController.hasRendererFor(fFormat)) {
-            // test and add not atomic
-            Context context = ActivityThread.currentApplication();
-            mSubtitleController.registerRenderer(new SRTRenderer(context, mTaskHandler));
-        }
-        final SubtitleTrack track = mSubtitleController.addTrack(fFormat);
-        synchronized (mIndexTrackPairs) {
-            mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
-        }
-
-        getMediaTimeProvider();
-
-        final long offset2 = offset;
-        final long length2 = length;
-        final HandlerThread thread = new HandlerThread(
-                "TimedTextReadThread",
-                Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
-        thread.start();
-        Handler handler = new Handler(thread.getLooper());
-        handler.post(new Runnable() {
-            private int addTrack() {
-                final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-                try {
-                    Os.lseek(dupedFd, offset2, OsConstants.SEEK_SET);
-                    byte[] buffer = new byte[4096];
-                    for (long total = 0; total < length2;) {
-                        int bytesToRead = (int) Math.min(buffer.length, length2 - total);
-                        int bytes = IoBridge.read(dupedFd, buffer, 0, bytesToRead);
-                        if (bytes < 0) {
-                            break;
-                        } else {
-                            bos.write(buffer, 0, bytes);
-                            total += bytes;
-                        }
-                    }
-                    Handler h = mTimeProvider.mEventHandler;
-                    int what = TimeProvider.NOTIFY;
-                    int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
-                    Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, bos.toByteArray());
-                    Message m = h.obtainMessage(what, arg1, 0, trackData);
-                    h.sendMessage(m);
-                    return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
-                } catch (Exception e) {
-                    Log.e(TAG, e.getMessage(), e);
-                    return MEDIA_INFO_TIMED_TEXT_ERROR;
-                } finally {
-                    try {
-                        Os.close(dupedFd);
-                    } catch (ErrnoException e) {
-                        Log.e(TAG, e.getMessage(), e);
-                    }
-                }
-            }
-
-            public void run() {
-                int res = addTrack();
-                if (mTaskHandler != null) {
-                    Message m = mTaskHandler.obtainMessage(MEDIA_INFO, res, 0, null);
-                    mTaskHandler.sendMessage(m);
-                }
-                thread.getLooper().quitSafely();
-            }
-        });
-    }
-
     /**
      * Returns the index of the audio, video, or subtitle track currently selected for playback,
      * The return value is an index into the array returned by {@link #getTrackInfo()}, and can
@@ -2285,22 +1818,6 @@
      */
     @Override
     public int getSelectedTrack(int trackType) {
-        if (mSubtitleController != null
-                && (trackType == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
-                || trackType == TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT)) {
-            SubtitleTrack subtitleTrack = mSubtitleController.getSelectedTrack();
-            if (subtitleTrack != null) {
-                synchronized (mIndexTrackPairs) {
-                    for (int i = 0; i < mIndexTrackPairs.size(); i++) {
-                        Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
-                        if (p.second == subtitleTrack && subtitleTrack.getTrackType() == trackType) {
-                            return i;
-                        }
-                    }
-                }
-            }
-        }
-
         PlayerMessage request = PlayerMessage.newBuilder()
                 .addValues(Value.newBuilder().setInt32Value(INVOKE_ID_GET_SELECTED_TRACK))
                 .addValues(Value.newBuilder().setInt32Value(trackType))
@@ -2309,16 +1826,7 @@
         if (response == null) {
             return -1;
         }
-        int inbandTrackIndex = response.getValues(0).getInt32Value();
-        synchronized (mIndexTrackPairs) {
-            for (int i = 0; i < mIndexTrackPairs.size(); i++) {
-                Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
-                if (p.first != null && p.first == inbandTrackIndex) {
-                    return i;
-                }
-            }
-        }
-        return -1;
+        return response.getValues(0).getInt32Value();
     }
 
     /**
@@ -2385,56 +1893,6 @@
 
     private void selectOrDeselectTrack(int index, boolean select)
             throws IllegalStateException {
-        // handle subtitle track through subtitle controller
-        populateInbandTracks();
-
-        Pair<Integer,SubtitleTrack> p = null;
-        try {
-            p = mIndexTrackPairs.get(index);
-        } catch (ArrayIndexOutOfBoundsException e) {
-            // ignore bad index
-            return;
-        }
-
-        SubtitleTrack track = p.second;
-        if (track == null) {
-            // inband (de)select
-            selectOrDeselectInbandTrack(p.first, select);
-            return;
-        }
-
-        if (mSubtitleController == null) {
-            return;
-        }
-
-        if (!select) {
-            // out-of-band deselect
-            if (mSubtitleController.getSelectedTrack() == track) {
-                mSubtitleController.selectTrack(null);
-            } else {
-                Log.w(TAG, "trying to deselect track that was not selected");
-            }
-            return;
-        }
-
-        // out-of-band select
-        if (track.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
-            int ttIndex = getSelectedTrack(TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT);
-            synchronized (mIndexTrackPairs) {
-                if (ttIndex >= 0 && ttIndex < mIndexTrackPairs.size()) {
-                    Pair<Integer,SubtitleTrack> p2 = mIndexTrackPairs.get(ttIndex);
-                    if (p2.first != null && p2.second == null) {
-                        // deselect inband counterpart
-                        selectOrDeselectInbandTrack(p2.first, false);
-                    }
-                }
-            }
-        }
-        mSubtitleController.selectTrack(track);
-    }
-
-    private void selectOrDeselectInbandTrack(int index, boolean select)
-            throws IllegalStateException {
         PlayerMessage request = PlayerMessage.newBuilder()
                 .addValues(Value.newBuilder().setInt32Value(
                             select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK))
@@ -2447,15 +1905,14 @@
     // in the base class Object.
     @Override
     protected void finalize() throws Throwable {
-        if (mGuard != null) {
-            mGuard.warnIfOpen();
-        }
-
-        close();
+        super.finalize();
         native_finalize();
     }
 
-    private void release() {
+    private synchronized void release() {
+        if (mReleased) {
+            return;
+        }
         stayAwake(false);
         updateSurfaceScreenOn();
         synchronized (mEventCbLock) {
@@ -2465,10 +1922,6 @@
             mHandlerThread.quitSafely();
             mHandlerThread = null;
         }
-        if (mTimeProvider != null) {
-            mTimeProvider.close();
-            mTimeProvider = null;
-        }
 
         // Modular DRM clean up
         mOnDrmConfigHelper = null;
@@ -2478,6 +1931,7 @@
         resetDrmState();
 
         _release();
+        mReleased = true;
     }
 
     private native void _release();
@@ -2504,17 +1958,6 @@
     private static final int MEDIA_DRM_INFO = 210;
     private static final int MEDIA_AUDIO_ROUTING_CHANGED = 10000;
 
-    private TimeProvider mTimeProvider;
-
-    /** @hide */
-    @Override
-    public MediaTimeProvider getMediaTimeProvider() {
-        if (mTimeProvider == null) {
-            mTimeProvider = new TimeProvider(this);
-        }
-        return mTimeProvider;
-    }
-
     private class TaskHandler extends Handler {
         private MediaPlayer2Impl mMediaPlayer;
 
@@ -2554,17 +1997,6 @@
             switch(msg.what) {
             case MEDIA_PREPARED:
             {
-                try {
-                    scanInternalSubtitleTracks();
-                } catch (RuntimeException e) {
-                    // send error message instead of crashing;
-                    // send error message instead of inlining a call to onError
-                    // to avoid code duplication.
-                    Message msg2 = obtainMessage(
-                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
-                    sendMessage(msg2);
-                }
-
                 if (dsd != null) {
                     sendEvent(new EventNotifier() {
                         @Override
@@ -2660,21 +2092,13 @@
             }
 
             case MEDIA_STOPPED:
-            {
-                TimeProvider timeProvider = mTimeProvider;
-                if (timeProvider != null) {
-                    timeProvider.onStopped();
-                }
-                break;
-            }
-
             case MEDIA_STARTED:
             case MEDIA_PAUSED:
+            case MEDIA_SKIPPED:
+            case MEDIA_NOTIFY_TIME:
             {
-                TimeProvider timeProvider = mTimeProvider;
-                if (timeProvider != null) {
-                    timeProvider.onPaused(msg.what == MEDIA_PAUSED);
-                }
+                // Do nothing. The client should have enough information with
+                // {@link EventCallback#onMediaTimeDiscontinuity}.
                 break;
             }
 
@@ -2710,15 +2134,6 @@
                         processPendingTask_l();
                     }
                 }
-            }
-                // fall through
-
-            case MEDIA_SKIPPED:
-            {
-                TimeProvider timeProvider = mTimeProvider;
-                if (timeProvider != null) {
-                    timeProvider.onSeekComplete(mMediaPlayer);
-                }
                 return;
             }
 
@@ -2763,33 +2178,6 @@
                     case MEDIA_INFO_VIDEO_TRACK_LAGGING:
                         Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")");
                         break;
-
-                    case MEDIA_INFO_METADATA_UPDATE:
-                        try {
-                            scanInternalSubtitleTracks();
-                        } catch (RuntimeException e) {
-                            Message msg2 = obtainMessage(
-                                    MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED,
-                                    null);
-                            sendMessage(msg2);
-                        }
-                        // fall through
-
-                    case MEDIA_INFO_EXTERNAL_METADATA_UPDATE:
-                        msg.arg1 = MEDIA_INFO_METADATA_UPDATE;
-                        // update default track selection
-                        if (mSubtitleController != null) {
-                            mSubtitleController.selectDefaultTrack();
-                        }
-                        break;
-
-                    case MEDIA_INFO_BUFFERING_START:
-                    case MEDIA_INFO_BUFFERING_END:
-                        TimeProvider timeProvider = mTimeProvider;
-                        if (timeProvider != null) {
-                            timeProvider.onBuffering(msg.arg1 == MEDIA_INFO_BUFFERING_START);
-                        }
-                        break;
                 }
 
                 sendEvent(new EventNotifier() {
@@ -2810,15 +2198,6 @@
                 return;
             }
 
-            case MEDIA_NOTIFY_TIME:
-            {
-                TimeProvider timeProvider = mTimeProvider;
-                if (timeProvider != null) {
-                    timeProvider.onNotifyTime();
-                }
-                return;
-            }
-
             case MEDIA_TIMED_TEXT:
             {
                 final TimedText text;
@@ -3030,6 +2409,12 @@
         }
     }
 
+    public static void checkArgument(boolean expression, String errorMessage) {
+        if (!expression) {
+            throw new IllegalArgumentException(errorMessage);
+        }
+    }
+
     private void sendEvent(final EventNotifier notifier) {
         synchronized (mEventCbLock) {
             try {
@@ -3673,7 +3058,7 @@
             supportedSchemes = new UUID[supportedDRMsCount];
             for (int i = 0; i < supportedDRMsCount; i++) {
                 byte[] uuid = new byte[16];
-                in.next().getBytesValue().copyTo(uuid, uuid.length);
+                in.next().getBytesValue().copyTo(uuid, 0);
 
                 supportedSchemes[i] = bytesToUUID(uuid);
 
@@ -3806,7 +3191,7 @@
 
     private native void _prepareDrm(@NonNull byte[] uuid, @NonNull byte[] drmSessionId);
 
-        // Modular DRM helpers
+    // Modular DRM helpers
 
     private void prepareDrm_createDrmStep(@NonNull UUID uuid)
             throws UnsupportedSchemeException {
@@ -3892,12 +3277,12 @@
         }
 
         @Override
-        public void onStreamPresentationEnd(AudioTrack track) {
+        public void onPresentationEnded(AudioTrack track) {
             native_stream_event_onStreamPresentationEnd(mNativeCallbackPtr, mUserDataPtr);
         }
 
         @Override
-        public void onStreamDataRequest(AudioTrack track) {
+        public void onDataRequest(AudioTrack track, int size) {
             native_stream_event_onStreamDataRequest(
                     mJAudioTrackPtr, mNativeCallbackPtr, mUserDataPtr);
         }
@@ -4239,396 +3624,6 @@
         }
     }
 
-    /** @hide */
-    static class TimeProvider implements MediaTimeProvider {
-        private static final String TAG = "MTP";
-        private static final long MAX_NS_WITHOUT_POSITION_CHECK = 5000000000L;
-        private static final long MAX_EARLY_CALLBACK_US = 1000;
-        private static final long TIME_ADJUSTMENT_RATE = 2;  /* meaning 1/2 */
-        private long mLastTimeUs = 0;
-        private MediaPlayer2Impl mPlayer;
-        private boolean mPaused = true;
-        private boolean mStopped = true;
-        private boolean mBuffering;
-        private long mLastReportedTime;
-        // since we are expecting only a handful listeners per stream, there is
-        // no need for log(N) search performance
-        private MediaTimeProvider.OnMediaTimeListener mListeners[];
-        private long mTimes[];
-        private EventHandler mEventHandler;
-        private boolean mRefresh = false;
-        private boolean mPausing = false;
-        private boolean mSeeking = false;
-        private static final int NOTIFY = 1;
-        private static final int NOTIFY_TIME = 0;
-        private static final int NOTIFY_STOP = 2;
-        private static final int NOTIFY_SEEK = 3;
-        private static final int NOTIFY_TRACK_DATA = 4;
-        private HandlerThread mHandlerThread;
-
-        /** @hide */
-        public boolean DEBUG = false;
-
-        public TimeProvider(MediaPlayer2Impl mp) {
-            mPlayer = mp;
-            try {
-                getCurrentTimeUs(true, false);
-            } catch (IllegalStateException e) {
-                // we assume starting position
-                mRefresh = true;
-            }
-
-            Looper looper;
-            if ((looper = Looper.myLooper()) == null &&
-                (looper = Looper.getMainLooper()) == null) {
-                // Create our own looper here in case MP was created without one
-                mHandlerThread = new HandlerThread("MediaPlayer2MTPEventThread",
-                      Process.THREAD_PRIORITY_FOREGROUND);
-                mHandlerThread.start();
-                looper = mHandlerThread.getLooper();
-            }
-            mEventHandler = new EventHandler(looper);
-
-            mListeners = new MediaTimeProvider.OnMediaTimeListener[0];
-            mTimes = new long[0];
-            mLastTimeUs = 0;
-        }
-
-        private void scheduleNotification(int type, long delayUs) {
-            // ignore time notifications until seek is handled
-            if (mSeeking && type == NOTIFY_TIME) {
-                return;
-            }
-
-            if (DEBUG) Log.v(TAG, "scheduleNotification " + type + " in " + delayUs);
-            mEventHandler.removeMessages(NOTIFY);
-            Message msg = mEventHandler.obtainMessage(NOTIFY, type, 0);
-            mEventHandler.sendMessageDelayed(msg, (int) (delayUs / 1000));
-        }
-
-        /** @hide */
-        public void close() {
-            mEventHandler.removeMessages(NOTIFY);
-            if (mHandlerThread != null) {
-                mHandlerThread.quitSafely();
-                mHandlerThread = null;
-            }
-        }
-
-        /** @hide */
-        protected void finalize() {
-            if (mHandlerThread != null) {
-                mHandlerThread.quitSafely();
-            }
-        }
-
-        /** @hide */
-        public void onNotifyTime() {
-            synchronized (this) {
-                if (DEBUG) Log.d(TAG, "onNotifyTime: ");
-                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
-            }
-        }
-
-        /** @hide */
-        public void onPaused(boolean paused) {
-            synchronized(this) {
-                if (DEBUG) Log.d(TAG, "onPaused: " + paused);
-                if (mStopped) { // handle as seek if we were stopped
-                    mStopped = false;
-                    mSeeking = true;
-                    scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
-                } else {
-                    mPausing = paused;  // special handling if player disappeared
-                    mSeeking = false;
-                    scheduleNotification(NOTIFY_TIME, 0 /* delay */);
-                }
-            }
-        }
-
-        /** @hide */
-        public void onBuffering(boolean buffering) {
-            synchronized (this) {
-                if (DEBUG) Log.d(TAG, "onBuffering: " + buffering);
-                mBuffering = buffering;
-                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
-            }
-        }
-
-        /** @hide */
-        public void onStopped() {
-            synchronized(this) {
-                if (DEBUG) Log.d(TAG, "onStopped");
-                mPaused = true;
-                mStopped = true;
-                mSeeking = false;
-                mBuffering = false;
-                scheduleNotification(NOTIFY_STOP, 0 /* delay */);
-            }
-        }
-
-        /** @hide */
-        public void onSeekComplete(MediaPlayer2Impl mp) {
-            synchronized(this) {
-                mStopped = false;
-                mSeeking = true;
-                scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
-            }
-        }
-
-        /** @hide */
-        public void onNewPlayer() {
-            if (mRefresh) {
-                synchronized(this) {
-                    mStopped = false;
-                    mSeeking = true;
-                    mBuffering = false;
-                    scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
-                }
-            }
-        }
-
-        private synchronized void notifySeek() {
-            mSeeking = false;
-            try {
-                long timeUs = getCurrentTimeUs(true, false);
-                if (DEBUG) Log.d(TAG, "onSeekComplete at " + timeUs);
-
-                for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
-                    if (listener == null) {
-                        break;
-                    }
-                    listener.onSeek(timeUs);
-                }
-            } catch (IllegalStateException e) {
-                // we should not be there, but at least signal pause
-                if (DEBUG) Log.d(TAG, "onSeekComplete but no player");
-                mPausing = true;  // special handling if player disappeared
-                notifyTimedEvent(false /* refreshTime */);
-            }
-        }
-
-        private synchronized void notifyTrackData(Pair<SubtitleTrack, byte[]> trackData) {
-            SubtitleTrack track = trackData.first;
-            byte[] data = trackData.second;
-            track.onData(data, true /* eos */, ~0 /* runID: keep forever */);
-        }
-
-        private synchronized void notifyStop() {
-            for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
-                if (listener == null) {
-                    break;
-                }
-                listener.onStop();
-            }
-        }
-
-        private int registerListener(MediaTimeProvider.OnMediaTimeListener listener) {
-            int i = 0;
-            for (; i < mListeners.length; i++) {
-                if (mListeners[i] == listener || mListeners[i] == null) {
-                    break;
-                }
-            }
-
-            // new listener
-            if (i >= mListeners.length) {
-                MediaTimeProvider.OnMediaTimeListener[] newListeners =
-                    new MediaTimeProvider.OnMediaTimeListener[i + 1];
-                long[] newTimes = new long[i + 1];
-                System.arraycopy(mListeners, 0, newListeners, 0, mListeners.length);
-                System.arraycopy(mTimes, 0, newTimes, 0, mTimes.length);
-                mListeners = newListeners;
-                mTimes = newTimes;
-            }
-
-            if (mListeners[i] == null) {
-                mListeners[i] = listener;
-                mTimes[i] = MediaTimeProvider.NO_TIME;
-            }
-            return i;
-        }
-
-        public void notifyAt(
-                long timeUs, MediaTimeProvider.OnMediaTimeListener listener) {
-            synchronized(this) {
-                if (DEBUG) Log.d(TAG, "notifyAt " + timeUs);
-                mTimes[registerListener(listener)] = timeUs;
-                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
-            }
-        }
-
-        public void scheduleUpdate(MediaTimeProvider.OnMediaTimeListener listener) {
-            synchronized(this) {
-                if (DEBUG) Log.d(TAG, "scheduleUpdate");
-                int i = registerListener(listener);
-
-                if (!mStopped) {
-                    mTimes[i] = 0;
-                    scheduleNotification(NOTIFY_TIME, 0 /* delay */);
-                }
-            }
-        }
-
-        public void cancelNotifications(
-                MediaTimeProvider.OnMediaTimeListener listener) {
-            synchronized(this) {
-                int i = 0;
-                for (; i < mListeners.length; i++) {
-                    if (mListeners[i] == listener) {
-                        System.arraycopy(mListeners, i + 1,
-                                mListeners, i, mListeners.length - i - 1);
-                        System.arraycopy(mTimes, i + 1,
-                                mTimes, i, mTimes.length - i - 1);
-                        mListeners[mListeners.length - 1] = null;
-                        mTimes[mTimes.length - 1] = NO_TIME;
-                        break;
-                    } else if (mListeners[i] == null) {
-                        break;
-                    }
-                }
-
-                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
-            }
-        }
-
-        private synchronized void notifyTimedEvent(boolean refreshTime) {
-            // figure out next callback
-            long nowUs;
-            try {
-                nowUs = getCurrentTimeUs(refreshTime, true);
-            } catch (IllegalStateException e) {
-                // assume we paused until new player arrives
-                mRefresh = true;
-                mPausing = true; // this ensures that call succeeds
-                nowUs = getCurrentTimeUs(refreshTime, true);
-            }
-            long nextTimeUs = nowUs;
-
-            if (mSeeking) {
-                // skip timed-event notifications until seek is complete
-                return;
-            }
-
-            if (DEBUG) {
-                StringBuilder sb = new StringBuilder();
-                sb.append("notifyTimedEvent(").append(mLastTimeUs).append(" -> ")
-                        .append(nowUs).append(") from {");
-                boolean first = true;
-                for (long time: mTimes) {
-                    if (time == NO_TIME) {
-                        continue;
-                    }
-                    if (!first) sb.append(", ");
-                    sb.append(time);
-                    first = false;
-                }
-                sb.append("}");
-                Log.d(TAG, sb.toString());
-            }
-
-            Vector<MediaTimeProvider.OnMediaTimeListener> activatedListeners =
-                new Vector<MediaTimeProvider.OnMediaTimeListener>();
-            for (int ix = 0; ix < mTimes.length; ix++) {
-                if (mListeners[ix] == null) {
-                    break;
-                }
-                if (mTimes[ix] <= NO_TIME) {
-                    // ignore, unless we were stopped
-                } else if (mTimes[ix] <= nowUs + MAX_EARLY_CALLBACK_US) {
-                    activatedListeners.add(mListeners[ix]);
-                    if (DEBUG) Log.d(TAG, "removed");
-                    mTimes[ix] = NO_TIME;
-                } else if (nextTimeUs == nowUs || mTimes[ix] < nextTimeUs) {
-                    nextTimeUs = mTimes[ix];
-                }
-            }
-
-            if (nextTimeUs > nowUs && !mPaused) {
-                // schedule callback at nextTimeUs
-                if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs);
-                mPlayer.notifyAt(nextTimeUs);
-            } else {
-                mEventHandler.removeMessages(NOTIFY);
-                // no more callbacks
-            }
-
-            for (MediaTimeProvider.OnMediaTimeListener listener: activatedListeners) {
-                listener.onTimedEvent(nowUs);
-            }
-        }
-
-        public long getCurrentTimeUs(boolean refreshTime, boolean monotonic)
-                throws IllegalStateException {
-            synchronized (this) {
-                // we always refresh the time when the paused-state changes, because
-                // we expect to have received the pause-change event delayed.
-                if (mPaused && !refreshTime) {
-                    return mLastReportedTime;
-                }
-
-                try {
-                    mLastTimeUs = mPlayer.getCurrentPosition() * 1000L;
-                    mPaused = !mPlayer.isPlaying() || mBuffering;
-                    if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
-                } catch (IllegalStateException e) {
-                    if (mPausing) {
-                        // if we were pausing, get last estimated timestamp
-                        mPausing = false;
-                        if (!monotonic || mLastReportedTime < mLastTimeUs) {
-                            mLastReportedTime = mLastTimeUs;
-                        }
-                        mPaused = true;
-                        if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime);
-                        return mLastReportedTime;
-                    }
-                    // TODO get time when prepared
-                    throw e;
-                }
-                if (monotonic && mLastTimeUs < mLastReportedTime) {
-                    /* have to adjust time */
-                    if (mLastReportedTime - mLastTimeUs > 1000000) {
-                        // schedule seeked event if time jumped significantly
-                        // TODO: do this properly by introducing an exception
-                        mStopped = false;
-                        mSeeking = true;
-                        scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
-                    }
-                } else {
-                    mLastReportedTime = mLastTimeUs;
-                }
-
-                return mLastReportedTime;
-            }
-        }
-
-        private class EventHandler extends Handler {
-            public EventHandler(Looper looper) {
-                super(looper);
-            }
-
-            @Override
-            public void handleMessage(Message msg) {
-                if (msg.what == NOTIFY) {
-                    switch (msg.arg1) {
-                    case NOTIFY_TIME:
-                        notifyTimedEvent(true /* refreshTime */);
-                        break;
-                    case NOTIFY_STOP:
-                        notifyStop();
-                        break;
-                    case NOTIFY_SEEK:
-                        notifySeek();
-                        break;
-                    case NOTIFY_TRACK_DATA:
-                        notifyTrackData((Pair<SubtitleTrack, byte[]>)msg.obj);
-                        break;
-                    }
-                }
-            }
-        }
-    }
-
     private abstract class Task implements Runnable {
         private final int mMediaCallType;
         private final boolean mNeedToWaitForEventToComplete;
@@ -4649,6 +3644,17 @@
                         && getState() == PLAYER_STATE_ERROR) {
                     status = CALL_STATUS_INVALID_OPERATION;
                 } else {
+                    if (mMediaCallType == CALL_COMPLETED_SEEK_TO) {
+                        synchronized (mTaskLock) {
+                            if (!mPendingTasks.isEmpty()) {
+                                Task nextTask = mPendingTasks.get(0);
+                                if (nextTask.mMediaCallType == mMediaCallType) {
+                                    throw new CommandSkippedException(
+                                            "consecutive seekTo is skipped except last one");
+                                }
+                            }
+                        }
+                    }
                     process();
                 }
             } catch (IllegalStateException e) {
@@ -4684,7 +3690,7 @@
 
         private void sendCompleteNotification(int status) {
             // In {@link #notifyWhenCommandLabelReached} case, a separate callback
-            // {#link #onCommandLabelReached} is already called in {@code process()}.
+            // {@link #onCommandLabelReached} is already called in {@code process()}.
             if (mMediaCallType == CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED) {
                 return;
             }
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 66feb1d..8664aa1 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -31,6 +31,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
+import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
 import android.media.MediaScannerConnection.MediaScannerConnectionClient;
 import android.net.Uri;
@@ -1128,6 +1129,38 @@
     }
 
     /**
+     * Opens a raw file descriptor to read the data under the given default URI.
+     *
+     * @param context the Context to use when resolving the Uri.
+     * @param uri The desired default URI to open.
+     * @return a new AssetFileDescriptor pointing to the file. You own this descriptor
+     * and are responsible for closing it when done. This value may be {@code null}.
+     * @throws FileNotFoundException if the provided URI could not be opened.
+     * @see #getDefaultUri
+     */
+    public static AssetFileDescriptor openDefaultRingtoneUri(
+            @NonNull Context context, @NonNull Uri uri) throws FileNotFoundException {
+        // Try cached ringtone first since the actual provider may not be
+        // encryption aware, or it may be stored on CE media storage
+        final int type = getDefaultType(uri);
+        final Uri cacheUri = getCacheForType(type, context.getUserId());
+        final Uri actualUri = getActualDefaultRingtoneUri(context, type);
+        final ContentResolver resolver = context.getContentResolver();
+
+        AssetFileDescriptor afd = null;
+        if (cacheUri != null) {
+            afd = resolver.openAssetFileDescriptor(cacheUri, "r");
+            if (afd != null) {
+                return afd;
+            }
+        }
+        if (actualUri != null) {
+            afd = resolver.openAssetFileDescriptor(actualUri, "r");
+        }
+        return afd;
+    }
+
+    /**
      * Creates a {@link android.media.MediaScannerConnection} to scan a ringtone file and add its
      * information to the internal database.
      *
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 4cc86fd..fd14060 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -160,7 +160,15 @@
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
         try {
             retriever.setDataSource(filePath);
-            bitmap = retriever.getFrameAtTime(-1);
+            // First retrieve album art in metadata if set.
+            byte[] embeddedPicture = retriever.getEmbeddedPicture();
+            if (embeddedPicture != null && embeddedPicture.length > 0) {
+                bitmap = BitmapFactory.decodeByteArray(embeddedPicture, 0, embeddedPicture.length);
+            }
+            // Fall back to first frame of the video.
+            if (bitmap == null) {
+                bitmap = retriever.getFrameAtTime(-1);
+            }
         } catch (IllegalArgumentException ex) {
             // Assume this is a corrupt video file
         } catch (RuntimeException ex) {
diff --git a/media/java/android/media/projection/MediaProjectionManager.java b/media/java/android/media/projection/MediaProjectionManager.java
index aa0d0cc..900e3bb 100644
--- a/media/java/android/media/projection/MediaProjectionManager.java
+++ b/media/java/android/media/projection/MediaProjectionManager.java
@@ -66,7 +66,7 @@
     }
 
     /**
-     * Returns an Intent that <b>must</b> passed to startActivityForResult()
+     * Returns an Intent that <b>must</b> be passed to startActivityForResult()
      * in order to start screen capture. The activity will prompt
      * the user whether to allow screen capture.  The result of this
      * activity should be passed to getMediaProjection.
diff --git a/media/java/android/media/soundtrigger/SoundTriggerManager.java b/media/java/android/media/soundtrigger/SoundTriggerManager.java
index 9eb0c6d..cf7bf19 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerManager.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerManager.java
@@ -365,4 +365,22 @@
             return Integer.MAX_VALUE;
         }
     }
+
+    /**
+     * Synchronously get state of the indicated model.  The model state is returned as
+     * a recognition event, or null if the model is not loaded, or if this method
+     * is not supported.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public SoundTrigger.RecognitionEvent getModelState(UUID soundModelId) {
+        if (soundModelId == null) {
+            return null;
+        }
+        try {
+            return mSoundTriggerService.getModelState(new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
 }
diff --git a/media/java/android/media/update/ApiLoader.java b/media/java/android/media/update/ApiLoader.java
index a7eb30d..0c1d1a2 100644
--- a/media/java/android/media/update/ApiLoader.java
+++ b/media/java/android/media/update/ApiLoader.java
@@ -16,14 +16,64 @@
 
 package android.media.update;
 
+import android.app.ActivityManager;
+import android.app.AppGlobals;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Build;
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+import com.android.internal.annotations.GuardedBy;
+
+import dalvik.system.PathClassLoader;
+
+import java.io.File;
+
 /**
  * @hide
  */
 public final class ApiLoader {
+    @GuardedBy("this")
+    private static StaticProvider sMediaUpdatable;
+
+    private static final String UPDATE_PACKAGE = "com.android.media.update";
+    private static final String UPDATE_CLASS = "com.android.media.update.ApiFactory";
+    private static final String UPDATE_METHOD = "initialize";
+    private static final boolean REGISTER_UPDATE_DEPENDENCY = true;
+
     private ApiLoader() { }
 
     public static StaticProvider getProvider() {
-        throw new RuntimeException("Use MediaSession/Browser instead of"
-                + " hidden MediaSession2/Browser2 APIs.");
+        try {
+            return getMediaUpdatable();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        } catch (NameNotFoundException | ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // TODO This method may do I/O; Ensure it does not violate (emit warnings in) strict mode.
+    private static synchronized StaticProvider getMediaUpdatable()
+            throws NameNotFoundException, ReflectiveOperationException, RemoteException {
+        if (sMediaUpdatable != null) return sMediaUpdatable;
+
+        // TODO Figure out when to use which package (query media update service)
+        int flags = Build.IS_DEBUGGABLE ? 0 : PackageManager.MATCH_SYSTEM_ONLY;
+        ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
+                UPDATE_PACKAGE, flags, UserHandle.myUserId());
+
+        if (REGISTER_UPDATE_DEPENDENCY) {
+            // Register a dependency to the updatable in order to be killed during updates
+            ActivityManager.getService().addPackageDependency(ai.packageName);
+        }
+
+        ClassLoader classLoader = new PathClassLoader(ai.sourceDir,
+                ai.nativeLibraryDir + File.pathSeparator + System.getProperty("java.library.path"),
+                ClassLoader.getSystemClassLoader().getParent());
+        return sMediaUpdatable = (StaticProvider) classLoader.loadClass(UPDATE_CLASS)
+                .getMethod(UPDATE_METHOD, ApplicationInfo.class).invoke(null, ai);
     }
 }
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index e67b100..474b671 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -538,8 +538,13 @@
         MtpPropertyGroup propertyGroup;
         for (MtpStorageManager.MtpObject obj : objs) {
             if (property == 0xffffffff) {
+                if (format == 0 && handle != 0 && handle != 0xffffffff) {
+                    // return properties based on the object's format
+                    format = obj.getFormat();
+                }
                 // Get all properties supported by this object
-                propertyGroup = mPropertyGroupsByFormat.get(obj.getFormat());
+                // format should be the same between get & put
+                propertyGroup = mPropertyGroupsByFormat.get(format);
                 if (propertyGroup == null) {
                     int[] propertyList = getSupportedObjectProperties(format);
                     propertyGroup = new MtpPropertyGroup(mMediaProvider, mVolumeName,
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 3870124..fa9ab1f 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -128,6 +128,7 @@
         "libmediametrics",
         "libmediaplayer2",
         "libmediaplayer2-protos",
+        "libmediandk_utils",
         "libmediautils",
         "libnetd_client",  // for setNetworkForUser
         "libprotobuf-cpp-lite",
diff --git a/media/jni/OWNERS b/media/jni/OWNERS
new file mode 100644
index 0000000..bb91d4b
--- /dev/null
+++ b/media/jni/OWNERS
@@ -0,0 +1,2 @@
+# extra for MTP related files
+per-file android_mtp_*.cpp=marcone@google.com,jsharkey@android.com,jameswei@google.com,rmojumder@google.com
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 693a3d0..61c28ed 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -283,7 +283,8 @@
 static void
 android_media_MediaPlayer2_handleDataSourceUrl(
         JNIEnv *env, jobject thiz, jboolean isCurrent, jlong srcId,
-        jobject httpServiceObj, jstring path, jobjectArray keys, jobjectArray values) {
+        jobject httpServiceObj, jstring path, jobjectArray keys, jobjectArray values,
+        jlong startPos, jlong endPos) {
 
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL) {
@@ -300,7 +301,8 @@
     if (tmp == NULL) {  // Out of memory
         return;
     }
-    ALOGV("handleDataSourceUrl: path %s, srcId %lld", tmp, (long long)srcId);
+    ALOGV("handleDataSourceUrl: path %s, srcId %lld, start %lld, end %lld",
+          tmp, (long long)srcId, (long long)startPos, (long long)endPos);
 
     if (strncmp(tmp, "content://", 10) == 0) {
         ALOGE("handleDataSourceUrl: content scheme is not supported in native code");
@@ -313,6 +315,8 @@
     dsd->mId = srcId;
     dsd->mType = DataSourceDesc::TYPE_URL;
     dsd->mUrl = tmp;
+    dsd->mStartPositionMs = startPos;
+    dsd->mEndPositionMs = endPos;
 
     env->ReleaseStringUTFChars(path, tmp);
     tmp = NULL;
@@ -341,9 +345,9 @@
 
 static void
 android_media_MediaPlayer2_handleDataSourceFD(
-    JNIEnv *env, jobject thiz, jboolean isCurrent, jlong srcId,
-    jobject fileDescriptor, jlong offset, jlong length)
-{
+        JNIEnv *env, jobject thiz, jboolean isCurrent, jlong srcId,
+        jobject fileDescriptor, jlong offset, jlong length,
+        jlong startPos, jlong endPos) {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
@@ -355,8 +359,10 @@
         return;
     }
     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-    ALOGV("handleDataSourceFD: srcId=%lld, fd=%d (%s), offset=%lld, length=%lld",
-          (long long)srcId, fd, nameForFd(fd).c_str(), (long long)offset, (long long)length);
+    ALOGV("handleDataSourceFD: srcId=%lld, fd=%d (%s), offset=%lld, length=%lld, "
+          "start=%lld, end=%lld",
+          (long long)srcId, fd, nameForFd(fd).c_str(), (long long)offset, (long long)length,
+          (long long)startPos, (long long)endPos);
 
     struct stat sb;
     int ret = fstat(fd, &sb);
@@ -389,6 +395,8 @@
     dsd->mFD = fd;
     dsd->mFDOffset = offset;
     dsd->mFDLength = length;
+    dsd->mStartPositionMs = startPos;
+    dsd->mEndPositionMs = endPos;
 
     status_t err;
     if (isCurrent) {
@@ -402,7 +410,8 @@
 
 static void
 android_media_MediaPlayer2_handleDataSourceCallback(
-    JNIEnv *env, jobject thiz, jboolean isCurrent, jlong srcId, jobject dataSource)
+    JNIEnv *env, jobject thiz, jboolean isCurrent, jlong srcId, jobject dataSource,
+    jlong startPos, jlong endPos)
 {
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
@@ -419,6 +428,8 @@
     dsd->mId = srcId;
     dsd->mType = DataSourceDesc::TYPE_CALLBACK;
     dsd->mCallbackSource = callbackDataSource;
+    dsd->mStartPositionMs = startPos;
+    dsd->mEndPositionMs = endPos;
 
     status_t err;
     if (isCurrent) {
@@ -769,18 +780,6 @@
                               NULL, NULL);
 }
 
-static void
-android_media_MediaPlayer2_notifyAt(JNIEnv *env, jobject thiz, jlong mediaTimeUs)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    ALOGV("notifyAt: %lld", (long long)mediaTimeUs);
-    process_media_player_call( env, thiz, mp->notifyAt((int64_t)mediaTimeUs), NULL, NULL );
-}
-
 static jint
 android_media_MediaPlayer2_getState(JNIEnv *env, jobject thiz)
 {
@@ -986,15 +985,15 @@
 }
 
 static void
-android_media_MediaPlayer2_setVolume(JNIEnv *env, jobject thiz, jfloat leftVolume, jfloat rightVolume)
+android_media_MediaPlayer2_setVolume(JNIEnv *env, jobject thiz, jfloat volume)
 {
-    ALOGV("setVolume: left %f  right %f", (float) leftVolume, (float) rightVolume);
+    ALOGV("setVolume: volume %f", (float) volume);
     sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
     if (mp == NULL ) {
         jniThrowException(env, "java/lang/IllegalStateException", NULL);
         return;
     }
-    process_media_player_call( env, thiz, mp->setVolume((float) leftVolume, (float) rightVolume), NULL, NULL );
+    process_media_player_call( env, thiz, mp->setVolume((float) volume), NULL, NULL );
 }
 
 static jbyteArray
@@ -1454,17 +1453,17 @@
     {
         "nativeHandleDataSourceUrl",
         "(ZJLandroid/media/Media2HTTPService;Ljava/lang/String;[Ljava/lang/String;"
-        "[Ljava/lang/String;)V",
+        "[Ljava/lang/String;JJ)V",
         (void *)android_media_MediaPlayer2_handleDataSourceUrl
     },
     {
         "nativeHandleDataSourceFD",
-        "(ZJLjava/io/FileDescriptor;JJ)V",
+        "(ZJLjava/io/FileDescriptor;JJJJ)V",
         (void *)android_media_MediaPlayer2_handleDataSourceFD
     },
     {
         "nativeHandleDataSourceCallback",
-        "(ZJLandroid/media/Media2DataSource;)V",
+        "(ZJLandroid/media/Media2DataSource;JJ)V",
         (void *)android_media_MediaPlayer2_handleDataSourceCallback
     },
     {"nativePlayNextDataSource", "(J)V",                        (void *)android_media_MediaPlayer2_playNextDataSource},
@@ -1482,7 +1481,6 @@
     {"_setSyncParams",     "(Landroid/media/SyncParams;)V",  (void *)android_media_MediaPlayer2_setSyncParams},
     {"getSyncParams",     "()Landroid/media/SyncParams;",   (void *)android_media_MediaPlayer2_getSyncParams},
     {"_seekTo",             "(JI)V",                            (void *)android_media_MediaPlayer2_seekTo},
-    {"_notifyAt",           "(J)V",                             (void *)android_media_MediaPlayer2_notifyAt},
     {"_pause",              "()V",                              (void *)android_media_MediaPlayer2_pause},
     {"isPlaying",           "()Z",                              (void *)android_media_MediaPlayer2_isPlaying},
     {"getCurrentPosition",  "()J",                              (void *)android_media_MediaPlayer2_getCurrentPosition},
@@ -1494,7 +1492,7 @@
     {"getParameter",        "(I)Ljava/lang/Object;",           (void *)android_media_MediaPlayer2_getParameter},
     {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer2_setLooping},
     {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer2_isLooping},
-    {"_setVolume",          "(FF)V",                            (void *)android_media_MediaPlayer2_setVolume},
+    {"_setVolume",          "(F)V",                             (void *)android_media_MediaPlayer2_setVolume},
     {"_invoke",             "([B)[B",                           (void *)android_media_MediaPlayer2_invoke},
     {"native_init",         "()V",                              (void *)android_media_MediaPlayer2_native_init},
     {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer2_native_setup},
diff --git a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
index 6595baa..7919723 100644
--- a/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
+++ b/media/mca/filterpacks/java/android/filterpacks/videosrc/SurfaceTextureSource.java
@@ -38,7 +38,7 @@
  * <p>To use, connect up the sourceListener callback, and then when executing
  * the graph, use the SurfaceTexture object passed to the callback to feed
  * frames into the filter graph. For example, pass the SurfaceTexture into
- * {#link
+ * {@link
  * android.hardware.Camera.setPreviewTexture(android.graphics.SurfaceTexture)}.
  * This filter is intended for applications that need for flexibility than the
  * CameraSource and MediaSource provide. Note that the application needs to
diff --git a/media/tests/MtpTests/OWNERS b/media/tests/MtpTests/OWNERS
new file mode 100644
index 0000000..1928ba8
--- /dev/null
+++ b/media/tests/MtpTests/OWNERS
@@ -0,0 +1,7 @@
+set noparent
+
+marcone@google.com
+jsharkey@android.com
+jameswei@google.com
+rmojumder@google.com
+
diff --git a/opengl/java/android/opengl/EGL15.java b/opengl/java/android/opengl/EGL15.java
new file mode 100644
index 0000000..f855fe2
--- /dev/null
+++ b/opengl/java/android/opengl/EGL15.java
@@ -0,0 +1,167 @@
+/*
+** 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.
+*/
+
+package android.opengl;
+
+/**
+ * EGL 1.5
+ *
+ */
+public class EGL15 {
+
+    public static final int EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT            = 0x00000001;
+    public static final int EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT   = 0x00000002;
+    public static final int EGL_OPENGL_ES3_BIT                             = 0x00000040;
+    public static final int EGL_SYNC_FLUSH_COMMANDS_BIT                    = 0x0001;
+    public static final int EGL_GL_COLORSPACE_SRGB                         = 0x3089;
+    public static final int EGL_GL_COLORSPACE_LINEAR                       = 0x308A;
+    public static final int EGL_CONTEXT_MAJOR_VERSION                      = 0x3098;
+    public static final int EGL_CL_EVENT_HANDLE                            = 0x309C;
+    public static final int EGL_GL_COLORSPACE                              = 0x309D;
+    public static final int EGL_GL_TEXTURE_2D                              = 0x30B1;
+    public static final int EGL_GL_TEXTURE_3D                              = 0x30B2;
+    public static final int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X             = 0x30B3;
+    public static final int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X             = 0x30B4;
+    public static final int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y             = 0x30B5;
+    public static final int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y             = 0x30B6;
+    public static final int EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z             = 0x30B7;
+    public static final int EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z             = 0x30B8;
+    public static final int EGL_GL_RENDERBUFFER                            = 0x30B9;
+    public static final int EGL_GL_TEXTURE_LEVEL                           = 0x30BC;
+    public static final int EGL_GL_TEXTURE_ZOFFSET                         = 0x30BD;
+    public static final int EGL_IMAGE_PRESERVED                            = 0x30D2;
+    public static final int EGL_SYNC_PRIOR_COMMANDS_COMPLETE               = 0x30F0;
+    public static final int EGL_SYNC_STATUS                                = 0x30F1;
+    public static final int EGL_SIGNALED                                   = 0x30F2;
+    public static final int EGL_UNSIGNALED                                 = 0x30F3;
+    public static final int EGL_TIMEOUT_EXPIRED                            = 0x30F5;
+    public static final int EGL_CONDITION_SATISFIED                        = 0x30F6;
+    public static final int EGL_SYNC_TYPE                                  = 0x30F7;
+    public static final int EGL_SYNC_CONDITION                             = 0x30F8;
+    public static final int EGL_SYNC_FENCE                                 = 0x30F9;
+    public static final int EGL_CONTEXT_MINOR_VERSION                      = 0x30FB;
+    public static final int EGL_CONTEXT_OPENGL_PROFILE_MASK                = 0x30FD;
+    public static final int EGL_SYNC_CL_EVENT                              = 0x30FE;
+    public static final int EGL_SYNC_CL_EVENT_COMPLETE                     = 0x30FF;
+    public static final int EGL_CONTEXT_OPENGL_DEBUG                       = 0x31B0;
+    public static final int EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE          = 0x31B1;
+    public static final int EGL_CONTEXT_OPENGL_ROBUST_ACCESS               = 0x31B2;
+    public static final int EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY = 0x31BD;
+    public static final int EGL_NO_RESET_NOTIFICATION                      = 0x31BE;
+    public static final int EGL_LOSE_CONTEXT_ON_RESET                      = 0x31BF;
+    public static final int EGL_PLATFORM_ANDROID_KHR                       = 0x3141;
+    public static final long EGL_FOREVER                                   = 0xFFFFFFFFFFFFFFFFL;
+    public static final EGLImage EGL_NO_IMAGE                              = null;
+    public static final EGLSync EGL_NO_SYNC                                = null;
+    public static final EGLContext EGL_NO_CONTEXT                          = null;
+    public static final EGLDisplay EGL_NO_DISPLAY                          = null;
+    public static final EGLSurface EGL_NO_SURFACE                          = null;
+
+    native private static void _nativeClassInit();
+    static {
+        _nativeClassInit();
+    }
+    // C function EGLSync eglCreateSync ( EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list )
+
+    public static native EGLSync eglCreateSync(
+        EGLDisplay dpy,
+        int type,
+        long[] attrib_list,
+        int offset
+    );
+
+    // C function EGLBoolean eglDestroySync ( EGLDisplay dpy, EGLSync sync )
+
+    public static native boolean eglDestroySync(
+        EGLDisplay dpy,
+        EGLSync sync
+    );
+
+    // C function EGLint eglClientWaitSync ( EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout )
+
+    public static native int eglClientWaitSync(
+        EGLDisplay dpy,
+        EGLSync sync,
+        int flags,
+        long timeout
+    );
+
+    // C function EGLBoolean eglGetSyncAttrib ( EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value )
+
+    public static native boolean eglGetSyncAttrib(
+        EGLDisplay dpy,
+        EGLSync sync,
+        int attribute,
+        long[] value,
+        int offset
+    );
+
+    // C function EGLDisplay eglGetPlatformDisplay ( EGLenum platform, EGLAttrib native_display, const EGLAttrib *attrib_list )
+
+    public static native EGLDisplay eglGetPlatformDisplay(
+        int platform,
+        long native_display,
+        long[] attrib_list,
+        int offset
+    );
+
+    // C function EGLSurface eglCreatePlatformWindowSurface ( EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list )
+
+    public static native EGLSurface eglCreatePlatformWindowSurface(
+        EGLDisplay dpy,
+        EGLConfig config,
+        java.nio.Buffer native_window,
+        long[] attrib_list,
+        int offset
+    );
+
+    // C function EGLSurface eglCreatePlatformPixmapSurface ( EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list )
+
+    public static native EGLSurface eglCreatePlatformPixmapSurface(
+        EGLDisplay dpy,
+        EGLConfig config,
+        java.nio.Buffer native_pixmap,
+        long[] attrib_list,
+        int offset
+    );
+
+    // C function EGLBoolean eglWaitSync ( EGLDisplay dpy, EGLSync sync, EGLint flags )
+
+    public static native boolean eglWaitSync(
+        EGLDisplay dpy,
+        EGLSync sync,
+        int flags
+    );
+
+    // C function EGLImage eglCreateImage ( EGLDisplay dpy, EGLContext context, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list )
+
+    public static native EGLImage eglCreateImage(
+        EGLDisplay dpy,
+        EGLContext context,
+        int target,
+        long buffer,
+        long[] attrib_list,
+        int offset
+    );
+
+    // C function EGLBoolean eglDestroyImage ( EGLDisplay dpy, EGLImage image )
+
+    public static native boolean eglDestroyImage(
+        EGLDisplay dpy,
+        EGLImage image
+    );
+
+}
diff --git a/opengl/java/android/opengl/EGLImage.java b/opengl/java/android/opengl/EGLImage.java
new file mode 100644
index 0000000..731ce72
--- /dev/null
+++ b/opengl/java/android/opengl/EGLImage.java
@@ -0,0 +1,37 @@
+/*
+**
+** 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.
+*/
+
+package android.opengl;
+
+/**
+ * Wrapper class for native EGLImage objects.
+ *
+ */
+public class EGLImage extends EGLObjectHandle {
+    private EGLImage(long handle) {
+        super(handle);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof EGLImage)) return false;
+
+        EGLImage that = (EGLImage) o;
+        return getNativeHandle() == that.getNativeHandle();
+    }
+}
diff --git a/opengl/java/android/opengl/EGLSync.java b/opengl/java/android/opengl/EGLSync.java
new file mode 100644
index 0000000..472f9e7
--- /dev/null
+++ b/opengl/java/android/opengl/EGLSync.java
@@ -0,0 +1,37 @@
+/*
+**
+** 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.
+*/
+
+package android.opengl;
+
+/**
+ * Wrapper class for native EGLSync objects.
+ *
+ */
+public class EGLSync extends EGLObjectHandle {
+    private EGLSync(long handle) {
+        super(handle);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof EGLSync)) return false;
+
+        EGLSync that = (EGLSync) o;
+        return getNativeHandle() == that.getNativeHandle();
+    }
+}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 33cb5964..4518d79 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -30,7 +30,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.carrierdefaultapp.R;
+
 /**
  * This util class provides common logic for carrier actions
  */
@@ -102,7 +102,7 @@
                 SubscriptionManager.getDefaultVoiceSubscriptionId());
         logd("onDisableAllMeteredApns subId: " + subId);
         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
-        telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, !ENABLE);
+        telephonyMgr.createForSubscriptionId(subId).setCarrierDataEnabled(!ENABLE);
     }
 
     private static void onEnableAllMeteredApns(Intent intent, Context context) {
@@ -110,7 +110,7 @@
                 SubscriptionManager.getDefaultVoiceSubscriptionId());
         logd("onEnableAllMeteredApns subId: " + subId);
         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
-        telephonyMgr.carrierActionSetMeteredApnsEnabled(subId, ENABLE);
+        telephonyMgr.createForSubscriptionId(subId).setCarrierDataEnabled(ENABLE);
     }
 
     private static void onEnableDefaultURLHandler(Context context) {
diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
index f9dbcd4..5d84d64 100644
--- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
+++ b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/CarrierDefaultReceiverTest.java
@@ -104,6 +104,6 @@
         assertNotNull(pendingIntent);
 
         Rlog.d(TAG, "verify carrier action: disable all metered apns");
-        verify(mTelephonyMgr).carrierActionSetMeteredApnsEnabled(eq(subId), eq(false));
+        verify(mTelephonyMgr).setCarrierDataEnabled(eq(false));
     }
 }
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index cdaabdc..d0ca04b 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -184,7 +184,6 @@
         if (shouldScan(mBluetoothFilters)) {
             final IntentFilter intentFilter = new IntentFilter();
             intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
-            intentFilter.addAction(BluetoothDevice.ACTION_DISAPPEARED);
 
             mBluetoothBroadcastReceiver = new BluetoothBroadcastReceiver();
             registerReceiver(mBluetoothBroadcastReceiver, intentFilter);
diff --git a/packages/CtsShim/build/Android.mk b/packages/CtsShim/build/Android.mk
index e645adc..03eb0d9 100644
--- a/packages/CtsShim/build/Android.mk
+++ b/packages/CtsShim/build/Android.mk
@@ -67,10 +67,6 @@
 LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# out/target/common/obj/APPS/CtsShimPriv_intermediates/AndroidManifest.xml:25: error: unexpected element <restrict-update> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(BUILD_PACKAGE)
 
@@ -113,10 +109,6 @@
 LOCAL_MANIFEST_FILE := shim/AndroidManifest.xml
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/packages/CtsShim/build/shim/AndroidManifest.xml:25: error: unexpected element <restrict-update> found in <manifest>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(BUILD_PACKAGE)
 
diff --git a/packages/EasterEgg/src/com/android/egg/paint/CutoutAvoidingToolbar.kt b/packages/EasterEgg/src/com/android/egg/paint/CutoutAvoidingToolbar.kt
index 164fc5a..9855565 100644
--- a/packages/EasterEgg/src/com/android/egg/paint/CutoutAvoidingToolbar.kt
+++ b/packages/EasterEgg/src/com/android/egg/paint/CutoutAvoidingToolbar.kt
@@ -26,15 +26,16 @@
     private var _insets: WindowInsets? = null
 
     constructor(context: Context) : super(context) {
-        init(null, 0)
     }
 
     constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
-        init(attrs, 0)
     }
 
-    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
-        init(attrs, defStyle)
+    constructor(
+        context: Context,
+        attrs: AttributeSet,
+        defStyle: Int
+    ) : super(context, attrs, defStyle) {
     }
 
     override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
@@ -81,8 +82,4 @@
             requestLayout()
         }
     }
-
-    private fun init(attrs: AttributeSet?, defStyle: Int) {
-    }
-
 }
diff --git a/packages/EasterEgg/src/com/android/egg/paint/Painting.kt b/packages/EasterEgg/src/com/android/egg/paint/Painting.kt
index a4a3d3d..fc7e8b0 100644
--- a/packages/EasterEgg/src/com/android/egg/paint/Painting.kt
+++ b/packages/EasterEgg/src/com/android/egg/paint/Painting.kt
@@ -17,7 +17,6 @@
 package com.android.egg.paint
 
 import android.content.Context
-import android.content.res.Resources
 import android.graphics.*
 import android.provider.Settings
 import android.util.AttributeSet
@@ -26,7 +25,6 @@
 import android.view.View
 import android.view.WindowInsets
 import java.util.concurrent.TimeUnit
-import android.util.Log
 import android.provider.Settings.System
 
 import org.json.JSONObject
@@ -86,11 +84,11 @@
         }
 
     var bitmap: Bitmap? = null
-    var paperColor : Int = 0xFFFFFFFF.toInt()
+    var paperColor: Int = 0xFFFFFFFF.toInt()
 
     private var _paintCanvas: Canvas? = null
     private val _bitmapLock = Object()
-    
+
     private var _drawPaint = Paint(Paint.ANTI_ALIAS_FLAG)
     private var _lastX = 0f
     private var _lastY = 0f
@@ -113,7 +111,9 @@
                         FADE_TO_BLACK_CF
 
                 synchronized(_bitmapLock) {
-                    c.drawBitmap(bitmap, 0f, 0f, pt)
+                    bitmap?.let {
+                        c.drawBitmap(bitmap!!, 0f, 0f, pt)
+                    }
                 }
                 invalidate()
             }
@@ -122,18 +122,22 @@
     }
 
     constructor(context: Context) : super(context) {
-        init(null, 0)
+        init()
     }
 
     constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
-        init(attrs, 0)
+        init()
     }
 
-    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
-        init(attrs, defStyle)
+    constructor(
+        context: Context,
+        attrs: AttributeSet,
+        defStyle: Int
+    ) : super(context, attrs, defStyle) {
+        init()
     }
 
-    private fun init(attrs: AttributeSet?, defStyle: Int) {
+    private fun init() {
         loadDevicePressureData()
     }
 
@@ -264,7 +268,7 @@
         super.onDraw(canvas)
 
         bitmap?.let {
-            canvas.drawBitmap(bitmap, 0f, 0f, _drawPaint);
+            canvas.drawBitmap(bitmap!!, 0f, 0f, _drawPaint)
         }
     }
 
@@ -330,8 +334,8 @@
                 }
                 if (bits.width != oldBits.height || bits.height != oldBits.width) {
                     matrix.postScale(
-                            bits.width.toFloat()/oldBits.height,
-                            bits.height.toFloat()/oldBits.width)
+                            bits.width.toFloat() / oldBits.height,
+                            bits.height.toFloat() / oldBits.width)
                 }
                 c.matrix = matrix
             }
@@ -350,9 +354,10 @@
         val invertPaint = Paint()
         invertPaint.colorFilter = INVERT_CF
         synchronized(_bitmapLock) {
-            _paintCanvas?.drawBitmap(bitmap, 0f, 0f, invertPaint)
+            bitmap?.let {
+                _paintCanvas?.drawBitmap(bitmap!!, 0f, 0f, invertPaint)
+            }
         }
         invalidate()
     }
 }
-
diff --git a/packages/EasterEgg/src/com/android/egg/paint/ToolbarView.kt b/packages/EasterEgg/src/com/android/egg/paint/ToolbarView.kt
index 86b11e7..460fa3a 100644
--- a/packages/EasterEgg/src/com/android/egg/paint/ToolbarView.kt
+++ b/packages/EasterEgg/src/com/android/egg/paint/ToolbarView.kt
@@ -17,19 +17,10 @@
 package com.android.egg.paint
 
 import android.content.Context
-import android.graphics.Canvas
-import android.graphics.Color
-import android.graphics.Paint
-import android.graphics.Rect
-import android.graphics.drawable.Drawable
-import android.text.TextPaint
-import android.transition.ChangeBounds
 import android.transition.Transition
 import android.transition.TransitionListenerAdapter
-import android.transition.TransitionManager
 import android.util.AttributeSet
 import android.view.*
-import android.view.animation.OvershootInterpolator
 import android.widget.FrameLayout
 
 class ToolbarView : FrameLayout {
@@ -44,15 +35,16 @@
     }
 
     constructor(context: Context) : super(context) {
-        init(null, 0)
     }
 
     constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
-        init(attrs, 0)
     }
 
-    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
-        init(attrs, defStyle)
+    constructor(
+        context: Context,
+        attrs: AttributeSet,
+        defStyle: Int
+    ) : super(context, attrs, defStyle) {
     }
 
     override fun onApplyWindowInsets(insets: WindowInsets?): WindowInsets {
@@ -70,8 +62,4 @@
 
         return super.onApplyWindowInsets(insets)
     }
-
-    private fun init(attrs: AttributeSet?, defStyle: Int) {
-    }
-
 }
diff --git a/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java b/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
index 5782ea1..31c9224 100644
--- a/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/AgingHelper.java
@@ -66,7 +66,7 @@
 
     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().isImportanceLocked()) {
+        if (entry.getChannel().hasUserSetImportance()) {
             return;
         }
 
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index 3333e15..8f33a70 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -25,7 +25,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityThread;
-import android.app.AlarmManager;
 import android.app.INotificationManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -224,8 +223,9 @@
     }
 
     /** A convenience helper for creating an adjustment for an SBN. */
+    @VisibleForTesting
     @Nullable
-    private Adjustment createEnqueuedNotificationAdjustment(
+    Adjustment createEnqueuedNotificationAdjustment(
             @NonNull NotificationEntry entry,
             @NonNull ArrayList<Notification.Action> smartActions,
             @NonNull ArrayList<CharSequence> smartReplies) {
@@ -237,7 +237,9 @@
             signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, smartReplies);
         }
         if (mNotificationCategorizer.shouldSilence(entry)) {
-            signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
+            final int importance = entry.getImportance() < IMPORTANCE_LOW ? entry.getImportance()
+                    : IMPORTANCE_LOW;
+            signals.putInt(KEY_IMPORTANCE, importance);
         }
 
         return new Adjustment(
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
index 2820232..2eb005a 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
@@ -66,6 +66,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.FileOutputStream;
+import java.util.ArrayList;
 
 public class AssistantTest extends ServiceTestCase<Assistant> {
 
@@ -466,4 +467,12 @@
 
         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(
+                mPackageManager, sbn, P1C3), new ArrayList<>(), new ArrayList<>());
+        assertEquals(IMPORTANCE_MIN, adjust.getSignals().getInt(Adjustment.KEY_IMPORTANCE));
+    }
 }
diff --git a/packages/ExternalStorageProvider/Android.bp b/packages/ExternalStorageProvider/Android.bp
new file mode 100644
index 0000000..973fef3
--- /dev/null
+++ b/packages/ExternalStorageProvider/Android.bp
@@ -0,0 +1,19 @@
+android_app {
+    name: "ExternalStorageProvider",
+
+    manifest: "AndroidManifest.xml",
+
+    resource_dirs: [
+        "res",
+    ],
+
+    srcs: [
+        "src/**/*.java",
+    ],
+
+    platform_apis: true,
+
+    certificate: "platform",
+
+    privileged: true,
+}
diff --git a/packages/ExternalStorageProvider/Android.mk b/packages/ExternalStorageProvider/Android.mk
deleted file mode 100644
index 9e99313..0000000
--- a/packages/ExternalStorageProvider/Android.mk
+++ /dev/null
@@ -1,13 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_PACKAGE_NAME := ExternalStorageProvider
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
-
-include $(BUILD_PACKAGE)
diff --git a/packages/ExternalStorageProvider/AndroidManifest.xml b/packages/ExternalStorageProvider/AndroidManifest.xml
index 1072f95..484dbcc 100644
--- a/packages/ExternalStorageProvider/AndroidManifest.xml
+++ b/packages/ExternalStorageProvider/AndroidManifest.xml
@@ -17,6 +17,10 @@
             <intent-filter>
                 <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
             </intent-filter>
+            <!-- Stub that allows MediaProvider to make incoming calls -->
+            <path-permission
+                android:path="/media_internal"
+                android:permission="android.permission.WRITE_MEDIA_STORAGE" />
         </provider>
 
         <receiver android:name=".MountReceiver">
diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
index 62207c5..4e52ff6d 100644
--- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
+++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java
@@ -37,6 +37,7 @@
 import android.provider.DocumentsContract.Document;
 import android.provider.DocumentsContract.Path;
 import android.provider.DocumentsContract.Root;
+import android.provider.MediaStore;
 import android.provider.Settings;
 import android.system.ErrnoException;
 import android.system.Os;
@@ -606,11 +607,16 @@
                     }
                     break;
                 }
-                case "getDocumentId": {
-                    final String path = arg;
-                    final List<UriPermission> accessUriPermissions =
-                            extras.getParcelableArrayList(AUTHORITY + ".extra.uriPermissions");
+                case MediaStore.GET_DOCUMENT_URI_CALL: {
+                    // All callers must go through MediaProvider
+                    getContext().enforceCallingPermission(
+                            android.Manifest.permission.WRITE_MEDIA_STORAGE, TAG);
 
+                    final Uri fileUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
+                    final List<UriPermission> accessUriPermissions = extras
+                            .getParcelableArrayList(DocumentsContract.EXTRA_URI_PERMISSIONS);
+
+                    final String path = fileUri.getPath();
                     try {
                         final Bundle out = new Bundle();
                         final Uri uri = getDocumentUri(path, accessUriPermissions);
@@ -619,7 +625,22 @@
                     } catch (FileNotFoundException e) {
                         throw new IllegalStateException("File in " + path + " is not found.", e);
                     }
+                }
+                case MediaStore.GET_MEDIA_URI_CALL: {
+                    // All callers must go through MediaProvider
+                    getContext().enforceCallingPermission(
+                            android.Manifest.permission.WRITE_MEDIA_STORAGE, TAG);
 
+                    final Uri documentUri = extras.getParcelable(DocumentsContract.EXTRA_URI);
+                    final String docId = DocumentsContract.getDocumentId(documentUri);
+                    try {
+                        final Bundle out = new Bundle();
+                        final Uri uri = Uri.fromFile(getFileForDocId(docId));
+                        out.putParcelable(DocumentsContract.EXTRA_URI, uri);
+                        return out;
+                    } catch (FileNotFoundException e) {
+                        throw new IllegalStateException(e);
+                    }
                 }
                 default:
                     Log.w(TAG, "unknown method passed to call(): " + method);
diff --git a/packages/ExternalStorageProvider/tests/Android.bp b/packages/ExternalStorageProvider/tests/Android.bp
new file mode 100644
index 0000000..83427d4
--- /dev/null
+++ b/packages/ExternalStorageProvider/tests/Android.bp
@@ -0,0 +1,25 @@
+android_test {
+    name: "ExternalStorageProviderTests",
+
+    manifest: "AndroidManifest.xml",
+
+    srcs: [
+        "src/**/*.java",
+    ],
+
+    libs: [
+        "android.test.base",
+        "android.test.mock",
+        "android.test.runner",
+    ],
+
+    static_libs: [
+        "android-support-test",
+        "mockito-target",
+        "truth-prebuilt",
+    ],
+
+    certificate: "platform",
+
+    instrumentation_for: "ExternalStorageProvider",
+}
diff --git a/packages/ExternalStorageProvider/tests/AndroidManifest.xml b/packages/ExternalStorageProvider/tests/AndroidManifest.xml
new file mode 100644
index 0000000..58b6e86
--- /dev/null
+++ b/packages/ExternalStorageProvider/tests/AndroidManifest.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.externalstorage.tests">
+
+    <application android:label="ExternalStorageProvider Tests">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.externalstorage"
+                     android:label="ExternalStorageProvider Tests" />
+</manifest>
+
diff --git a/packages/ExternalStorageProvider/tests/AndroidTest.xml b/packages/ExternalStorageProvider/tests/AndroidTest.xml
new file mode 100644
index 0000000..e5fa73f
--- /dev/null
+++ b/packages/ExternalStorageProvider/tests/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?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 ExternalStorageProvider.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="ExternalStorageProviderTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
+    <option name="test-tag" value="ExternalStorageProviderTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.externalstorage.tests" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java b/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
new file mode 100644
index 0000000..a88b3e1
--- /dev/null
+++ b/packages/ExternalStorageProvider/tests/src/com/android/externalstorage/ExternalStorageProviderTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.externalstorage;
+
+import static com.android.externalstorage.ExternalStorageProvider.AUTHORITY;
+
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.pm.ProviderInfo;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class ExternalStorageProviderTest {
+    @Test
+    public void onCreate_shouldUpdateVolumes() throws Exception {
+        ExternalStorageProvider externalStorageProvider = new ExternalStorageProvider();
+        ExternalStorageProvider spyProvider = spy(externalStorageProvider);
+        ProviderInfo providerInfo = new ProviderInfo();
+        providerInfo.authority = AUTHORITY;
+        providerInfo.grantUriPermissions = true;
+        providerInfo.exported = true;
+
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                spyProvider.attachInfoForTesting(
+                        InstrumentationRegistry.getTargetContext(), providerInfo);
+            }
+        });
+
+        verify(spyProvider, atLeast(1)).updateVolumes();
+    }
+}
diff --git a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
index 0bf8bc1..4408ef5 100644
--- a/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
+++ b/packages/LocalTransport/src/com/android/localtransport/LocalTransport.java
@@ -95,7 +95,6 @@
     private long mFullBackupSize;
 
     private FileInputStream mCurFullRestoreStream;
-    private FileOutputStream mFullRestoreSocketStream;
     private byte[] mFullRestoreBuffer;
     private final LocalTransportParameters mParameters;
 
@@ -195,6 +194,15 @@
 
     @Override
     public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data, int flags) {
+        try {
+            return performBackupInternal(packageInfo, data, flags);
+        } finally {
+            IoUtils.closeQuietly(data);
+        }
+    }
+
+    private int performBackupInternal(
+            PackageInfo packageInfo, ParcelFileDescriptor data, int flags) {
         boolean isIncremental = (flags & FLAG_INCREMENTAL) != 0;
         boolean isNonIncremental = (flags & FLAG_NON_INCREMENTAL) != 0;
 
@@ -750,7 +758,6 @@
     private void resetFullRestoreState() {
         IoUtils.closeQuietly(mCurFullRestoreStream);
         mCurFullRestoreStream = null;
-        mFullRestoreSocketStream = null;
         mFullRestoreBuffer = null;
     }
 
@@ -795,10 +802,11 @@
                 Log.e(TAG, "Unable to read archive for " + name);
                 return TRANSPORT_PACKAGE_REJECTED;
             }
-            mFullRestoreSocketStream = new FileOutputStream(socket.getFileDescriptor());
             mFullRestoreBuffer = new byte[2*1024];
         }
 
+        FileOutputStream stream = new FileOutputStream(socket.getFileDescriptor());
+
         int nRead;
         try {
             nRead = mCurFullRestoreStream.read(mFullRestoreBuffer);
@@ -815,14 +823,12 @@
                 if (DEBUG) {
                     Log.i(TAG, "   delivering restore chunk: " + nRead);
                 }
-                mFullRestoreSocketStream.write(mFullRestoreBuffer, 0, nRead);
+                stream.write(mFullRestoreBuffer, 0, nRead);
             }
         } catch (IOException e) {
             return TRANSPORT_ERROR;  // Hard error accessing the file; shouldn't happen
         } finally {
-            // Most transports will need to explicitly close 'socket' here, but this transport
-            // is in the same process as the caller so it can leave it up to the backup manager
-            // to manage both socket fds.
+            IoUtils.closeQuietly(socket);
         }
 
         return nRead;
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index 7c81399..4801f62 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -12,6 +12,7 @@
     <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" />
     <uses-permission android:name="android.permission.MANAGE_APP_OPS_MODES" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+    <uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
 
     <uses-permission android:name="com.google.android.permission.INSTALL_WEARABLE_PACKAGES" />
 
diff --git a/packages/PackageInstaller/res/values-af/strings.xml b/packages/PackageInstaller/res/values-af/strings.xml
index 0d41c18..2e7c4aa 100644
--- a/packages/PackageInstaller/res/values-af/strings.xml
+++ b/packages/PackageInstaller/res/values-af/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Pakketinstalleerder"</string>
-    <string name="next" msgid="3057143178373252333">"Volgende"</string>
-    <string name="install" msgid="5896438203900042068">"Installeer"</string>
-    <string name="done" msgid="3889387558374211719">"Klaar"</string>
-    <string name="cancel" msgid="8360346460165114585">"Kanselleer"</string>
-    <string name="installing" msgid="8613631001631998372">"Installeer tans…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installeer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
-    <string name="install_done" msgid="3682715442154357097">"Program geïnstalleer."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Wil jy hierdie program installeer? Dit sal kan ingaan by:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Wil jy hierdie program installeer? Dit vereis nie enige spesiale toegang nie."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Wil jy \'n opdatering vir die bestaande program installeer? Jou bestaande data sal nie verlore gaan nie. Die opgedateerde program sal kan ingaan by:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Wil jy \'n opdatering vir hierdie ingeboude program installeer? Jou bestaande data sal nie verlore gaan nie. Die opgedateerde program sal kan ingaan by:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Wil jy \'n opdatering na hierdie bestaande program installeer? Jou bestaande data sal nie verlore raak nie. Dit vereis nie enige spesiale toegang nie."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Wil jy \'n opdatering na hierdie ingeboude program installeer? Jou bestaande data sal nie verlore raak nie. Dit vereis nie enige spesiale toegang nie."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Program nie geïnstalleer nie."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Die installering van die pakket is geblokkeer."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Program is nie geïnstalleer nie omdat pakket met \'n bestaande pakket bots."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Program is nie geïnstalleer nie omdat dit nie met jou tablet versoenbaar is nie."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Hierdie program is nie met jou TV versoenbaar nie."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Program is nie geïnstalleer nie omdat dit nie met jou foon versoenbaar is nie."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Program is nie geïnstalleer nie omdat pakket ongeldig blyk te wees."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou tablet geïnstalleer word nie."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou TV geïnstalleer word nie."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou foon geïnstalleer word nie."</string>
-    <string name="launch" msgid="4826921505917605463">"Open"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Jou administrateur laat nie toe dat programme wat by onbekende bronne verkry is, geïnstalleer word nie"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Hierdie gebruiker kan nie onbekende programme installeer nie"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Hierdie gebruiker word nie toegelaat om programme te installeer nie"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Bestuur programme"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Geen spasie oor nie"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie geïnstalleer word nie. Maak \'n bietjie plek en probeer weer."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Program nie gevind nie"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Die program is nie in die lys van geïnstalleerde programme gevind nie."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nie toegelaat nie"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Die huidige gebruiker mag nie hierdie deïnstallering uitvoer nie."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fout"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Program kon nie gedeïnstalleer word nie."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Deïnstalleer program"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Deïnstalleer opdatering"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is deel van die volgende program:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Wil jy hierdie program deïnstalleer?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Wil jy hierdie program vir "<b>"alle"</b>" gebruikers deïnstalleer? Die program en sy data sal vir "<b>"alle"</b>" gebruikers op hierdie toestel verwyder word."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Wil jy hierdie program vir die gebruiker <xliff:g id="USERNAME">%1$s</xliff:g> deïnstalleer?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Vervang hierdie program met die fabriekweergawe? Alle data sal verwyder word."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vervang hierdie program met die fabriekweergawe? Alle data sal verwyder word. Dit beïnvloed alle gebruikers van hierdie toestel, insluitend dié met werkprofiele."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Voer tans deïnstallerings uit"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mislukte installerings"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Deïnstalleer tans…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Deïnstalleer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Deïnstallering klaar."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Het <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> gedeïnstalleer"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Deïnstallasie onsuksesvol."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Kon nie <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deïnstalleer nie."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Kan nie aktiewe toesteladministrasieprogram deïnstalleer nie"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Kan nie aktiewe toesteladministrasieprogram vir <xliff:g id="USERNAME">%1$s</xliff:g> deïnstalleer nie"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Dié program word vereis vir sommige gebruikers of profiele en is vir ander gedeïnstalleer"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Hierdie program is nodig vir jou profiel en kan nie gedeïnstalleer word nie."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Jou toesteladministrateur vereis die program; dit kan nie deïnstalleer word nie."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Bestuur toesteladministrasieprogramme"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Bestuur gebruikers"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie deïnstalleer word nie."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Kon nie die pakket ontleed nie."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nuut"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privaatheid"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Toesteltoegang"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Hierdie opdatering vereis geen nuwe toestemmings nie."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Weier"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Meer inligting"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Weier in elk geval"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> van <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Laat &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toe om <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Laat &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; altyd toe om <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Net terwyl program gebruik word"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Altyd"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Weier en moenie weer vra nie"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> is gedeaktiveer"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"alles is gedeaktiveer"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"geen is gedeaktiveer nie"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Laat toe"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Programme"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Programtoestemmings"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Moenie weer vra nie"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Geen toestemmings nie"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Bykomende toestemmings"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Maak programinligting oop"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Nog <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Nog <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Hierdie program is vir \'n ouer weergawe van Android ontwerp. As toestemming geweier word, kan dit veroorsaak dat dit nie meer soos beplan funksioneer nie."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"voer \'n onbekende handeling uit"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> uit <xliff:g id="COUNT_1">%2$d</xliff:g> programme toegelaat"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Wys stelsel"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Versteek stelsel"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Geen programme nie"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Ligginginstellings"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is \'n verskaffer van liggingdienste vir hierdie toestel. Liggingtoegang kan vanuit ligginginstellings verander word."</string>
-    <string name="system_warning" msgid="7103819124542305179">"As jy hierdie toestemming weier, sal basiese kenmerke van jou toestel dalk nie meer soos bedoel werk nie."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Afgedwing deur beleid"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Agtergrondtoegang is gedeaktiveer volgens beleid"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Agtergrondtoegang is geaktiveer volgens beleid"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Voorgrondtoegang is geaktiveer volgens beleid"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Beheer deur administrateur"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Altyd"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Net as program gebruik word"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nooit"</string>
-    <string name="loading" msgid="7811651799620593731">"Laai tans …"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Alle toestemmings"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Ander programvermoëns"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Toestemmingsversoek"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Skermoorlegger bespeur"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Om hierdie toestemminginstelling te verander, moet jy eers die skermoorlegger by Instellings &gt; Programme afskakel"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Maak instellings oop"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Installeer- en deïnstalleerhandelinge word nie in Wear gesteun nie."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Kies waartoe &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang mag kry"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; is opgedateer. Kies waartoe hierdie program toegang mag kry."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Kanselleer"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Gaan voort"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nuwe toestemmings"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Huidige toestemmings"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Voer tans program uit …"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Onbekend"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Jou tablet word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Jou TV word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Jou foon word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Jou foon en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou foon of verlies van data wat uit sy gebruik kan spruit."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Jou tablet en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou tablet of verlies van data wat uit sy gebruik kan spruit."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Jou TV en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou TV of verlies van data wat uit sy gebruik kan spruit."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Gaan voort"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Instellings"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installeer/deïnstalleer Wear-programme"</string>
+    <string name="app_name" msgid="7488448184431507488">"Pakketinstalleerder"</string>
+    <string name="install" msgid="711829760615509273">"Installeer"</string>
+    <string name="done" msgid="6632441120016885253">"Klaar"</string>
+    <string name="cancel" msgid="1018267193425558088">"Kanselleer"</string>
+    <string name="installing" msgid="4921993079741206516">"Installeer tans …"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installeer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+    <string name="install_done" msgid="5987363587661783896">"Program geïnstalleer."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Wil jy hierdie program installeer?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Wil jy \'n opdatering vir hierdie bestaande program installeer? Jou bestaande data sal nie verlore gaan nie."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Wil jy \'n opdatering vir hierdie ingeboude program installeer? Jou bestaande data sal nie verlore gaan nie."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Program nie geïnstalleer nie."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Die installering van die pakket is geblokkeer."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Program is nie geïnstalleer nie omdat pakket met \'n bestaande pakket bots."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Program is nie geïnstalleer nie omdat dit nie met jou tablet versoenbaar is nie."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Hierdie program is nie met jou TV versoenbaar nie."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Program is nie geïnstalleer nie omdat dit nie met jou foon versoenbaar is nie."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Program is nie geïnstalleer nie omdat pakket ongeldig blyk te wees."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou tablet geïnstalleer word nie."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou TV geïnstalleer word nie."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie op jou foon geïnstalleer word nie."</string>
+    <string name="launch" msgid="3952550563999890101">"Maak oop"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Jou administrateur laat nie toe dat programme wat by onbekende bronne verkry is, geïnstalleer word nie"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Hierdie gebruiker kan nie onbekende programme installeer nie"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Hierdie gebruiker word nie toegelaat om programme te installeer nie"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Bestuur programme"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Geen spasie oor nie"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie geïnstalleer word nie. Maak spasie beskikbaar en probeer weer."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Program nie gevind nie"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Die program is nie in die lys geïnstalleerde programme gevind nie."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nie toegelaat nie"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Die huidige gebruiker mag nie hierdie deïnstallering uitvoer nie."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Fout"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Program kon nie gedeïnstalleer word nie."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Deïnstalleer program"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Deïnstalleer opdatering"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is deel van die volgende program:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Wil jy hierdie program deïnstalleer?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Wil jy hierdie program vir "<b>"alle"</b>" gebruikers deïnstalleer? Die program en sy data sal van "<b>"alle"</b>" gebruikers op hierdie toestel verwyder word."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Wil jy hierdie program vir die gebruiker <xliff:g id="USERNAME">%1$s</xliff:g> deïnstalleer?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Vervang hierdie program met die fabriekweergawe? Alle data sal verwyder word."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vervang hierdie program met die fabriekweergawe? Alle data sal verwyder word. Dit beïnvloed alle gebruikers van hierdie toestel, insluitend dié met werkprofiele."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Voer tans deïnstallerings uit"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mislukte deïnstallerings"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Deïnstalleer tans …"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Deïnstalleer tans <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Deïnstallering is klaar."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Het <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> gedeïnstalleer"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Deïnstallering onsuksesvol."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Kon nie <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deïnstalleer nie."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Kan nie aktiewe toesteladministrasieprogram deïnstalleer nie"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Kan nie aktiewe toesteladministrasieprogram vir <xliff:g id="USERNAME">%1$s</xliff:g> deïnstalleer nie"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Dié program word vir sommige gebruikers of profiele vereis en is vir ander gedeïnstalleer"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Hierdie program is nodig vir jou profiel en kan nie gedeïnstalleer word nie."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Jou toesteladministrateur vereis die program; kan nie gedeïnstalleer word nie."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Bestuur toesteladministrasieprogramme"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Bestuur gebruikers"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> kon nie gedeïnstalleer word nie."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Kon nie die pakket ontleed nie."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Installeer- en deïnstalleerhandelinge word nie in Wear gesteun nie."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Voer tans program uit …"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Onbekend"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Jou tablet word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Jou TV word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Jou foon word vir jou veiligheid nie toegelaat om onbekende programme van hierdie bron af te installeer nie."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Jou foon en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou foon of verlies van data wat uit sy gebruik kan spruit."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Jou tablet en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou tablet of verlies van data wat uit sy gebruik kan spruit."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Jou TV en persoonlike data is meer kwesbaar vir aanvalle deur onbekende programme. Deur hierdie program te installeer, stem jy in dat jy verantwoordelik is vir enige skade aan jou TV of verlies van data wat uit sy gebruik kan spruit."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Gaan voort"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Instellings"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installeer/deïnstalleer Wear-programme"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-am/strings.xml b/packages/PackageInstaller/res/values-am/strings.xml
index d4c5076..4c3d60d 100644
--- a/packages/PackageInstaller/res/values-am/strings.xml
+++ b/packages/PackageInstaller/res/values-am/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"ጥቅል ጫኝ"</string>
-    <string name="next" msgid="3057143178373252333">"ቀጣይ"</string>
-    <string name="install" msgid="5896438203900042068">"ጫን"</string>
-    <string name="done" msgid="3889387558374211719">"ተከናውኗል"</string>
-    <string name="cancel" msgid="8360346460165114585">"ይቅር"</string>
-    <string name="installing" msgid="8613631001631998372">"በመጫን ላይ…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በመጫን ላይ…"</string>
-    <string name="install_done" msgid="3682715442154357097">"መተግበሪያ ተጭኗል፡፡"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"ይህንን መተግበሪያ መጫን ይፈልጋሉ? ወደዚህ መዳረሻ ያገኛል፦"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ይህንን መተግበሪያ መጫን ይፈልጋሉ? ምንም የተለየ መዳረሻ አይጠይቅም።"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"ለእዚህ ነባር መተግበሪያ ማዘመኛ መጫን ይፈልጋሉ? የነበረው ውሂብህ አይጠፋም። የዘመነው መተግበሪያ ወደዚህ መዳረሻ ያገኛል፦"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ለእዚህ አብሮ ለተሰራ መተግበሪያ ማዘመኛ መጫን ይፈልጋሉ? የነበረው ውሂብዎ አይጠፋም። የዘመነው መተግበሪያ ወደዚህ መዳረሻ ያገኛል፦"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ለዚህ ነባር መተግበሪያ ዝማኔ መጫን ይፈልጋሉ? ነባር ውሂብዎ አይጠፉም። ምንም የተለየ መዳረሻ አይፈልግም።"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ለዚህ አብሮ ለተሰራ መተግበሪያ ዝማኔ መጫን ይፈልጋሉ? ነባር ውሂብዎ አይጠፉም። ምንም የተለየ መዳረሻ አይፈልግም።"</string>
-    <string name="install_failed" msgid="6579998651498970899">"ትግበራ አልተጫነም።"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ጥቅሉ እንዳይጫን ታግዷል።"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"እንደ ጥቅል ያልተጫነ መተግበሪያ ከነባር ጥቅል ጋር ይጋጫል።"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"እንደ መተግበሪያ ያልተጫነ መተግበሪያ ከጡባዊዎ ጋር ተኳሃኝ አይደለም።"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ይሄ መተግበሪያ ከእርስዎ ቴሌቪዥን ጋር ተኳሃኝ አይደለም።"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"እንደ መተግበሪያ ያልተጫነ መተግበሪያ ከስልክዎ ጋር ተኳሃኝ አይደለም።"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"እንደ ጥቅል ያልተጫነ መተግበሪያ ልክ ያልሆነ ይመስላል።"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> በዚህ ስልክ ላይ መጫን አልተቻለም።"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ ቴሌቪዥን ላይ ሊጫን አልቻለም።"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>በዚህ ስልክ ላይ መጫን አልተቻለም።"</string>
-    <string name="launch" msgid="4826921505917605463">"ክፈት"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"የእርስዎ አስተዳዳሪ ካልታወቁ ምንጮች የመጡ መተግበሪያዎች እንዲጫኑ አይፈቅድም"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ያልታወቁ መተግበሪያዎች በዚህ ተጠቃሚ ሊጫኑ አይችሉም"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ይህ ተጠቃሚ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም"</string>
-    <string name="ok" msgid="3468756155452870475">"እሺ"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"መተግበሪያዎች አስተዳድር"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ቦታ ሞልቷል"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>ለመጫን አልቻለም። ትንሽ ቦታ አስለቅቅ እና እንደገና ሞክር፡፡"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ትግበራ አልተገኘም"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"መተግበሪያው በተጫኑ መተግበሪያዎች ዝርዝር ውስጥ አልተገኘም።"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"አይፈቀድም"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"አሁን ያለው ተጠቃሚ ይህን ማራገፍ ሥራ እንዲያከናውን አይፈቀድለትም።"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"ስሕተት"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"መተግበሪያ ሊራገፍ አልተቻለም"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ትግበራ አራግፍ"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"ማዘመን አራግፍ"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>የሚከተለው ትግበራ አካል ነው፡"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"ይሄን መተግበሪያ ማራገፍ ይፈልጋሉ?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ይህን መተግበሪያ "<b>"ለሁሉም"</b>" ተጠቃሚዎች መጫን ይፈልጋሉ? መተግበሪያው እና ውሂቡ በመሣሪያው ላይ ካሉ "<b>"ሁሉም"</b>" ተጠቃሚዎች ይሰረዛሉ።"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"ይህን መተግበሪያ ለተጠቃሚ <xliff:g id="USERNAME">%1$s</xliff:g> ማራገፍ ይፈልጋሉ?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ይህ መተግበሪያ በፋብሪክው ስሪት ይተካ? ሁሉም ውሂብ ይወገዳል።"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ይህ መተግበሪያ በፋብሪክው ስሪት ይተካ? ሁሉም ውሂብ ይወገዳል። እነዚያን የሥራ መገለጫዎች ያላቸውን ጨምሮ ሁሉንም በዚህ መሣሪያ ላይ ባሉ ተጠቃሚዎች ላይ ተጽዕኖ ያሳርፍባቸዋል።"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"በማሄድ ላይ ያሉ ማራገፎች"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ያልተሳኩ ማራገፎች"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"ባለመጫንላይ"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በማራገፍ ላይ…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"አራግፍ ተጠናቋል"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ተራግፏል"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"ማራገፍ አልተሳካም፡፡"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን ማራገፍ ስኬታማ አልነበረም።"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ገባሪ የመሣሪያ አስተዳደር መተግበሪያን ማራገፍ አይቻልም"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"ለ<xliff:g id="USERNAME">%1$s</xliff:g> ገባሪ የመሣሪያ አስተዳደር መተግበሪያን ማራገፍ አይቻልም"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ይህ መተግበሪያ ለአንዳንድ ተጠቃሚዎች ወይም መገለጫዎች ያስፈልጋል እና ለሌሎች ተራግፏል"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ይህ መተግበሪያ ለእርስዎ መገለጫዎ ያስፈልጋል እና ሊራገፍ አይችልም።"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ይህ መተግበሪያ በመሣሪያዎ አስተዳዳሪ የሚፈለግ እና ሊራገፍ የማይችል ነው።"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"የመሣሪያ አስተዳደር መተግበሪያዎችን ያስተዳድሩ"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ተጠቃሚዎችን ያስተዳድሩ"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>ማራገፍ አልተቻለም"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"አካታቹን መተንተን ችግር ነበረ።"</string>
-    <string name="newPerms" msgid="6039428254474104210">"አዲስ"</string>
-    <string name="allPerms" msgid="1024385515840703981">"ሁሉም"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"ግላዊነት"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"የመሳሪያ መዳረሻ"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ይህ ዝማኔ ምንም አዲስ ፈቃድ አያስፈልገውም።"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ከልክል"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ተጨማሪ መረጃ"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ለማንኛውም ከልክል"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ከ<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g> እንዲከናወን ይፈቀድለት?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"ሁልጊዜ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ወደ <xliff:g id="ACTION">%2$s</xliff:g> ይፈቀድ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"መተግበሪያን በመጠቀም ላይ ሲኮን ብቻ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ሁልጊዜ"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"አትቀበል እና እንደገና አትጠይቅ"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ተሰናክሏል"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"ሁሉም ተሰናክሏል"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ምንም አልተሰናከለም"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ፍቀድ"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"መተግበሪያዎች"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"የመተግበሪያ ፈቃዶች"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"ዳግም አትጠይቅ"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"ምንም ፍቃዶች የሉም"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"ተጨማሪ ፈቃዶች"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"የመተግበሪያ መረጃን ክፈት"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ተጨማሪ</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ተጨማሪ</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ይህ መተግበሪያ ለAndroid አሮጌ ስሪት የተነደፈ ነበር። ፈቃድ መከልከል እንደሚፈለገው ከእንግዲህ እንዳይሰራ ሊያደርገው ይችላል።"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ያልታወቀ እርምጃ ያከናውናል"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> ከ<xliff:g id="COUNT_1">%2$d</xliff:g> መተግበሪያዎች ተፈቅዶላቸዋል"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"ስርዓትን አሳይ"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"ስርዓትን ደብቅ"</string>
-    <string name="no_apps" msgid="1965493419005012569">"ምንም መተግበሪያዎች የሉም"</string>
-    <string name="location_settings" msgid="1774875730854491297">"የአካባቢ ቅንብሮች"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> የዚህ መሳሪያ አካባቢ አገልግሎቶች አቅራቢ ነው። የአካባቢ መዳረሻ ከአካባቢ ቅንብሮች ሊሻሻል ይችላል።"</string>
-    <string name="system_warning" msgid="7103819124542305179">"ይህን ፍቃድ ከከለከሉ የመሳሪያዎ መሰረታዊ ባህሪያት ከዚህ በኋላ እንደተፈለገው ላይሰሩ ይችላሉ።"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"በመመሪያ ተፈጻሚ የሆነ"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"የጀርባ መዳረሻ በመመሪያ ተሰናክሏል"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"የጀርባ መዳረሻ በመመሪያ ነቅቷል"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"የፊት መዳረሻ በመመሪያ ነቅቷል"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"በአስተዳዳሪ ቁጥጥር የሚደረግበት"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ዘወትር"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"መተግበሪያን በስራ ላይ ሲሆን ብቻ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"በጭራሽ"</string>
-    <string name="loading" msgid="7811651799620593731">"በመጫን ላይ…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"ሁሉም ፍቃዶች"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"ሌሎች የመተግበሪያ ችሎታዎች"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"የፍቃድ ጥያቄ"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"የማያ ገጽ ተደራቢ ተገኝቷል"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ይህን የፍቃድ ቅንብር ለመቀየር መጀመሪያ የማያ ገጽ ተደራቢውን ከቅንብሮች &gt; መተግበሪያዎች ማጥፋት አለብዎ"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ቅንብሮችን ክፈት"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"በWear ላይ የመጫን/ማራገፍ እርምጃዎች አይደገፉም።"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ምን መድረስ እንደሚችል ይምረጡ"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ተዘምኗል። ይህ መተግበሪያ ምን መድረስ እንደሚችል ይምረጡ።"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"ይቅር"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"ቀጥል"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"አዲስ ፍቃዶች"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"የአሁኖቹ ፍቃዶች"</string>
-    <string name="message_staging" msgid="6151794817691100003">"መተግበሪያን በማዘጋጀት ላይ…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"ያልታወቀ"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ለእርስዎ ደህንነት ሲባል የእርስዎ ጡባዊ ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ለእርስዎ ደህንነት ሲባል የእርስዎ ቴሌቪዥን ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ለእርስዎ ደህንነት ሲባል የእርስዎ ስልክ ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"የእርስዎ ስልክ እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይልበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ስልክ ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"የእርስዎ ጡባዊ እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ጡባዊ ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"የእርስዎ ቴሌቪዥን እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ቴሌቪዥን ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ቀጥል"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ቅንብሮች"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"የWear መተግበሪያዎችን መጫን/ማራገፍ"</string>
+    <string name="app_name" msgid="7488448184431507488">"ጥቅል ጫኚ"</string>
+    <string name="install" msgid="711829760615509273">"ጫን"</string>
+    <string name="done" msgid="6632441120016885253">"ተከናውኗል"</string>
+    <string name="cancel" msgid="1018267193425558088">"ይቅር"</string>
+    <string name="installing" msgid="4921993079741206516">"በመጫን ላይ…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በመጫን ላይ…"</string>
+    <string name="install_done" msgid="5987363587661783896">"መተግበሪያ ተጭኗል።"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"ይህን መተግበሪያ መጫን ይፈልጋሉ?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"ለዚህ ነባር መተግበሪያ ዝማኔ መጫን ይፈልጋሉ? ነባሪ ውሂብዎ አይጠፋም።"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"ለዚህ አብሮ ለተሠራ መተግበሪያ ዝማኔ መጫን ይፈልጋሉ? ነባር ውሂብዎ አይጠፋም።"</string>
+    <string name="install_failed" msgid="5777824004474125469">"መተግበሪያ አልተጫነም።"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"ጥቅሉ እንዳይጫን ታግዷል።"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"እንደ ጥቅል ያልተጫነ መተግበሪያ ከነባር ጥቅል ጋር ይጋጫል።"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"እንደ መተግበሪያ ያልተጫነ መተግበሪያ ከጡባዊዎ ጋር ተኳሃኝ አይደለም።"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"ይሄ መተግበሪያ ከእርስዎ ቴሌቪዥን ጋር ተኳኋኝ አይደለም።"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"እንደ መተግበሪያ ያልተጫነ መተግበሪያ ከስልክዎ ጋር ተኳሃኝ አይደለም።"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"እንደ ጥቅል ያልተጫነ መተግበሪያ ልክ ያልሆነ ይመስላል።"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ ጡባዊ ላይ መጫን አልተቻለም።"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"ያልታወቁ መተግበሪያዎች በዚህ ተጠቃሚ ሊጫኑ አይችሉም"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ይህ ተጠቃሚ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም"</string>
+    <string name="ok" msgid="7871959885003339302">"እሺ"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"መተግበሪያዎችን ያቀናብሩ"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"ቦታ ሞልቷል"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g>ን መጫን አልቻለም። የተወሰነ ቦታ ያስለቅቁና እንደገና ይሞክሩ።"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"መተግበሪያ አልተገኘም"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"መተግበሪያው በተጫኑ መተግበሪያዎች ዝርዝር ውስጥ አልተገኘም።"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"አልተፈቀደም"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"የአሁኑ ተጠቃሚ ይህን ማራገፍ እንዲያከናውን አይፈቀድላቸውም።"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"ስህተት"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"መተግበሪያ ሊራገፍ አልተቻለም"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"መተግበሪያን አራግፍ"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"ዝማኔን አራግፍ"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> የሚከተለው መተግበሪያ አካል ነው፦"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"ይህን መተግበሪያ ማራገፍ ይፈልጋሉ?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"ይህን መተግበሪያ "<b>"ለሁሉም"</b>" ተጠቃሚዎች መጫን ይፈልጋሉ? መተግበሪያው እና ውሂቡ በመሣሪያው ላይ ካሉ "<b>"ሁሉም"</b>" ተጠቃሚዎች ይሰረዛሉ።"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"ይህን መተግበሪያ ለተጠቃሚ <xliff:g id="USERNAME">%1$s</xliff:g> ማራገፍ ይፈልጋሉ?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ይህ መተግበሪያ በፋብሪካው ስሪት ይተካ? ሁሉም ውሂብ ይወገዳል።"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ይህ መተግበሪያ በፋብሪካው ስሪት ይተካ? ሁሉም ውሂብ ይወገዳል። እነዚያን የሥራ መገለጫዎች ያላቸውን ጨምሮ ሁሉንም በዚህ መሣሪያ ላይ ባሉ ተጠቃሚዎች ላይ ተጽዕኖ ያሳርፍባቸዋል።"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"በማሄድ ላይ ያሉ ማራገፎች"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"ያልተሳኩ ማራገፎች"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"በማራገፍ ላይ…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ን በማራገፍ ላይ…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"ማራግፍ ተጠናቅቋል።"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"በWear ላይ የመጫን/ማራገፍ እርምጃዎች አይደገፉም።"</string>
+    <string name="message_staging" msgid="8032722385658438567">"መተግበሪያን በማዘጋጀት ላይ…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"ያልታወቀ"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"ለእርስዎ ደህንነት ሲባል የእርስዎ ጡባዊ ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"ለእርስዎ ደህንነት ሲባል የእርስዎ ቴሌቪዥን ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"ለእርስዎ ደህንነት ሲባል የእርስዎ ስልክ ከዚህ ምንጭ የመጡ ያልታወቁ መተግበሪያዎችን እንዲጭን አልተፈቀደለትም።"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"የእርስዎ ስልክ እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይልበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ስልክ ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"የእርስዎ ጡባዊ እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ጡባዊ ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"የእርስዎ ቴሌቪዥን እና የግል ውሂብ በማይታወቁ መተግበሪያዎች ለሚደርሱ ጥቃቶች በይበልጥ ተጋላጭ ናቸው። ይህን መተግበሪያ በመጫንዎ በእርስዎ ቴሌቪዥን ላይ ለሚደርስ ማናቸውም ጉዳት ወይም መተግበሪያውን በመጠቀም ለሚከሰት የውሂብ መጥፋት ኃላፊነቱን እንደሚወስዱ ተስማምተዋል።"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"ቀጥል"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"ቅንብሮች"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"የWear መተግበሪያዎችን መጫን/ማራገፍ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index 613481e..1721bf5 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -16,145 +16,76 @@
 
 <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="2738748390251381682">"أداة تثبيت الحزم"</string>
-    <string name="next" msgid="3057143178373252333">"التالي"</string>
-    <string name="install" msgid="5896438203900042068">"تثبيت"</string>
-    <string name="done" msgid="3889387558374211719">"تم"</string>
-    <string name="cancel" msgid="8360346460165114585">"إلغاء"</string>
-    <string name="installing" msgid="8613631001631998372">"جارٍ التثبيت..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"جارٍ تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"تم تثبيت التطبيق."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"هل تريد تثبيت هذا التطبيق؟ سيكون بإمكانه الدخول إلى:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"هل تريد تثبيت هذا التطبيق؟ إنه لا يتطلب أي دخول خاص."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"هل تريد تثبيت تحديث لهذا التطبيق الحالي؟ لن تفقد بياناتك الحالية. سيكون بإمكان التطبيق المحدّث الدخول إلى:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"هل تريد تثبيت تحديث لهذا التطبيق المضمن؟ لن تفقد بياناتك الحالية. سيكون بإمكان التطبيق المحدّث الدخول إلى:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"هل تريد تثبيت تحديث لهذا التطبيق الحالي؟ لن يتم فقد بياناتك الحالية. كما أنه لا يتطلب أي دخول خاص."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"هل تريد تثبيت تحديث لهذا التطبيق المضمن؟ لن يتم فقد بياناتك الحالية. كما أنه لا يتطلب أي دخول خاص."</string>
-    <string name="install_failed" msgid="6579998651498970899">"التطبيق ليس مثبتًا."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"تم حظر تثبيت الحزمة."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"لم يتم تثبيت التطبيق لأن حزمة التثبيت تتعارض مع حزمة حالية."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"لم يتم تثبيت التطبيق لأنه ليس متوافقًا مع جهازك اللوحي."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"هذا التطبيق لا يتوافق مع جهاز التلفزيون."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"لم يتم تثبيت التطبيق لأنه ليس متوافقًا مع هاتفك."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"لم يتم تثبيت التطبيق لأن الحزمة تبدو غير صالحة."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> على جهازك اللوحي."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> على جهاز التلفزيون."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> على هاتفك."</string>
-    <string name="launch" msgid="4826921505917605463">"فتح"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"لا يسمح المشرف بتثبيت التطبيقات التي يتم الحصول عليها من مصادر غير معروفة"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"يتعذر على هذا المستخدم تثبيت التطبيقات غير المعروفة"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"غير مسموح لهذا المستخدم بتثبيت التطبيقات"</string>
-    <string name="ok" msgid="3468756155452870475">"موافق"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"إدارة التطبيقات"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"نفدت مساحة التخزين"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> يُرجى تحرير بعض المساحة والمحاولة مرة أخرى."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"لم يتم العثور على التطبيق"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"لم يتم العثور على التطبيق في قائمة التطبيقات المثبتة."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"غير مسموح به"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"غير مسموح للمستخدم الحالي بتنفيذ عملية إلغاء التثبيت هذه."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"الخطأ"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"تعذر إلغاء تثبيت التطبيق."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"إلغاء تثبيت التطبيق"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"إزالة التحديث"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> هو جزء من التطبيق التالي:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"هل تريد إزالة هذا التطبيق؟"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"هل تريد إزالة هذا التطبيق "<b>"لكل"</b>" المستخدمين؟ ستتم إزالة التطبيق وبياناته من "<b>"كل"</b>" المستخدمين على هذا الجهاز."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"هل تريد إزالة هذا التطبيق للمستخدم <xliff:g id="USERNAME">%1$s</xliff:g>؟"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات. وسيؤثر هذا في جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"عمليات إلغاء التثبيت الجارية"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"عمليات إلغاء التثبيت غير الناجحة"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"جارٍ الإزالة..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"جارٍ إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"انتهت الإزالة."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"تم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"تعذّر إلغاء التثبيت."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"لم يتم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> بنجاح."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"تعذر إلغاء تثبيت تطبيق مشرف الأجهزة النشطة"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"تعذر إلغاء تثبيت تطبيق مشرف الأجهزة النشطة لدى <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"هذا التطبيق مطلوب لبعض المستخدمين أو الملفات الشخصية وتم إلغاء تثبيته لآخرين."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"هذا التطبيق مطلوب لملفك الشخصي ولا يمكن إلغاء تثبيته."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"مشرف الجهاز يحتاج إلى هذا التطبيق ولا يمكن إزالته."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"إدارة تطبيقات مشرف الجهاز"</string>
-    <string name="manage_users" msgid="3125018886835668847">"إدارة حسابات المستخدمين"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"تعذرت إزالة <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"حدثت مشكلة أثناء تحليل الحزمة."</string>
-    <string name="newPerms" msgid="6039428254474104210">"جديد"</string>
-    <string name="allPerms" msgid="1024385515840703981">"الكل"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"الخصوصية"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"الدخول إلى الجهاز"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"لا يتطلب هذا التحديث أي أذونات جديدة."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"رفض"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"مزيد من المعلومات"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"الرفض على أي حال"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> من <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"‏هل توافق على منح &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; إذن <xliff:g id="ACTION">%2$s</xliff:g>؟"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"‏هل تريد السماح دائمًا للتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بهذا الإجراء: <xliff:g id="ACTION">%2$s</xliff:g>؟"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"أثناء استخدام التطبيق فقط"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"دائمًا"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"رفض وعدم طرح السؤال مرة أخرى"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> إذن غير مفعّل"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"كل الأذونات غير مفعّلة"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ليس هناك أذونات غير مفعّلة"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"سماح"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"التطبيقات"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"أذونات التطبيق"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"عدم السؤال مرة أخرى"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"ما مِن أذونات"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"أذونات إضافية"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"فتح معلومات التطبيق"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g>لا أذونات أخرى</item>
-      <item quantity="two">إذنان آخران (<xliff:g id="COUNT_1">%1$d</xliff:g>)</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> أذونات أخرى</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> إذنًا آخر</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> من الأذونات الأخرى</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>إذن واحد آخر</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"‏تم تصميم هذا التطبيق لإصدار قديم من Android. وقد يؤدي رفض الإذن إلى عدم العمل على النحو المطلوب مرة أخرى."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"تنفيذ إجراء غير معروف"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"تم السماح لـ <xliff:g id="COUNT_0">%1$d</xliff:g> من أصل <xliff:g id="COUNT_1">%2$d</xliff:g> تطبيق"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"عرض النظام"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"إخفاء النظام"</string>
-    <string name="no_apps" msgid="1965493419005012569">"ليس هناك أي تطبيقات"</string>
-    <string name="location_settings" msgid="1774875730854491297">"إعدادات الموقع"</string>
-    <string name="location_warning" msgid="8778701356292735971">"يعد <xliff:g id="APP_NAME">%1$s</xliff:g> أحد مقدمي خدمات الموقع لهذا الجهاز. يمكن تعديل إمكانية الوصول إلى الموقع من إعدادات الموقع."</string>
-    <string name="system_warning" msgid="7103819124542305179">"في حال رفض هذا الإذن، قد لا تعمل ميزات أساسية في جهازك على النحو المنشود."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"فرضته إحدى السياسات"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"تمّ إيقاف الوصول إلى الخلفية بواسطة السياسة."</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"تمّ تفعيل الوصول إلى الخلفية بواسطة السياسة."</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"تمّ تفعيل الوصول إلى المقدمة بواسطة السياسة."</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"إعدادات يتحكم فيها المشرف"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"دائمًا"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"أثناء استخدام التطبيق فقط"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"أبدًا"</string>
-    <string name="loading" msgid="7811651799620593731">"جارٍ التحميل..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"كل الأذونات"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"إمكانات التطبيق الأخرى"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"طلب الإذن"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"تم اكتشاف طبقة متراكبة للشاشة"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"لتغيير إعداد هذا الإذن، يتعين عليك أولاً إيقاف الطبقة المتراكبة للشاشة من الإعدادات &gt; التطبيقات"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"فتح الإعدادات"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"‏لا تتوافق إجراءات التثبيت/إلغاء التثبيت مع نظام Android Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"‏اختيار ما تريد السماح لتطبيق &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; بالوصول إليه"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"‏تم تحديث &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;. عليك اختيار ما تريد السماح لهذا التطبيق بالوصول إليه."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"إلغاء"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"متابعة"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"الأذونات الجديدة"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"الأذونات الحالية"</string>
-    <string name="message_staging" msgid="6151794817691100003">"جارٍ الطرح المرحلي للتطبيق…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"غير معروف"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"لأغراض الأمان، غير مسموح لجهازك اللوحي بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"لأغراض الأمان، غير مسموح لجهاز التلفزيون الذي تستخدمه بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"لأغراض الأمان، غير مسموح لهاتفك بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"يعتبر الهاتف والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث لهاتفك أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"يعتبر الجهاز اللوحي والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث للجهاز اللوحي أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"يعتبر جهاز التلفزيون والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث لجهاز التلفزيون أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"متابعة"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"الإعدادات"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"‏تثبيت / إلغاء تثبيت تطبيقات Android Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"أداة تثبيت الحزم"</string>
+    <string name="install" msgid="711829760615509273">"تثبيت"</string>
+    <string name="done" msgid="6632441120016885253">"تم"</string>
+    <string name="cancel" msgid="1018267193425558088">"إلغاء"</string>
+    <string name="installing" msgid="4921993079741206516">"جارٍ التثبيت…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"جارٍ تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"تم تثبيت التطبيق."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"هل تريد تثبيت هذا التطبيق؟"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"هل تريد تثبيت تحديث لهذا التطبيق الحالي؟ لن تفقد بياناتك الحالية."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"هل تريد تثبيت تحديث لهذا التطبيق المضمَّن؟ لن تفقد بياناتك الحالية."</string>
+    <string name="install_failed" msgid="5777824004474125469">"التطبيق ليس مثبتًا."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"تم حظر تثبيت الحزمة."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"لم يتم تثبيت التطبيق لأن حزمة التثبيت تتعارض مع حزمة حالية."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"لم يتم تثبيت التطبيق لأنه ليس متوافقًا مع جهازك اللوحي."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"هذا التطبيق لا يتوافق مع جهاز التلفزيون."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"لم يتم تثبيت التطبيق لأنه ليس متوافقًا مع هاتفك."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"لم يتم تثبيت التطبيق لأن الحزمة تبدو غير صالحة."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> على جهازك اللوحي."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"يتعذر على هذا المستخدم تثبيت التطبيقات غير المعروفة"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"غير مسموح لهذا المستخدم بتثبيت التطبيقات"</string>
+    <string name="ok" msgid="7871959885003339302">"حسنًا"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"إدارة التطبيقات"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"نفدت مساحة التخزين"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"تعذر تثبيت <xliff:g id="APP_NAME">%1$s</xliff:g> الرجاء تحرير بعض المساحة والمحاولة مرة أخرى."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"لم يتمّ العثور على التطبيق."</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"لم يتم العثور على التطبيق في قائمة التطبيقات المثبتة."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"غير مسموح به"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"غير مسموح للمستخدم الحالي بتنفيذ عملية إلغاء التثبيت هذه."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"خطأ"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"تعذر إلغاء تثبيت التطبيق."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"إلغاء تثبيت التطبيق"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"إزالة التحديث"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> هو جزء من التطبيق التالي:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"هل تريد إزالة هذا التطبيق؟"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"هل تريد إزالة هذا التطبيق "<b>"لكل"</b>" المستخدمين؟ ستتم إزالة التطبيق وبياناته من "<b>"كل"</b>" المستخدمين على هذا الجهاز."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"هل تريد إزالة هذا التطبيق للمستخدم <xliff:g id="USERNAME">%1$s</xliff:g>؟"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد استبدال هذا التطبيق بإصدار المصنع؟ ستتم إزالة جميع البيانات. وسيؤثر هذا في جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"عمليات إلغاء التثبيت الجارية"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"عمليات إلغاء التثبيت غير الناجحة"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"جارٍ إلغاء التثبيت…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"جارٍ إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"تمّ إلغاء تثبيت التطبيق."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"‏لا تتوافق إجراءات التثبيت/إلغاء التثبيت مع نظام Android Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"جارٍ الطرح المرحلي للتطبيق…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"غير معروف"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"لأغراض الأمان، غير مسموح لجهازك اللوحي بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"لأغراض الأمان، غير مسموح لجهاز التلفزيون الذي تستخدمه بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"لأغراض الأمان، غير مسموح لهاتفك بتثبيت تطبيقات غير معروفة من هذا المصدر."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"يعتبر الهاتف والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث لهاتفك أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"يعتبر الجهاز اللوحي والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث للجهاز اللوحي أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"يعتبر جهاز التلفزيون والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث لجهاز التلفزيون أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"متابعة"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"الإعدادات"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"‏تثبيت / إلغاء تثبيت تطبيقات Android Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-as/strings.xml b/packages/PackageInstaller/res/values-as/strings.xml
deleted file mode 100644
index de2f2d6..0000000
--- a/packages/PackageInstaller/res/values-as/strings.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  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.
- -->
-
-<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="2738748390251381682">"পেকেজ ইনষ্টলাৰ"</string>
-    <string name="next" msgid="3057143178373252333">"পৰৱৰ্তী"</string>
-    <string name="install" msgid="5896438203900042068">"ইনষ্টল কৰক"</string>
-    <string name="done" msgid="3889387558374211719">"সম্পন্ন হ\'ল"</string>
-    <string name="cancel" msgid="8360346460165114585">"বাতিল কৰক"</string>
-    <string name="installing" msgid="8613631001631998372">"ইনষ্টল কৰি থকা হৈছে…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ইনষ্টল কৰি থকা হৈছে…"</string>
-    <string name="install_done" msgid="3682715442154357097">"এপ্ ইনষ্টল কৰা হ\'ল।"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"আপুনি এই এপ্লিকেশ্বন ইনষ্টল কৰিব বিচাৰেনে? ই এইবোৰ ব্যৱহাৰ কৰিব পাৰিব:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"আপুনি এই এপ্লিকেশ্বন ইনষ্টল কৰিব বিচাৰেনে? ইয়াক ব্য়ৱহাৰ সম্পৰ্কীয় কোনো অনুমতিৰ প্ৰয়োজন নাই।"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"আপুনি পূর্বৰে পৰা থকা এপ্লিকেশ্বন আপডেট কৰিব বিচাৰেনে? আপুনি কোনো পুৰণি ডেটা নেহেৰুৱাই। আপডেট হোৱা এপ্লিকেশ্বনে এইবোৰ ব্যৱহাৰ কৰিব পাৰিব:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"আপুনি এই অন্তনির্মিত এপ্লিকেশ্বন আপডেট কৰিব বিচাৰেনে? আপুনি কোনো পুৰণি ডেটা নেহেৰুৱাই। আপডেট হোৱা এপ্লিকেশ্বনে এইবোৰ ব্যৱহাৰ কৰিব পাৰিব:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"আপুনি পূর্বৰে পৰা থকা এপ্লিকেশ্বন আপডেট কৰিব বিচাৰেনে? আপুনি কোনো পুৰণি ডেটা নেহেৰুৱাব। ব্যৱহাৰৰ বাবে ইয়াক কোনো বিশেষ অনুমতিৰ প্ৰয়োজন নাই৷"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"আপুনি এই অন্তনির্মিত এপ্লিকেশ্বন আপডেট কৰিব বিচাৰেনে? আপুনি নিজৰ পুৰণি ডেটা নেহেৰুৱাব৷ ব্যৱহাৰৰ বাবে ইয়াক কোনো বিশেষ অনুমতিৰ প্ৰয়োজন নাই৷"</string>
-    <string name="install_failed" msgid="6579998651498970899">"এপ্ ইনষ্টল কৰা হোৱা নাই।"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"পেকেজটোৰ ইনষ্টল অৱৰোধ কৰা হৈছে।"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"এপটো ইনষ্টল কৰিব পৰা নহ\'ল কাৰণ ইয়াৰ পেকেজ আৰু পূর্বৰে পৰা উপলব্ধ পেকেজৰ মাজত সমস্যাৰ সৃষ্টি হৈছে।"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"আপোনাৰ টেবলেটৰ সৈতে মিল নথকাৰ বাবে এপটো ইনষ্টল নহ\'ল।"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"আপোনাৰ টিভিত এই এপ্ চলিব নোৱাৰে।"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"আপোনাৰ ফ\'নৰ সৈতে মিল নথকাৰ বাবে এপটো ইনষ্টল নহ\'ল।"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"পেকেজ মান্য নোহোৱাৰ বাবে এপটো ইনষ্টল নহ\'ল।"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক আপোনাৰ টে\'বলেটত ইনষ্টল কৰিব পৰা নগ\'ল৷"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"আপোনাৰ টিভিত <xliff:g id="APP_NAME">%1$s</xliff:g> ইনষ্টল কৰিব পৰা নগ\'ল।"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক আপোনাৰ ফ\'নত ইনষ্টল কৰিব পৰা নগ\'ল৷"</string>
-    <string name="launch" msgid="4826921505917605463">"খোলক"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"আপোনাৰ প্ৰশাসকে অজ্ঞাত উৎসৰ পৰা লাভ কৰা এপ্ ইনষ্টল কৰাৰ অনুমতি দিয়া নাই"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"এই ব্যৱহাৰকাৰীয়ে অজ্ঞাত উৎসৰপৰা লাভ কৰা এপসমূহ ইনষ্টল কৰিব নোৱাৰে"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"এই ব্যৱহাৰকাৰীক এপ্ ইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই"</string>
-    <string name="ok" msgid="3468756155452870475">"ঠিক আছে"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"এপসমূহ পৰিচালনা কৰক"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"পৰ্যাপ্ত খালী ঠাই নাই"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক ইনষ্টল কৰিব পৰা নগ\'ল। কিছু খালী ঠাই উলিয়াই পুনৰ চেষ্টা কৰক৷"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"এপ্ পোৱা নগ\'ল"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ইনষ্টল হৈ থকা এপসমূহৰ তালিকাত এই এপটো পোৱা নগ\'ল।"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"অনুমতি দিয়া হোৱা নাই"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"বর্তমানৰ ব্যৱহাৰকাৰীক আনইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই।"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"আসোঁৱাহ"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"এপ্ আনইনষ্টল কৰিব পৰা নাযাব।"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"এপ্ আনইনষ্টল কৰক"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"আপডেট আনইনষ্টল কৰক"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> হৈছে তলৰ এপটোৰ এটা অংশ:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"আপুনি এই এপটো আনইনষ্টল কৰিব বিচাৰেনে?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"আপুনি "<b>"সকলো"</b>" ব্যৱহাৰকাৰীৰ বাবে এই এপটো আনইনষ্টল কৰিবলৈ বিচাৰেনে? এপ্লিকেশ্বন আৰু ইয়াৰ ডেটাক ডিভাইচটোত থকা "<b>"সকলো"</b>" ব্যৱহাৰকাৰীৰ পৰা আঁতৰোৱা হ\'ব৷"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"আপুনি ব্যৱহাৰকাৰী <xliff:g id="USERNAME">%1$s</xliff:g>ৰ বাবে এই এপটো আনইনষ্টল কৰিব বিচাৰেনে?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"এই এপটো ফেক্টৰী সংস্কৰণৰ সৈতে সলনি কৰিব বিচাৰেনে? সকলো তথ্য় মচা হ\'ব।"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"এই এপটো ফেক্টৰী সংস্কৰণৰ সৈতে সলনি কৰিব বিচাৰেনে? সকলো তথ্য় মচা হ\'ব। ইয়াৰ প্ৰভাৱ কার্মস্থানৰ প্ৰফাইল থকা ডিভাইচটোৰ ব্য়ৱহাৰকাৰীসকলৰ লগতে অইন সকলো ব্য়ৱহাৰকাৰীৰ ওপৰতো পৰিব।"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"আনইনষ্টল হৈ থকা বস্তুবোৰ"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"আনইনষ্টল কৰিব নোৱাৰা বস্তুবোৰ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"আনইনষ্টল কৰি থকা হৈছে…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ক আনইনষ্টল কৰি থকা হৈছে…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"আনইনষ্টল কাৰ্যটো সমাপ্ত হ\'ল৷"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনষ্টল কৰা হ\'ল"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"আনইনষ্টল কৰিব পৰা নগ\'ল।"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ক আনইনষ্টল কৰিব পৰা নগ\'ল।"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ডিভাইচৰ সক্ৰিয় প্ৰশাসক এপ্ আনইনষ্টল কৰিব নোৱাৰি"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>ৰ সক্ৰিয় ডিভাইচৰ প্ৰশাসকীয় এপ্ আনইনষ্টল কৰিব নোৱাৰি"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"এই এপটো কিছুসংখ্য়ক ব্যৱহাৰকাৰী বা প্ৰ\'ফাইলৰ বাবে প্ৰয়োজনীয় আৰু বাকীসকলৰ বাবে ইয়াক আনইনষ্টল কৰা হৈছে"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"আপোনাৰ প্ৰ\'ফাইলৰ বাবে এই এপৰ প্ৰয়োজন আছে গতিকে আনইনষ্টল কৰিব পৰা নাযায়।"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"আপোনাৰ ডিভাইচৰ প্ৰশাসকে এই এপটো ৰখাটো বাধ্যতামূলক কৰি ৰাখিছে, গতিকে ইয়াক আনইনষ্টল কৰিব পৰা নাযায়।"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"ডিভাইচৰ প্ৰশাসকীয় এপসমূহ পৰিচালনা কৰক"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ব্য়ৱহাৰকাৰীসকলক পৰিচালনা কৰক"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>ক আনইনষ্টল কৰিব নোৱাৰি৷"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"পেকেজটো পাৰ্ছ কৰোঁতে এটা সমস্যাই দেখা দিছিল।"</string>
-    <string name="newPerms" msgid="6039428254474104210">"নতুন"</string>
-    <string name="allPerms" msgid="1024385515840703981">"সকলো"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"গোপনীয়তা"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ডিভাইচৰ ব্যৱহাৰ"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"এই আপডেটক কোনো নতুন অনুমতিৰ প্ৰয়োজন নাই।"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"প্ৰত্যাখ্যান কৰক"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"অধিক তথ্য"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"যিহ\'লেও অস্বীকাৰ কৰক"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>ৰ ভিতৰত<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>টা"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক <xliff:g id="ACTION">%2$s</xliff:g>ৰ বাবে অনুমতি দিবনে?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক সদায় <xliff:g id="ACTION">%2$s</xliff:g> কৰাৰ অনুমতি দিবনে?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"এপ্ ব্য়ৱহাৰ কৰি থাকোঁতে মাত্ৰ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"সদায়"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"অস্বীকাৰ কৰক আৰু পুনৰাই নুসুধিব"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>টা অক্ষম কৰা হ\'ল"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"সকলো অক্ষম কৰা হ\'ল"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"একো অক্ষম কৰা হোৱা নাই"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"অনুমতি দিয়ক"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"এপসমূহ"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"এপক দিয়া অনুমতিসমূহ"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"পুনৰাই নুসুধিব"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"কোনো অনুমতি নাই"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"অতিৰিক্ত অনুমতিসমূহ"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"এপৰ তথ্য় খোলক"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> অধিক</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> অধিক</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"এই এপটো Androidৰ এটা পুৰণা সংস্কৰণৰ বাবে প্ৰস্তুত কৰা হৈছিল। অনুমতি নিদিলে ই বিচৰাধৰণে কাম নকৰিবও পাৰে।"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"অজ্ঞাত কাৰ্য কৰিব পাৰে"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>ৰ ভিতৰত<xliff:g id="COUNT_0">%1$d</xliff:g>টা এপক অনুমতি দিয়া হৈছে"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"ছিষ্টেম দেখুৱাওক"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"ছিষ্টেম লুকুৱাওক"</string>
-    <string name="no_apps" msgid="1965493419005012569">"কোনো এপে এই অনুমতি বিচৰা নাই"</string>
-    <string name="location_settings" msgid="1774875730854491297">"অৱস্থান ছেটিংসমূহ"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> এই ডিভাইচৰ অৱস্থান সেৱা প্ৰদানকাৰী। অৱস্থানৰ ছেটিংসমূহত অৱস্থানৰ ব্যৱহাৰ সংশোধন কৰিব পাৰি।"</string>
-    <string name="system_warning" msgid="7103819124542305179">"আপুনি যদি এই অনুমতি প্ৰদান নকৰে, তেন্তে আপোনাৰ ডিভাইচৰ মৌলিক সুবিধাসমূহে বিচৰাধৰণে কাম নকৰিবও পাৰে।"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"নীতিৰ যোগেদি বলৱৎ কৰা"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"নীতি অনুসৰি নেপথ্য় চোৱা সুবিধা অক্ষম কৰা হ’ল"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"নীতি অনুসৰি নেপথ্য় চোৱা সুবিধা সক্ষম কৰা হ’ল"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"নীতি অনুসৰি অগ্ৰভূমি চোৱা সুবিধা সক্ষম কৰা হ’ল"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"প্ৰশাসকে নিয়ন্ত্ৰিত কৰা"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"সদায়"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"এপ্ ব্য়ৱহাৰ কৰি থাকোঁতে মাত্ৰ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"কেতিয়াও নহয়"</string>
-    <string name="loading" msgid="7811651799620593731">"ল\'ড কৰি থকা হৈছে…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"সকলো অনুমতি"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"অন্য এপৰ কার্যক্ষমতাসমূহ"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"অনুমতি বিচাৰি কৰা অনুৰোধ"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"স্ক্ৰীণ অভাৰলে\' চিনাক্ত কৰা হৈছে"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"এই অনুমতিৰ ছেটিং সলনি কৰিবলৈ আপুনি প্ৰথমে ছেটিংসমূহ &gt; এপসমূহ-লৈ গৈ স্ক্ৰীণ অভাৰলে\' অফ কৰিব লাগিব।"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ছেটিংসমূহ খোলক"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android ৱেৰ"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ইনষ্টল/আনইনষ্টল কাৰ্য Wearত কৰিব নোৱাৰি।"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ক কি কিত প্ৰৱেশ কৰিবলৈ অনুমতি দিব বাছনি কৰক"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; আপডেট কৰা হৈছে। এই এপক কি কিত প্ৰৱেশ কৰিবলৈ অনুমতি দিব বাছনি কৰক।"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"বাতিল কৰক"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"অব্যাহত ৰাখক"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"নতুন অনুমতিসমূহ"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"এপে বর্তমান ব্যৱহাৰ কৰি থকা অনুমতিসমূহ"</string>
-    <string name="message_staging" msgid="6151794817691100003">"এপৰ অন্তিম পর্যায়ৰ পৰীক্ষণ চলি আছে…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"অজ্ঞাত"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"আপোনাৰ টেবলেটটো যাতে সুৰক্ষিত থাকে তাৰ বাবে আপোনাৰ টেবলেটটোক এই উৎসৰ পৰা অজ্ঞাত এপসমূহ ইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই।"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"আপোনাৰ টিভিটো যাতে সুৰক্ষিত থাকে তাৰ বাবে আপোনাৰ টিভিটোক এই উৎসৰ পৰা অজ্ঞাত এপসমূহ ইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই।"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"আপোনাৰ ফ\'নটো যাতে সুৰক্ষিত থাকে তাৰ বাবে আপোনাৰ ফ\'নটোক এই উৎসৰ পৰা অজ্ঞাত এপসমূহ ইনষ্টল কৰিবলৈ অনুমতি দিয়া হোৱা নাই।"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"আপোনাৰ টিভি আৰু ব্যক্তিগত ডেটা অজ্ঞাত এপৰ আক্ৰমণৰ বলি হোৱাৰ সম্ভাৱনা অধিক। এই এপটো ইনষ্টল কৰি আপুনি ইয়াক ব্যৱহাৰ কৰাৰ ফলত আপোনাৰ ফ\'নত কোনো ক্ষতি হ\'লে বা ডেটা হেৰুৱালে আপুনিয়েই দায়ী হ\'ব বুলি সন্মত।"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"আপোনাৰ টেবলেট আৰু ব্যক্তিগত ডেটা অজ্ঞাত এপৰ আক্ৰমণৰ বলি হোৱাৰ সম্ভাৱনা অধিক। এই এপটো ইনষ্টল কৰি আপুনি ইয়াক ব্যৱহাৰ কৰাৰ ফলত আপোনাৰ টেবলেটত কোনো ক্ষতি হ\'লে বা ডেটা হেৰুৱালে আপুনিয়েই দায়ী হ\'ব বুলি সন্মত।"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"আপোনাৰ টিভি আৰু ব্যক্তিগত ডেটা অজ্ঞাত এপৰ আক্ৰমণৰ বলি হোৱাৰ সম্ভাৱনা অধিক। এই এপটো ইনষ্টল কৰি আপুনি ইয়াক ব্যৱহাৰ কৰাৰ ফলত আপোনাৰ টিভিত কোনো ক্ষতি হ\'লে বা ডেটা হেৰুৱালে আপুনিয়েই দায়ী হ\'ব বুলি সন্মত।"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"অব্যাহত ৰাখক"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ছেটিংবোৰ"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"ৱেৰ এপসমূহ ইনষ্টল/আনইনষ্টল কৰি থকা হৈছে"</string>
-</resources>
diff --git a/packages/PackageInstaller/res/values-az/strings.xml b/packages/PackageInstaller/res/values-az/strings.xml
index d870887..2248c6d 100644
--- a/packages/PackageInstaller/res/values-az/strings.xml
+++ b/packages/PackageInstaller/res/values-az/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Paket quraşdırıcı"</string>
-    <string name="next" msgid="3057143178373252333">"Növbəti"</string>
-    <string name="install" msgid="5896438203900042068">"Quraşdır"</string>
-    <string name="done" msgid="3889387558374211719">"Hazırdır"</string>
-    <string name="cancel" msgid="8360346460165114585">"Ləğv et"</string>
-    <string name="installing" msgid="8613631001631998372">"Quraşdırılır..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> quraşdırılır…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Tətbiq quraşdırılıb."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Bu tətbiqi quraşdırmaq istəyirsiniz? Tətbiq buraya giriş əldə edəcək:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Bu tətbiqi quraşdırmaq istəyirsiniz? Hər hansı bir xüsusi keçid tələb etmir."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Bu cari tətbiq güncəllənməsini quraşdırmaq istəyirsiniz? Hazırki datanız itməyəcək. Güncəllənmiş tətbiq aşağıdakılara çıxış əldə edəcək:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Daxili tətbiqdən yenilənməni quraşdırmaq istəyirsiniz? Hazırki datanız itməyəcək. Yenilənmiş tətbiq aşağıdakılara çıxış əldə edəcək:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Bu cari tətbiq güncəllənməsini quraşdırmaq istəyirsiniz? Hazırki datanız itməyəcək. O, xüsusi giriş tələb etmir."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Bu daxili tətbiq güncəllənməsini quraşdırmaq istəyirsiniz? Hazırki datanız itməyəcək. O, xüsusi giriş tələb etmir."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Tətbiq quraşdırılmayıb."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Paket yüklənməyə qarşı blok edildi."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Bu paketin mövcud paket ilə ziddiyəti səbəbiylə tətbiq quraşdırılmadı."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Bu tətbiq planşetinizə uyğun gəlmədiyi üçün tətbiq quraşdırılmadı."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Bu proqram TV-nizlə uyğun gəlmir."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Bu tətbiq telefonunuza uyğun gəlmədiyi üçün tətbiq quraşdırılmadı."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Paket yanlış kimi göründüyü üçün tətbiq quraşdırılmadı."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> planşetinizə yüklənə bilmədi."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> proqramını TV-nizdə quraşdırmaq mümkün olmadı."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> telefonunuza quraşdırıla bilmədi."</string>
-    <string name="launch" msgid="4826921505917605463">"Aç"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Naməlum mənbələrdən əldə edilmiş tətbiqlərin quraşdırılmasına admin tərəfindən icazə verilmir"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Naməlum tətbiqlər bu istifadəçi tərəfindən quraşdırıla bilməz"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Bu istifadəçinin tətbiqi quraşdırmaq üçün icazəsi yoxdur"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Tətbiqləri idarə et"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Boş yer yoxdur"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> quraşdırıla bilməz. Yaddaş üçün yer boşaldıb yenidən təkrar edin."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Tətbiq tapılmadı"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Tətbiq quraşdırılmış tətbiqlər siyahısında tapılmadı."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"İcazə verilmir"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Cari istifadəçiyə bu silinməni həyata keçirməyə icazə verilmir."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Xəta"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Tətbiq sistemdən silinmədi."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Tətbiqi qaldır"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Güncəlləməni sil"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> bu tətbiqin hissəsidir:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Bu tətbiqi aradan qaldırmaq istəyirsiniz mi?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Bu tətbiqi "<b>"bütün"</b>" istifadəçilər üçün silmək istəyirsiz? Tətbiq və onun datası cihazdakı "<b>"bütün"</b>" istifadəçilər üçün silinəcək."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı istifadəçi üçün bu tətbiqi sistemdən silmək istəyirsiniz?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Tətbiq zavod versiyası ilə əvəz olunsun? Bütün data silinəcək."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Tətbiq zavod versiyası ilə əvəz olunsun? Bütün data silinəcək. Bu, iş profilləri olanlar da daxil olmaqla bu cihazın bütün istifadəçilərinə təsir edir."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"İşləyən sistemlər silinmələr"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Uğursuz olan sistemlər silinmələr"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Silinir..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinir…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Sistemdən silmə tamamlandı."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silindi"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Aradan qaldırılma uğursuz oldu."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinməsi uğursuz oldu."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktiv cihaz admin tətbiqini sistemdən silmək mümkün olmadı"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün aktiv cihaz admin tətbiqini sistemdən silmək mümkün olmadı"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Bu tətbiq bəzi istifadəçi və profillər tərəfindən tələb olunur və digərləri üçün silinib"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Bu tətbiq profil üçün tələb olunur və silinə bilməz."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Bu tətbiq cihaz administratoru tərəfindən tələb olunur və sistemdən silinə bilməz."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Cihaz admin tətbiqlərini idarə edin"</string>
-    <string name="manage_users" msgid="3125018886835668847">"İstifadəçiləri idarə edin"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> sistemdən silinə bilməz."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Paketin təhlilində problem var idi."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Yeni"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Hamısı"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Məxfilik"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Qurğu icazəsi"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Bu güncəllənmə heç bir icazə istəmir"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Rədd edin"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Daha ətraflı"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Hər bir halda rədd edin"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> icazədən <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ədəd"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinə <xliff:g id="ACTION">%2$s</xliff:g> fəaliyyəti üçün icazə verilsin?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin <xliff:g id="ACTION">%2$s</xliff:g> əməliyyatına daima icazə verilsin?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Ancaq tətbiq istifadəsi zamanı"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Həmişə"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Rədd edin və daha soruşmayın"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> deaktiv edildi"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"hamısı deaktiv edildi"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"heç biri deaktiv edilmədi"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"İcazə verin"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Tətbiqlər"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Tətbiq icazələri"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Bir daha soruşmayın"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"İcazə yoxdur"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Əlavə icazələr"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Tətbiq məlumatını açın"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">daha <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">daha <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Bu tətbiq köhnə Android versiyası üçün nəzərdə tutulub. İcazəni rədd etmək onun lazımi şəkildə işləməməsinə səbəb ola bilər."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"naməlum əməliyyat etmək"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> tətbiqdən <xliff:g id="COUNT_0">%1$d</xliff:g> ədədinə icazə var"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Sistemi göstərin"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Sistemi gizlədin"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Tətbiq yoxdur"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Məkan Ayarları"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu cihaz üçün məkan xidmətləri təminatçısıdır. Məkana giriş məkan ayarlarından dəyişdirilə bilər."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Bu icazəni rədd etsəniz, cihazınızın əsas funksiyaları lazımi qaydada işləməyə bilər."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Siyasət tərəfindən tətbiq olunur"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Arxa fon girişi siyasətə əsasən deaktiv edildi"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Arxa fon girişi siyasətə əsasən aktiv edildi"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Ön fon girişi siyasətə əsasən aktiv edildi"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Admin tərəfindən nəzarət olunur"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Həmişə"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Ancaq tətbiq istifadəsi zamanı"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Heç vaxt"</string>
-    <string name="loading" msgid="7811651799620593731">"Yüklənir…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Bütün icazələr"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Digər tətbiq imkanları"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"İcazə sorğusu"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Ekran örtüyü aşkarlandı"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Bu icazə ayarını dəyişdirmək üçün əvvəldə Ayarlar və Tətbiqlər bölməsindən ekran örtüyünü söndürməlisiniz"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Ayarları açın"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Yükləmə/Silmə fəaliyyətləri Wear\'də dəstəklənmir."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqinin giriş hüququnu seçin"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tətbiqi güncəlləndi. Bu tətbiqin giriş hüququnu seçin."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Ləğv edin"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Davam edin"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Yeni icazələr"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Cari icazələr"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Tətbiq hazırlanır..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Naməlum"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Təhlükəsizliyiniz üçün planşetə bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Təhlükəsizliyiniz üçün TV-yə bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Təhlükəsizliyiniz üçün telefona bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefon və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla telefona dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verən data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Planşet və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla planşetə dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verə biləcək data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tv və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla Tv\'ə dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verən data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Davam edin"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Ayarlar"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear tətbiqləri quraşdırılır/silinir"</string>
+    <string name="app_name" msgid="7488448184431507488">"Paket quraşdırıcı"</string>
+    <string name="install" msgid="711829760615509273">"Quraşdırın"</string>
+    <string name="done" msgid="6632441120016885253">"Hazırdır"</string>
+    <string name="cancel" msgid="1018267193425558088">"Ləğv edin"</string>
+    <string name="installing" msgid="4921993079741206516">"Quraşdırılır..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> quraşdırılır…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Tətbiq quraşdırılıb."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Bu tətbiqi quraşdırmaq istəyirsiniz?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Bu mövcud tətbiqdə güncəllənmə quraşdırmaq istəyirsiniz? Hazırkı datanız silinməyəcək."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Bu daxili tətbiqdə güncəllənmə quraşdırmaq istəyirsiniz? Hazırkı datanız silinməyəcək."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Tətbiq quraşdırılmayıb."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paketin quraşdırılması blok edildi."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Bu paketin mövcud paket ilə ziddiyətinə görə tətbiq quraşdırılmadı."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Bu tətbiq planşetinizə uyğun gəlmədiyi üçün quraşdırılmadı."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Bu proqram TV-yə uyğun gəlmir."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Bu tətbiq telefonunuza uyğun gəlmədiyi üçün quraşdırılmadı."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Paket yanlış kimi göründüyü üçün tətbiq quraşdırılmadı."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> planşetinizdə quraşdırılmadı."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> TV-nizdə quraşdırılmadı."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> telefonunuzda quraşdırılmadı."</string>
+    <string name="launch" msgid="3952550563999890101">"Açın"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Naməlum mənbələrdən əldə edilmiş tətbiqlərin quraşdırılmasına admin tərəfindən icazə verilmir"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Naməlum tətbiqlər bu istifadəçi tərəfindən quraşdırıla bilməz"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Bu istifadəçinin tətbiqi quraşdırmaq üçün icazəsi yoxdur"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Tətbiqi idarə edin"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Boş yer yoxdur"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> quraşdırıla bilməz. Yaddaş üçün yer boşaldıb yenidən təkrar edin."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Tətbiq tapılmadı"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Tətbiq quraşdırılmuş tətbiqlərin siyahısında tapılmadı."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"İcazə verilməyib"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Cari istifadəçiyə bu silinməni həyata keçirməyə icazə verilmir."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Xəta"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Tətbiq sistemdən silinmədi."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Tətbiqi sistemdən silin"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Güncəlləməni silin"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> bu tətbiqin hissəsidir:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Bu tətbiqi sistemdən silmək istəyirsiniz?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Bu tətbiqi "<b>"bütün"</b>" istifadəçilər üçün silmək istəyirsiz? Tətbiq və onun datası cihazdakı "<b>"bütün"</b>" istifadəçilər üçün silinəcək."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı istifadəçi üçün bu tətbiqi sistemdən silmək istəyirsiniz?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Tətbiq zavod versiyası ilə əvəz olunsun? Bütün data silinəcək."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Tətbiq zavod versiyası ilə əvəz olunsun? Bütün data silinəcək. Bu, iş profilləri daxil olmaqla bu cihazın bütün istifadəçilərinə təsir edir."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"İşləyən sistemlər silinmələr"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Uğursuz olan sistemlər silinmələr"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Sistemdən silinir..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinir…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Sistemdən silindi."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silindi"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Sistemdən silinmədi."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sistemdən silinmədi."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktiv cihaz admin tətbiqini sistemdən silmək mümkün olmadı"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün aktiv cihaz admin tətbiqini sistemdən silmək mümkün olmadı"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Bu tətbiq bəzi istifadəçi və profillər tərəfindən tələb olunur və digərləri üçün silinib"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Bu tətbiq profil üçün tələb olunur və silinə bilməz."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Bu tətbiq cihaz administratoru tərəfindən tələb olunur və sistemdən silinə bilməz."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Cihaz admin tətbiqlərini idarə edin"</string>
+    <string name="manage_users" msgid="1243995386982560813">"İstifadəçiləri idarə edin"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> sistemdən silinə bilməz."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Paketin təhlilində problem var idi."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Yükləmə/Sistemdən silmə fəaliyyətləri Wear\'də dəstəklənmir."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Tətbiq hazırlanır..."</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Naməlum"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Təhlükəsizliyiniz üçün planşetə bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Təhlükəsizliyiniz üçün TV-yə bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Təhlükəsizliyiniz üçün telefona bu mənbədən olan naməlum tətbiqləri quraşdırmağa icazə verilmir."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefon və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla telefona dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verən data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Planşet və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla planşetə dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verə biləcək data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Tv və şəxsi data naməlum tətbiqlərin hücumuna qarşı daha həssasdır. Bu tətbiqi quraşdırmaqla Tv-yə dəyə biləcək zərər və ya onun istifadəsi nəticəsində baş verən data itkisinə görə məsuliyyət daşıdığınızı qəbul edirsiniz."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Davam edin"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Ayarlar"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear tətbiqləri quraşdırılır/sistemdən silinir"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
index 4d8772f..6cd1f40 100644
--- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -16,142 +16,76 @@
 
 <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="2738748390251381682">"Upakovani program za instalaciju"</string>
-    <string name="next" msgid="3057143178373252333">"Dalje"</string>
-    <string name="install" msgid="5896438203900042068">"Instaliraj"</string>
-    <string name="done" msgid="3889387558374211719">"Gotovo"</string>
-    <string name="cancel" msgid="8360346460165114585">"Otkaži"</string>
-    <string name="installing" msgid="8613631001631998372">"Instaliranje..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instalira se <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikacija je instalirana."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Želite li da instalirate ovu aplikaciju? Imaće pristup sledećem:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Želite li da instalirate ovu aplikaciju? Ne zahteva poseban pristup."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Želite li da instalirate ažuriranje za ovu postojeću aplikaciju? Postojeći podaci neće biti izgubljeni. Ažurirana aplikacija imaće pristup sledećem:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Želite li da instalirate ažuriranje za ovu ugrađenu aplikaciju? Postojeći podaci neće biti izgubljeni. Ažurirana aplikacija će imati pristup sledećem:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Da li želite da instalirate ažuriranje ove postojeće aplikacije? Postojeći podaci neće biti izgubljeni. Nije potreban poseban pristup."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Da li želite da instalirate ažuriranje ove ugrađene aplikacije? Postojeći podaci neće biti izgubljeni. Nije potreban poseban pristup."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikacija nije instalirana."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Instaliranje paketa je blokirano."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacija nije instalirana jer je paket neusaglašen sa postojećim paketom."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacija nije instalirana jer nije kompatibilna sa tabletom."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ova aplikacija nije kompatibilna sa TV-om."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacija nije instalirana jer nije kompatibilna sa telefonom."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacija nije instalirana jer je paket nevažeći."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nismo uspeli da instaliramo <xliff:g id="APP_NAME">%1$s</xliff:g> na TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na telefon."</string>
-    <string name="launch" msgid="4826921505917605463">"Otvori"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administrator ne dozvoljava instaliranje aplikacija dobijenih iz nepoznatih izvora"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ovaj korisnik ne može da instalira nepoznate aplikacije"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ovom korisniku nije dozvoljeno da instalira aplikacije"</string>
-    <string name="ok" msgid="3468756155452870475">"Potvrdi"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Upravljanje aplikacijama"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nema više mesta"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite dodatni prostor i pokušajte ponovo."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacija nije pronađena"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacija nije pronađena na listi instaliranih aplikacija."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nije dozvoljeno"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Aktuelnom korisniku nije dozvoljeno da obavi ovo deinstaliranje."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Greška"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Deinstaliranje aplikacije nije uspelo."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Deinstaliranje aplikacije"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Deinstaliranje ažuriranja"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je deo sledeće aplikacije:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Da li želite da deinstalirate ovu aplikaciju?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Da li želite da deinstalirate ovu aplikaciju za "<b>"sve"</b>" korisnike? Aplikacija i podaci koji se na nju odnose biće uklonjeni za "<b>"sve"</b>" korisnike ovog uređaja."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Želite li da deinstalirate ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni. Ovo utiče na sve korisnike ovog uređaja, uključujući i one sa profilima za Work."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Aktivna deinstaliranja"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neuspela deinstaliranja"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Deinstaliranje..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se deinstalira…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Deinstaliranje je završeno."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je deinstalirana"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Deinstaliranje nije uspelo."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspelo."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja za <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ova aplikacija je potrebna za neke korisnike ili profile, a deinstalirana je za druge"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ova aplikacija je potrebna za vaš profil i ne može da se deinstalira."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ova aplikacija je potrebna administratoru uređaja i ne može da se deinstalira."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Upravljaj aplikacijama za administratore uređaja"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Upravljaj korisnicima"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Nije moguće deinstalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Došlo je do problema pri raščlanjivanju paketa."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Sve"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privatnost"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Pristup uređaju"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Ovo ažuriranje ne zahteva nove dozvole."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odbaci"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Više informacija"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Ipak odbij"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>. od <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Želite li da dozvolite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Želite li uvek da dozvolite da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Samo dok se aplikacija koristi"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Uvek"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odbij i ne pitaj ponovo"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Onemogućenih: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"sve su onemogućene"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"nijedna nije onemogućena"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Dozvoli"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacije"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Dozvole za aplikacije"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ne pitaj ponovo"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Nema dozvola"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Dodatne dozvole"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otvori informacije o aplikaciji"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="few">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ova aplikacija je dizajnirana za stariju verziju Android-a. Ako odbijete dozvolu, ona možda više neće pravilno da funkcioniše."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"obavlja nepoznatu radnju"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> od <xliff:g id="COUNT_1">%2$d</xliff:g> aplikacija ima dozvolu"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Prikaži sistemske"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Sakrij sistemske"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nema aplikacija"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Podešavanja lokacije"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> pruža usluge lokacije za ovaj uređaj. Pristup lokaciji možete da izmenite u podešavanjima lokacije."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ako odbijete ovu dozvolu, osnovne funkcije uređaja možda neće više funkcionisati ispravno."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Primenjuje se u skladu sa smernicama"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Pristup u pozadini je onemogućen smernicama"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Pristup u pozadini je omogućen smernicama"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Pristup u prvom planu je omogućen smernicama"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontroliše administrator"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Uvek"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Samo dok se aplikacija koristi"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nikada"</string>
-    <string name="loading" msgid="7811651799620593731">"Učitava se…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Sve dozvole"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Ostale mogućnosti aplikacije"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Zahtev za dozvolu"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Otkriven je element koji prekriva sadržaj ekrana"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Da biste promenili podešavanje ove dozvole, prvo treba da isključite element koji prekriva sadržaj ekrana u odeljku Podešavanja &gt; Aplikacije"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Otvori podešavanja"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Radnje Instaliraj/Deinstaliraj nisu podržane u Wear-u."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Izaberite čemu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; može da pristupa"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacija &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; je ažurirana. Izaberite čemu ova aplikacija može da pristupa."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Otkaži"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Nastavi"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nove dozvole"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Aktuelne dozvole"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Aplikacija se priprema…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Nepoznato"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Tabletu iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Televizoru iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Telefonu iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefon i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja telefona ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tablet i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja tableta ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja TV-a ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Nastavi"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Podešavanja"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instaliranje/deinstaliranje Wear aplikacija"</string>
+    <string name="app_name" msgid="7488448184431507488">"Program za instal. paketa"</string>
+    <string name="install" msgid="711829760615509273">"Instaliraj"</string>
+    <string name="done" msgid="6632441120016885253">"Gotovo"</string>
+    <string name="cancel" msgid="1018267193425558088">"Otkaži"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalira se..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instalira se <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Želite li da instalirate ovu aplikaciju?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Želite li da instalirate ažuriranje za ovu postojeću aplikaciju? Postojeći podaci se neće izgubiti."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Želite li da instalirate ažuriranje za ovu ugrađenu aplikaciju? Postojeći podaci se neće izgubiti."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa je blokirano."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer je paket neusaglašen sa postojećim paketom."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikacija nije instalirana jer nije kompatibilna sa tabletom."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ova aplikacija nije kompatibilna sa TV-om."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikacija nije instalirana jer nije kompatibilna sa telefonom."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikacija nije instalirana jer je paket nevažeći."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na telefon."</string>
+    <string name="launch" msgid="3952550563999890101">"Otvori"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administrator ne dozvoljava instaliranje aplikacija dobijenih iz nepoznatih izvora"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ovaj korisnik ne može da instalira nepoznate aplikacije"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ovom korisniku nije dozvoljeno da instalira aplikacije"</string>
+    <string name="ok" msgid="7871959885003339302">"Potvrdi"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Upravljajte apl."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nema više prostora"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Nismo uspeli da instaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite prostor i probajte ponovo."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikacija nije pronađena"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikacija nije pronađena na listi instaliranih aplikacija."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nije dozvoljeno"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Aktuelnom korisniku nije dozvoljeno da obavi ovo deinstaliranje."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Greška"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Deinstaliranje aplikacije nije uspelo."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Deinstaliraj aplikaciju"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Deinstaliraj ažuriranje"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je deo sledeće aplikacije:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Želite li da deinstalirate ovu aplikaciju?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Da li želite da deinstalirate ovu aplikaciju za "<b>"sve"</b>" korisnike? Aplikacija i podaci uz nje biće uklonjeni za "<b>"sve"</b>" korisnike ovog uređaja."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Želite li da deinstalirate ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite li da zamenite ovu aplikaciju fabričkom verzijom? Svi podaci će biti uklonjeni. Ovo utiče na sve korisnike ovog uređaja, uključujući i one sa profilima za Work."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Aktivna deinstaliranja"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspela deinstaliranja"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Deinstalira se…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se deinstalira…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Deinstaliranje je završeno."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je deinstalirana"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Deinstaliranje nije uspelo."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspelo."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Ne možete da deinstalirate aplikaciju za aktivnog administratora uređaja za <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ova aplikacija je obavezna za neke korisnike ili profile, a deinstalirana je za druge"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ova aplikacija je obavezna za vaš profil i ne može da se deinstalira."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ova aplikacija je obavezna za administratora uređaja i ne može da se deinstalira."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Upravljajte aplikacijama administratora uređaja"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Upravljajte korisnicima"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Nismo uspeli da deinstaliramo aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Došlo je do problema pri raščlanjivanju paketa."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Radnje Instaliraj/Deinstaliraj nisu podržane u Wear-u."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Aplikacija se priprema…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Nepoznato"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Tabletu iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Televizoru iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Telefonu iz bezbednosnih razloga nije dozvoljeno da instalira nepoznate aplikacije iz ovog izvora."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefon i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja telefona ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tablet i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja tableta ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja TV-a ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Nastavi"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Podešavanja"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instaliranje/deinstaliranje Wear aplikac."</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml
index 1b65e29..d432eb7 100644
--- a/packages/PackageInstaller/res/values-be/strings.xml
+++ b/packages/PackageInstaller/res/values-be/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"Усталёўшчык пакетаў"</string>
-    <string name="next" msgid="3057143178373252333">"Далей"</string>
-    <string name="install" msgid="5896438203900042068">"Усталяваць"</string>
-    <string name="done" msgid="3889387558374211719">"Гатова"</string>
-    <string name="cancel" msgid="8360346460165114585">"Скасаваць"</string>
-    <string name="installing" msgid="8613631001631998372">"Усталяванне..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Ідзе ўсталяванне <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Прыкладанне ўсталявана."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Усталяваць гэта прыкладанне? Яно атрымае доступ да:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Усталяваць гэта прыкладанне? Яно не патрабуе спецыяльнага доступу."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Усталяваць абнаўленне для гэтага існуючага прыкладання? Існуючыя дадзеныя не будуць страчаны. Абноўленае прыкладанне атрымае доступ да:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Усталяваць абнаўленне для гэтага ўбудаванага прыкладання? Існуючыя дадзеныя не будуць страчаны. Абноўленае прыкладанне атрымае доступ да:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Усталяваць абнаўленне для гэтага прыкладання? Вашы iснуючыя дадзеныя не будуць згублены. Спецыяльны доступ не патрабуецца."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Усталяваць абнаўленне для гэтага ўбудаванага прыкладання? Вашы iснуючыя дадзеныя не будуць згублены. Спецыяльны доступ не патрабуецца."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Прыкладанне не ўсталявана."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Для пакета заблакіравана магчымасць усталявання."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Праграма не ўсталявана, таму што пакет канфліктуе з існуючым пакетам."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Праграма не ўсталявана, таму што яна несумяшчальная з вашым планшэтам."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Гэта праграма несумяшчальная з вашым тэлевізарам."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Праграма не ўсталявана, таму што яна несумяшчальная з вашым тэлефонам."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Праграма не ўсталявана, таму што пакет, магчыма, з\'яўляецца несапраўдным."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"На гэтым планшэце немагчыма ўсталяваць прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"На вашым тэлевізары немагчыма ўсталяваць праграму <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"На гэтым тэлефоне немагчыма ўсталяваць прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="launch" msgid="4826921505917605463">"Адкрыць"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ваш адміністратар не дазваляе ўсталёўку праграм з невядомых крыніц."</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Гэты карыстальнік не можа ўсталёўваць невядомыя праграмы"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Гэты карыстальнік не можа ўсталёўваць праграмы"</string>
-    <string name="ok" msgid="3468756155452870475">"ОК"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Кіраванне прыкладаннямі"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Не хапае месца"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Немагчыма ўсталяваць прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g>. Вызваліце месца і паўтарыце спробу."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Прыкладанне не знойдзена"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Прыкладанне не знойдзена ў спісе ўсталяваных прыкладанняў."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Забаронена"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Бягучы карыстальнік не мае дазволу на гэта выдаленне."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Памылка"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Нельга выдаліць праграму."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Выдалiць прыкладанне"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Выдаліць абнаўленні"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> з\'яўляецца часткай наступнага прыкладання:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Выдаліць гэта прыкладанне?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Выдалiць гэта прыкладанне для "<b>"ўсiх"</b>" карыстальнirfў? Прыкладанне i яго дадзеныя будуць выдалены для "<b>"ўсiх"</b>" карыстальнiкаў прылады."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Хочаце выдаліць гэту праграму для карыстальніка <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Замяніць гэту праграму заводскай версіяй? Усе даныя будуць выдалены."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Замяніць гэту праграму заводскай версіяй? Усе даныя будуць выдаленыя. Гэта паўплывае на ўсіх карыстальнікаў гэтай прылады, у тым ліку карыстальнікаў з працоўнымі профілямі."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Актыўныя выдаленні"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Збоі выдалення"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Выдаленне..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> выдаляецца…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Выдаленне завершана"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Выдалена <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Няўдалае выдаленне."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Не атрымалася выдаліць <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Немагчыма выдаліць актыўную праграму адміністратара прылады"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Немагчыма выдаліць актыўную праграму адміністратара прылады для карыстальніка <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Гэта праграма патрабуецца для некаторых карыстальнікаў або профіляў і была выдалена для іншых"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Гэта праграма неабходная для вашага профілю і не можа быць выдалена."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Гэта праграма патрабуецца адміністратару вашай прылады і не можа быць выдалена."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Праграмы адміністратара для кіравання прыладамі"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Кіраванне карыстальнікамі"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Немагчыма выдалiць прыкладанне <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Памылка аналiзу пакета."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Новыя"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Усе"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Прыватнасць"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Доступ да прылады"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Гэтае абнаўленне не патрабуе ніякіх новых дазволаў."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Адмовіць"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Дадатковая iнфармацыя"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Усё роўна адмовіць"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> з <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Дазволіць &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Заўсёды дазваляць праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Толькі пры актыўнай праграме"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Заўсёды"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Адхіліць і больш не пытацца"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Адключана: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"усе адключаны"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"няма адключаных"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Дазволіць"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Праграмы"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Дазволы праграм"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Больш не пытацца"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Няма дазволаў"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Дадатковыя дазволы"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Паказаць звесткі пра праграму"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> іншы</item>
-      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> іншыя</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> іншых</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> іншага</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Гэта праграма была распрацавана для больш старой версіі Android. Адхіленне дазволу можа прывесці да таго, што яна не будзе працаваць належным чынам."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"выканаць невядомае дзеянне"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> з <xliff:g id="COUNT_1">%2$d</xliff:g> праграм з дазволам"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Паказаць сістэмныя"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Схаваць сістэмныя"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Няма праграм"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Налады месцазнаходжання"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> з\'яўляецца службай вызначэння месцазнаходжання для гэтай прылады. Доступ да вызначэння месцазнаходжання можна змяніць у наладах вызначэння месцазнаходжання."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Калі вы адхіліце гэты дазвол, асноўныя функцыі прылады могуць перастаць працаваць належным чынам."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Ажыццёўлена палітыкай"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Доступ у фонавым рэжыме адключаны згодна з правіламі"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Доступ у фонавым рэжыме ўключаны згодна з правіламі"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Доступ у актыўным рэжыме ўключаны згодна з правіламі"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Кантралюецца адміністратарам"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Заўсёды"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Толькі пры актыўнай праграме"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Ніколі"</string>
-    <string name="loading" msgid="7811651799620593731">"Загрузка..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Усе дазволы"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Іншыя магчымасці праграмы"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Запыт дазволу"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Выяўлены слой экрана"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Каб змяніць гэту наладу дазволу, вы павінны спачатку выключыць слой экрана з меню Налады &gt; Праграмы"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Адкрыць налады"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Дзеянні па ўсталяванні або выдаленні не падтрымліваюцца на Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Выберыце, да чаго дазволіць доступ праграме &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Праграма &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; была абноўлена. Выберыце, да чаго ёй дазволіць доступ."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Скасаваць"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Далей"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Новыя дазволы"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Бягучыя дазволы"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Падрыхтоўка праграмы..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Невядома"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"У мэтах бяспекі вашаму планшэту не дазваляецца ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"У мэтах бяспекі вашаму тэлевізару не дазваляецца ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"У мэтах бяспекі вашаму тэлефону не дазваляецца ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Ваш тэлефон і асабістыя даныя больш уразлівыя для нападаў невядомых праграм. Пры ўсталёўцы гэтай праграмы вы згаджаецеся, што несяце адказнасць за любыя пашкоджанні тэлефона ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ваш планшэт і асабістыя даныя больш уразлівыя для нападаў невядомых праграм. Пры ўсталёўцы гэтай праграмы вы згаджаецеся, што несяце адказнасць за любыя пашкоджанні планшэта ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Ваш тэлевізар і асабістыя даныя больш уразлівыя для нападаў невядомых праграм. Пры ўсталёўцы гэтай праграмы вы згаджаецеся, што несяце адказнасць за любыя пашкоджанні тэлевізара ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Працягнуць"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Налады"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Усталяванне/выдаленне праграм wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Усталёўшчык пакетаў"</string>
+    <string name="install" msgid="711829760615509273">"Усталяваць"</string>
+    <string name="done" msgid="6632441120016885253">"Гатова"</string>
+    <string name="cancel" msgid="1018267193425558088">"Скасаваць"</string>
+    <string name="installing" msgid="4921993079741206516">"Ідзе ўсталёўка…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Усталёўваецца <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Праграма ўсталявана."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Хочаце ўсталяваць гэту праграму?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Хочаце ўсталяваць абнаўленне для гэтай праграмы? Існуючыя даныя не будуць страчаны."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Хочаце ўсталяваць абнаўленне для ўбудаванай праграмы? Існуючыя даныя не будуць страчаны."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Праграма не ўсталявана."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Усталяванне пакета заблакіравана."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Праграма не ўсталявана, таму што пакет канфліктуе з існуючым пакетам."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Праграма не ўсталявана, таму што яна несумяшчальная з вашым планшэтам."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Гэта праграма несумяшчальная з вашым тэлевізарам."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Праграма не ўсталявана, таму што яна несумяшчальная з вашым тэлефонам."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Праграма не ўсталявана, таму што пакет, магчыма, з\'яўляецца несапраўдным."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"На вашым планшэце не ўдалося ўсталяваць праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Гэты карыстальнік не можа ўсталёўваць невядомыя праграмы"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Гэты карыстальнік не можа ўсталёўваць праграмы"</string>
+    <string name="ok" msgid="7871959885003339302">"ОК"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Кіраваць"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Не хапае месца"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Не ўдалося ўсталяваць праграму \"<xliff:g id="APP_NAME">%1$s</xliff:g>\". Вызваліце месца і паўтарыце спробу."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Праграма не знойдзена"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Праграма не знойдзена ў спісе ўсталяваных праграм."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Забаронена"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Гэты карыстальнік не можа здзейсніць выдаленне."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Памылка"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Не ўдалося выдаліць праграму."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Выдаліць праграму"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Выдаліць абнаўленне"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> з\'яўляецца часткай наступнай праграмы:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Выдаліць гэту праграму?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Выдаліць гэту праграму для "<b>"ўсіх"</b>" карыстальнікаў? Праграма і яе даныя будуць выдалены для "<b>"ўсіх"</b>" карыстальнікаў прылады."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Хочаце выдаліць гэту праграму для карыстальніка <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Замяніць гэту праграму заводскай версіяй? Усе даныя будуць выдалены."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Замяніць гэту праграму заводскай версіяй? Усе даныя будуць выдалены. Гэта паўплывае на ўсіх карыстальнікаў гэтай прылады, уключаючы карыстальнікаў з працоўнымі профілямі."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Актыўныя выдаленні"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Нявыкананыя выдаленні"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Ідзе выдаленне…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> выдаляецца…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Выдаленне завершана."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Дзеянні па ўсталяванні або выдаленні не падтрымліваюцца на Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Праграма падрыхтоўваецца…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Невядома"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"У мэтах бяспекі вашаму планшэту забаронена ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"У мэтах бяспекі вашаму тэлевізару забаронена ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"У мэтах бяспекі вашаму тэлефону забаронена ўсталёўваць невядомыя праграмы з гэтай крыніцы."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Ваш тэлефон і асабістыя даныя больш прыступныя для атак невядомых праграм. Усталёўваючы гэту праграму, вы згаджаецеся з тым, што несяце адказнасць за любыя пашкоджанні тэлефона ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Ваш планшэт і асабістыя даныя больш прыступныя для атак невядомых праграм. Усталёўваючы гэту праграму, вы згаджаецеся з тым, што несяце адказнасць за любыя пашкоджанні планшэта ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Ваш тэлевізар і асабістыя даныя больш прыступныя для атак невядомых праграм. Усталёўваючы гэту праграму, вы згаджаецеся з тым, што несяце адказнасць за любыя пашкоджанні тэлевізара ці страту даных, якія могуць адбыцца ў выніку выкарыстання гэтай праграмы."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Далей"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Налады"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Усталяванне і выдаленне праграм Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-bg/strings.xml b/packages/PackageInstaller/res/values-bg/strings.xml
index 30d99eb..a1ae85c 100644
--- a/packages/PackageInstaller/res/values-bg/strings.xml
+++ b/packages/PackageInstaller/res/values-bg/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Инсталираща програма за пакети"</string>
-    <string name="next" msgid="3057143178373252333">"Напред"</string>
-    <string name="install" msgid="5896438203900042068">"Инсталиране"</string>
-    <string name="done" msgid="3889387558374211719">"Готово"</string>
-    <string name="cancel" msgid="8360346460165114585">"Назад"</string>
-    <string name="installing" msgid="8613631001631998372">"Инсталира се..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се инсталира…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Приложението бе инсталирано."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Искате ли да инсталирате това приложение? То ще получи достъп до:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Искате ли да инсталирате това приложение? То не изисква никакъв специален достъп."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Искате ли да инсталирате актуализация за това съществуващо приложение? Съществуващите ви данни няма да бъдат загубени. Актуализираното приложение ще получи достъп до:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Искате ли да инсталирате актуализация за това вградено приложение? Съществуващите ви данни няма да бъдат загубени. Актуализираното приложение ще получи достъп до:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Искате ли да инсталирате актуализация за това съществуващо приложение? Съществуващите ви данни няма да бъдат загубени. Не се изисква специален достъп."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Искате ли да инсталирате актуализация за това вградено приложение? Съществуващите ви данни няма да бъдат загубени. Не се изисква специален достъп."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Приложението не бе инсталирано."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Инсталирането на пакета бе блокирано."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Приложението не бе инсталирано, тъй като пакетът е в конфликт със съществуващ пакет."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Приложението не бе инсталирано, тъй като не е съвместимо с таблета ви."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Това приложение не е съвместимо с телевизора ви."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Приложението не бе инсталирано, тъй като не е съвместимо с телефона ви."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Приложението не бе инсталирано, тъй като изглежда, че пакетът е невалиден."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира на таблета ви."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира на телевизора ви."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира на телефона ви."</string>
-    <string name="launch" msgid="4826921505917605463">"Отваряне"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Администраторът ви не разрешава инсталирането на приложения, получени от неизвестни източници"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Този потребител не може да инсталира неизвестни приложения"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Този потребител няма разрешение да инсталира приложения"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Управление на приложенията"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Няма място"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира. Освободете място и опитайте отново."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Приложението не бе намерено"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Приложението не бе намерено в списъка с инсталирани приложения."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Няма разрешение"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Текущият потребител няма разрешение да извърши това деинсталиране."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Грешка"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Приложението не можа да бъде деинсталирано."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Деинсталиране на приложението"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Деинсталиране на актуализацията"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> е част от следното приложение:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Искате ли да деинсталирате това приложение?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Искате ли да деинсталирате това приложение за "<b>"всички"</b>" потребители? Приложението и данните му ще бъдат премахнати от "<b>"всички"</b>" потребители на устройството."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Искате ли да деинсталирате това приложение за потребителя <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Това приложение да се замени ли с фабричната версия? Всички данни ще бъдат премахнати."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Това приложение да се замени ли с фабричната версия? Всички данни ще бъдат премахнати. Промяната ще засегне всеки потребител на устройството, включително тези със служебни потребителски профили."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Активни деинсталирания"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Неуспешни деинсталирания"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Деинсталира се..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Деинсталирането завърши."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Деинсталирахте <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Деинсталирането не бе успешно."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Деинсталирането на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> бе неуспешно."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Активното приложение за администриране на устройството не може да се деинсталира"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Активното приложение за администриране на устройството не може да се деинсталира за <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Това приложение е необходимо за някои потребители или потребителски профили и бе деинсталирано за други."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Това приложение е необходимо за потребителския ви профил и не може да се деинсталира."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Приложението се изисква от администратора на у-вото и не може да се деинсталира."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Управление на прилож. за администриране на у-вото"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Управление на потребителите"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се деинсталира."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"При синтактичния анализ на пакета възникна проблем."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Нови"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Всички"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Поверителност"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Достъп до у-вото"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Тази актуализация не изисква нови разрешения."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Отказване"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Още информация"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Отказване въпреки това"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> от <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Разрешаване на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Винаги ли да се разрешава на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Само при използване на приложението"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Винаги"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Отказване, без повторно запитване"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Деактивирахте <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"всички са деактивирани"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"няма деактивирани"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Разрешаване"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Приложения"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Разрешения за приложения"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Без повторно питане"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Няма разрешения"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Допълнителни разрешения"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Отваряне на информацията за приложението"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Още <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Още <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Това приложение е създадено за по-стара версия на Android. То може да спре да функционира нормално при отказване на разрешението."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"извършване на неизвестно действие"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> от <xliff:g id="COUNT_1">%2$d</xliff:g> приложения имат разрешение"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Системни приложения"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Скриване на системните"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Няма приложения"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Настройки за местоположението"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> е доставчик на услуги за местоположението за това устройство. Достъпът до местоположението може да бъде променен от съответните настройки."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ако откажете това разрешение, основни функции на устройството ви може да спрат да работят както трябва."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Наложено чрез правило"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Достъпът на заден план е деактивиран от правилата"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Достъпът на заден план е активиран от правилата"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Достъпът на преден план е активиран от правилата"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Контролира се от администратор"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Винаги"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Само при използване на прилож."</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Никога"</string>
-    <string name="loading" msgid="7811651799620593731">"Зарежда се…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Всички разрешения"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Други възможности на приложението"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Заявка за разрешение"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Открито е екранно наслагване"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"За да промените настройката за това разрешение, трябва първо да изключите екранното наслагване от „Настройки“ &gt; „Приложения“"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Отваряне на настройките"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Действията инсталиране и деинсталиране не се поддържат на устройства с Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Изберете до какво да има достъп &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Приложението &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; е актуализирано. Изберете до какво да има достъп."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Отказ"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Напред"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Нови разрешения"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Текущи разрешения"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Приложението се подготвя…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Неизвестно"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"От съображения за сигурност на таблета ви не могат да се инсталират неизвестни приложения от този източник."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"От съображения за сигурност на телевизора ви не могат да се инсталират неизвестни приложения от този източник."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"От съображения за сигурност на телефона ви не могат да се инсталират неизвестни приложения от този източник."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефонът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на телефона или загуба на информация вследствие на използването на приложението."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Таблетът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на таблета или загуба на информация вследствие на използването на приложението."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Телевизорът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на телевизора или загуба на информация вследствие на използването на приложението."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Напред"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Настройки"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Инсталир./деинсталир. на прилож. за Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Пакети: Инстал. програма"</string>
+    <string name="install" msgid="711829760615509273">"Инсталиране"</string>
+    <string name="done" msgid="6632441120016885253">"Готово"</string>
+    <string name="cancel" msgid="1018267193425558088">"Отказ"</string>
+    <string name="installing" msgid="4921993079741206516">"Инсталира се..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се инсталира…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Приложението бе инсталирано."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Искате ли да инсталирате това приложение?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Искате ли да инсталирате актуализация за това съществуващо приложение? Съществуващите ви данни няма да бъдат загубени."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Искате ли да инсталирате актуализация за това вградено приложение? Съществуващите ви данни няма да бъдат загубени."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Приложението не бе инсталирано."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирането на пакета бе блокирано."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Приложението не бе инсталирано, тъй като пакетът е в конфликт със съществуващ пакет."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Приложението не бе инсталирано, тъй като не е съвместимо с таблета ви."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Това приложение не е съвместимо с телевизора ви."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Приложението не бе инсталирано, тъй като не е съвместимо с телефона ви."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Приложението не бе инсталирано, тъй като изглежда, че пакетът е невалиден."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира на таблета ви."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Този потребител не може да инсталира неизвестни приложения"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Този потребител няма разрешение да инсталира приложения"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Прил.: Управл."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Няма място"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можа да се инсталира. Освободете място и опитайте отново."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Приложението не бе намерено"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Приложението не бе намерено в списъка с инсталирани приложения."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Не е разрешено"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Текущият потребител няма разрешение да извърши това деинсталиране."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Грешка"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Приложението не можа да бъде деинсталирано."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Деинсталиране на приложението"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Деинст. на актуализацията"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> е част от следното приложение:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Искате ли да деинсталирате това приложение?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Искате ли да деинсталирате това приложение за "<b>"всички"</b>" потребители? Приложението и данните му ще бъдат премахнати от "<b>"всички"</b>" потребители на устройството."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Искате ли да деинсталирате това приложение за потребителя <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Това приложение да се замени ли с фабричната версия? Всички данни ще бъдат премахнати."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Това приложение да се замени ли с фабричната версия? Всички данни ще бъдат премахнати. Промяната ще засегне всеки потребител на устройството, включително тези със служебни потребителски профили."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Активни деинсталирания"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Неуспешни деинсталирания"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Деинсталира се..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Деинсталирането завърши."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Действията инсталиране и деинсталиране не се поддържат на устройства с Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Приложението се подготвя…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Неизвестно"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"От съображения за сигурност на таблета ви не могат да се инсталират неизвестни приложения от този източник."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"От съображения за сигурност на телевизора ви не могат да се инсталират неизвестни приложения от този източник."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"От съображения за сигурност на телефона ви не могат да се инсталират неизвестни приложения от този източник."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефонът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на телефона или загуба на информация вследствие на използването на приложението."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблетът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на таблета или загуба на информация вследствие на използването на приложението."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Телевизорът и личните ви данни са по-уязвими към атаки от неизвестни приложения. С инсталирането на това приложение приемате, че носите отговорност при евентуална повреда на телевизора или загуба на информация вследствие на използването на приложението."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Напред"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Настройки"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Инсталир./деинсталир. на прилож. за Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml
index c66f5bb..0afcb81 100644
--- a/packages/PackageInstaller/res/values-bn/strings.xml
+++ b/packages/PackageInstaller/res/values-bn/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"প্যাকেজ ইনস্টলার"</string>
-    <string name="next" msgid="3057143178373252333">"পরবর্তী"</string>
-    <string name="install" msgid="5896438203900042068">"ইনস্টল করুন"</string>
-    <string name="done" msgid="3889387558374211719">"সম্পন্ন হয়েছে"</string>
-    <string name="cancel" msgid="8360346460165114585">"বাতিল করুন"</string>
-    <string name="installing" msgid="8613631001631998372">"ইনস্টল করা হচ্ছে…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ইন্সটল করা হচ্ছে…"</string>
-    <string name="install_done" msgid="3682715442154357097">"অ্যাপ্লিকেশান ইনস্টল করা হয়েছে৷"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"আপনি কি এই অ্যাপ্লিকেশানটি ইনস্টল করতে চান? এর মাধ্যমে যেসব জিনিস অ্যাক্সেস করার সুবিধা পাবেন সেগুলি হল:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"আপনি কি এই অ্যাপ্লিকেশানটি ইনস্টল করতে চান? এর জন্য কোনো বিশেষ অ্যাক্সেসের প্রয়োজন নেই৷"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"আপনি কি এই বিদ্যমান অ্যাপ্লিকেশানের একটি আপডেট ইনস্টল করতে চান? আপনার বিদ্যমান ডেটাগুলি একই রকম থাকবে৷ এই আপডেট হওয়া অ্যাপ্লিকেশানটির মাধ্যমে যেসব জিনিস অ্যাক্সেস করার সুবিধা পাবেন সেগুলি হল:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"আপনি কি এই ভেতরে থাকা অ্যাপ্লিকেশানের একটি আপডেট ইনস্টল করতে চান? আপনার বিদ্যমান ডেটাগুলি একই রকম থাকবে৷ এই আপডেট হওয়া অ্যাপ্লিকেশানটির মাধ্যমে যেসব জিনিস অ্যাক্সেস করার সুবিধা পাবেন সেগুলি হল:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"আপনি কি এই বিদ্যমান অ্যাপ্লিকেশানের একটি আপডেট ইনস্টল করতে চান? আপনার বিদ্যমান ডেটাগুলি একই রকম থাকবে৷ এর জন্য কোনো বিশেষ অ্যাক্সেসের প্রয়োজন নেই৷"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"আপনি কি ভেতরে থাকা অ্যাপ্লিকেশানের একটি আপডেট ইনস্টল করতে চান? আপনার বিদ্যমান ডেটাগুলি একই রকম থাকবে৷ এর জন্য কোনো বিশেষ অ্যাক্সেসের প্রয়োজন নেই৷"</string>
-    <string name="install_failed" msgid="6579998651498970899">"অ্যাপ্লিকেশান ইনস্টল করা হয়নি৷"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ইনস্টল হওয়া থেকে প্যাকেজটিকে অবরুদ্ধ করা হয়েছে।"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"কোনো বিদ্যমান প্যাকেজের সাথে এই প্যাকেজটির বিবাদ থাকার ফলে অ্যাপ ইনস্টল করা হয়নি৷"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"অ্যাপটি আপনার ট্যাবলেটের জন্য উপযুক্ত না হওয়ার কারণে এটি ইনস্টল করা হয়নি৷"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"এই অ্যাপ্লিকেশানটি আপনার টিভির জন্য উপযুক্ত নয়৷"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"অ্যাপটি আপনার ফোনের জন্য উপযুক্ত না হওয়ার কারণে এটি ইনস্টল করা হয়নি৷"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"প্যাকেজটি অবৈধ বলে মনে হওয়ার কারণে অ্যাপ ইনস্টল করা হয়নি৷"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> আপনার ট্যাবলেটে ইনস্টল করা যায়নি৷"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>-কে আপনার টিভিতে ইনস্টল করা যাবে না৷"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> আপনার ফোনে ইনস্টল করা যায়নি৷"</string>
-    <string name="launch" msgid="4826921505917605463">"খুলুন"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"আপনার প্রশাসক অজানা উৎস থেকে প্রাপ্ত অ্যাপ ইনস্টল করার অনুমতি দেয় না"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"এই ব্যবহারকারী অজানা অ্যাপ ইনস্টল করতে পারবেন না"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"এই ব্যবহারকারী অ্যাপ ইনস্টল করার অনুমতি পাননি"</string>
-    <string name="ok" msgid="3468756155452870475">"ঠিক আছে"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"অ্যাপ্লিকেশানগুলির পরিচালনা করুন"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"পর্যাপ্ত জায়গা খালি নেই"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ইনস্টল করা যায়নি৷ কিছু পরিমাণ জায়গা খালি করে আবার চেষ্টা করুন৷"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"অ্যাপ্লিকেশান পাওয়া যায়নি"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"অ্যাপ্লিকেশানটিকে ইনস্টল করা অ্যাপ্লিকেশানের তালিকাতে পাওয়া যায়নি৷"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"অনুমোদিত নয়"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"বর্তমান ব্যবহারকারী এই আনইনস্টলের কাজটি করার জন্য অনুমোদিত নয়৷"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"ত্রুটি"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"অ্যাপ আনইনস্টল করা গেল না৷"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"অ্যাপ্লিকেশানটিকে আনইনস্টল করুন"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"আপডেট আনইনস্টল করুন"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> হল নিম্নলিখিত অ্যাপ্লিকেশানগুলির অংশ বিশেষ:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"আপনি কি এই অ্যাপ্লিকেশানটিকে আনইনস্টল করতে চান?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"আপনি কি "<b>"সমস্ত"</b>" ব্যবহারকারীর জন্য এই অ্যাপ্লিকেশানটিকে আনইনস্টল করতে চান? এই ডিভাইসের "<b>"সমস্ত"</b>" ব্যবহারকারীর কাছ থেকে অ্যাপ্লিকেশানটি ও এর ডেটা হারিয়ে যাবে৷"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"আপনি কি ব্যবহারকারী <xliff:g id="USERNAME">%1$s</xliff:g> এর জন্য এই অ্যাপ্লিকেশানটি আনইনস্টল করতে চান?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ফ্যাক্টরি সংস্করণের সাথে এই অ্যাপটিকে বদলাবেন? সব ডেটা মুছে যাবে।"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ফ্যাক্টরি সংস্করণের সাথে এই অ্যাপটিকে বদলাবেন? সমস্ত ডেটা মুছে যাবে। এটি এই ডিভাইসের সমস্ত ব্যবহারকারী সহ তাদের কার্যের প্রোফাইলের উপরেও প্রভাব ফেলবে।"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"এগুলি আনইনস্টল করা হচ্ছে"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"এগুলি আনইনস্টল করা যায়নি"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"আনইনস্টল করা হচ্ছে ..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হচ্ছে…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"আনইনস্টল সমাপ্ত হয়েছে৷"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হয়েছে"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"আনইনস্টল সফল হয়নি৷"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা গেল না৷"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"সক্রিয় থাকা ডিভাইস প্রশাসক অ্যাপটি আনইনস্টল করা যাবে না"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> এর সক্রিয় থাকা ডিভাইস প্রশাসক অ্যাপটি আনইনস্টল করা যাবে না"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"কিছু ব্যবহারকারী বা প্রোফাইলের জন্য এই অ্যাপ্লিকেশানটি আবশ্যক এবং অন্যদের জন্য আনইনস্টল করা হবে"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"আপনার প্রোফাইলের জন্য এই অ্যাপ্লিকেশানটি প্রয়োজন এবং এটিকে আনইনস্টল করা যাবে না৷"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"আপনার ডিভাইস প্রশাসকের চাহিদা অনুযায়ী এই অ্যাপ্লিকেশানটি আবশ্যক এবং এটি আনইনস্টল করা যাবে না।"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"ডিভাইস প্রশাসক অ্যাপগুলি পরিচালনা করুন"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ব্যবহারকারীদের পরিচালনা করুন"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> আনইনস্টল করা যায়নি৷"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"প্যাকেজটি বিশ্লেষণ করার ক্ষেত্রে একটি সমস্যা হয়েছে৷"</string>
-    <string name="newPerms" msgid="6039428254474104210">"নতুন"</string>
-    <string name="allPerms" msgid="1024385515840703981">"সমস্ত"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"গোপনীয়তা"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ডিভাইসের অ্যাক্সেস"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"এই আপডেটের জন্য কোনো নতুন অনুমতির প্রয়োজন নেই৷"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"প্রত্যাখ্যান করুন"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"আরও তথ্য"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"যাইহোক অস্বীকার করুন"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> এর <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;কে <xliff:g id="ACTION">%2$s</xliff:g> এর অনুমতি দেবেন?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<xliff:g id="ACTION">%2$s</xliff:g>-এ সবসময় &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; অনুমতি দেবেন?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"অ্যাপটি ব্যবহার করার সময়"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"সবসময়"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"অস্বীকার করুন এবং আবার জিজ্ঞাসা করবেন না"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>টি অক্ষম করা হয়েছে"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"সমস্ত অক্ষম করা হয়েছে"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"কোনো কিছুই অক্ষম করা হয়নি"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"অনুমতি দিন"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"অ্যাপ"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"অ্যাপ্লিকেশনের অনুমতি"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"আর জিজ্ঞাসা করবেন না"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"কোনো অনুমতি নেই"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"অতিরিক্ত অনুমতিগুলি"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"অ্যাপের তথ্য দেখুন"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">আরও <xliff:g id="COUNT_1">%1$d</xliff:g>টি</item>
-      <item quantity="other">আরও <xliff:g id="COUNT_1">%1$d</xliff:g>টি</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"একটি পুরোনো সংস্করণের Android এর জন্য এই অ্যাপ্লিকেশানটি ডিজাইন করা হয়েছিল৷ অনুমতি অস্বীকার করলে এটিকে যে কাজের উদ্দেশ্যে তৈরি করা হয়েছিল সেটি নাও করতে পারে৷"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"কোনো অজানা কার্য সঞ্চালন করুন"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>টির মধ্যে <xliff:g id="COUNT_0">%1$d</xliff:g>টি অ্যাপ্লিকেশান মঞ্জুরিপ্রাপ্ত"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"সিস্টেম দেখুন"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"সিস্টেম লুকান"</string>
-    <string name="no_apps" msgid="1965493419005012569">"কোনো অ্যাপ্লিকেশান নেই"</string>
-    <string name="location_settings" msgid="1774875730854491297">"লোকেশন সেটিংস"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> এই ডিভাইসের জন্য একটি লোকেশন পরিষেবাগুলি প্রদান করে। লোকেশন সেটিংস থেকে লোকেশনের অ্যাক্সেস পরিবর্তন করা যায়।"</string>
-    <string name="system_warning" msgid="7103819124542305179">"আপনি যদি এই অনুমতিটি অস্বীকার করেন, তবে আপনার ডিভাইসের প্রাথমিক বৈশিষ্ট্যগুলিকে যে কাজের উদ্দেশ্যে তৈরি করা হয়েছিল সেগুলি নাও করতে পারে৷"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"নীতি দ্বারা প্রয়োগ করা হয়েছে"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"নীতির কারণে ব্যাকগ্রাউন্ড অ্যাক্সেস বন্ধ করা আছে"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"নীতির কারণে ব্যাকগ্রাউন্ড অ্যাক্সেস চালু করা আছে"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"নীতির কারণে খুলে রাখা অ্যাপের অ্যাক্সেস চালু করা আছে"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"অ্যাডমিনের দ্বারা নিয়ন্ত্রিত"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"সবসময়"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"অ্যাপটি ব্যবহার করার সময়"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"কখনও না"</string>
-    <string name="loading" msgid="7811651799620593731">"লোড হচ্ছে..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"সমস্ত অনুমতি"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"অন্যান্য অ্যাপ্লিকেশান ক্ষমতা"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"অনুমতির অনুরোধ"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"স্ক্রিন আচ্ছাদন শনাক্ত করা হয়েছে"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"এই অনুমতি সেটিংস পরিবর্তন করতে, আপনাকে প্রথমে সেটিংস &gt; এ গিয়ে অ্যাপ্লিকেশানগুলি থেকে স্ক্রিন ওভারলে বন্ধ করতে হবে"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"সেটিংস খুলুন"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ওয়েরে ইনস্টল/আনইনস্টল করার কাজগুলি সমর্থিত নয়।"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; কে কোন জিনিসগুলিতে অ্যাক্সেস দেবেন তা বেছে নিন"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; আপডেট করা হয়েছে৷ এই অ্যাপ্লিকেশানটিকে কোন জিনিসগুলিতে অ্যাক্সেস দেবেন তা চয়ন করুন৷"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"বাতিল করুন"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"চালিয়ে যান"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"নতুন অনুমতিগুলি"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"বর্তমান অনুমতিগুলি"</string>
-    <string name="message_staging" msgid="6151794817691100003">"অ্যাপ্লিকেশান স্টেজ করা হচ্ছে..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"অজানা"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"আপনার নিরাপত্তার জন্য আপনার ট্যাবলেট কে এই উৎস থেকে আসা অজানা অ্যাপ ইনস্টল করার অনুমতি দেওয়া হয় না।"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"আপনার নিরাপত্তার জন্য আপনার TV কে এই উৎস থেকে আসা অজানা অ্যাপ ইনস্টল করার অনুমতি দেওয়া হয় না।"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"আপনার নিরাপত্তার জন্য আপনার ফোন কে এই উৎস থেকে আসা অজানা অ্যাপ ইনস্টল করার অনুমতি দেওয়া হয় না।"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"অজানা অ্যাপের দ্বারা আপনার ফোন এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হলেন যে এটি ব্যবহারের ফলে আপনার ফোনের বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"অজানা অ্যাপের দ্বারা আপনার ট্যাবলেট এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হলেন যে এটি ব্যবহারের ফলে আপনার ট্যাবলেটের বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"অজানা অ্যাপের দ্বারা আপনার টিভি এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হলেন যে এটি ব্যবহারের ফলে আপনার টিভি বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"চালিয়ে যান"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"সেটিংস"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"ওয়্যার অ্যাপ ইনস্টল/আনইনস্টল করা হচ্ছে"</string>
+    <string name="app_name" msgid="7488448184431507488">"প্যাকেজ ইনস্টলার"</string>
+    <string name="install" msgid="711829760615509273">"ইনস্টল করুন"</string>
+    <string name="done" msgid="6632441120016885253">"হয়ে গেছে"</string>
+    <string name="cancel" msgid="1018267193425558088">"বাতিল করুন"</string>
+    <string name="installing" msgid="4921993079741206516">"ইনস্টল করা হচ্ছে…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ইনস্টল করা হচ্ছে…"</string>
+    <string name="install_done" msgid="5987363587661783896">"অ্যাপটি ইনস্টল করা হয়ে গেছে।"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"আপনি কি এই অ্যাপ্লিকেশনটি ইনস্টল করতে চান?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"আগে থেকেই আছে এই অ্যাপ্লিকেশনটির একটি আপডেট কি আপনি ইনস্টল করতে চান? আপনার আগে থেকেই আছে এমন ডেটা মুছে যাবে না।"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"এই বিল্ট-ইন অ্যাপ্লিকেশনটির একটি আপডেট কি আপনি ইনস্টল করতে চান? আপনার আগে থেকেই আছে এমন ডেটা মুছে যাবে না।"</string>
+    <string name="install_failed" msgid="5777824004474125469">"অ্যাপটি ইনস্টল করা হয়নি।"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"ইনস্টল হওয়া থেকে প্যাকেজটিকে ব্লক করা হয়েছে।"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"আগে থেকেই আছে এমন একটি প্যাকেজের সাথে প্যাকেজটির সমস্যা সৃষ্টি হওয়ায় অ্যাপটি ইনস্টল করা যায়নি।"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"আপনার ট্যাবলেটের সাথে মানানসই না হওয়ায় অ্যাপটি ইনস্টল করা যায়নি।"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"এই অ্যাপটি আপনার টিভির সাথে মানানসই নয়।"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"আপনার ফোনের সাথে মানানসই না হওয়ায় অ্যাপটি ইনস্টল করা যায়নি।"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"প্যাকেজটি সঠিক না হওয়ায় অ্যাপটি ইনস্টল করা হয়নি।"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> আপনার ট্যাবলেটে ইনস্টল করা যায়নি।"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"এই ব্যবহারকারী অজানা অ্যাপ ইনস্টল করতে পারেন না"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"এই ব্যবহারকারীর অ্যাপ ইনস্টল করার অনুমতি নেই"</string>
+    <string name="ok" msgid="7871959885003339302">"ঠিক আছে"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"অ্যাপ পরিচালনা"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"জায়গা খালি নেই"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ইনস্টল করা যায়নি। কিছু পরিমাণ জায়গা খালি করে আবার চেষ্টা করুন।"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"অ্যাপটি পাওয়া যায়নি"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ইনস্টল করা অ্যাপের সূচিতে এই অ্যাপটি পাওয়া যায়নি।"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"অনুমতি নেই"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"বর্তমান ব্যবহারকারীর এই আনইনস্টল করার অনুমতি নেই।"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"সমস্যা"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"অ্যাপটি আনইনস্টল করা যায়নি।"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"অ্যাপ আনইনস্টল করুন"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"আপডেট আনইনস্টল করুন"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> এই অ্যাপটির অংশ:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"আপনি কি এই অ্যাপটি আনইনস্টল করতে চান?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"আপনি কি "<b>"সব"</b>" ব্যবহারকারীর জন্য এই অ্যাপটিকে আনইনস্টল করতে চান? এই ডিভাইসের "<b>"সব"</b>" ব্যবহারকারীর ডেটা সহ এই অ্যাপ্লিকেশনটি সরিয়ে দেওয়া হবে।"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"আপনি কি <xliff:g id="USERNAME">%1$s</xliff:g>-এর জন্য এই অ্যাপটি আনইনস্টল করতে চান?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ফ্যাক্টরি ভার্সন দিয়ে এই অ্যাপটিকে বদলাতে চান? সব ডেটা মুছে যাবে।"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ফ্যাক্টরি ভার্সন দিয়ে এই অ্যাপটিকে বদলাতে চান? সব ডেটা মুছে যাবে। এই ডিভাইসে কাজের প্রোফাইল আছে এমন ব্যবহারকারী সহ সবাই এর দ্বারা প্রভাবিত হবেন।"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"আনইনস্টল করা হচ্ছে"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"আনইনস্টল করা যায়নি"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"আনইনস্টল করা হচ্ছে…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হচ্ছে…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"আনইনস্টল করা শেষ হয়েছে।"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear-এ ইনস্টল/আনইনস্টল করা সমর্থিত নয়।"</string>
+    <string name="message_staging" msgid="8032722385658438567">"অ্যাপ স্টেজ করা হচ্ছে…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"অজানা"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"আপনার নিরাপত্তার জন্য, এই অজানা উৎস থেকে আপনার ট্যাবলেটের অ্যাপ ইনস্টল করার অনুমতি নেই।"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"আপনার নিরাপত্তার জন্য, এই অজানা উৎস থেকে আপনার টিভির অ্যাপ ইনস্টল করার অনুমতি নেই।"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"আপনার নিরাপত্তার জন্য, এই অজানা উৎস থেকে আপনার ফোনের অ্যাপ ইনস্টল করার অনুমতি নেই।"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"অজানা অ্যাপের দ্বারা আপনার ফোন এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হচ্ছেন যে এটি ব্যবহারের ফলে আপনার ফোনের বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"অজানা অ্যাপের দ্বারা আপনার ট্যাবলেট এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হচ্ছেন যে এটি ব্যবহারের ফলে আপনার ট্যাবলেটের বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"অজানা অ্যাপের দ্বারা আপনার টিভি এবং ব্যক্তিগত ডেটা আক্রান্ত হওয়ার সম্ভাবনা বেশি থাকে। এই অ্যাপটি ইনস্টল করার মাধ্যমে আপনি সম্মত হচ্ছেন যে এটি ব্যবহারের ফলে আপনার টিভি বা ডেটার কোনও ক্ষতি হলে তার জন্য আপনিই দায়ী থাকবেন।"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"চালিয়ে যান"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"সেটিংস"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear অ্যাপ ইনস্টল/আনইনস্টল করা হচ্ছে"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-bs/strings.xml b/packages/PackageInstaller/res/values-bs/strings.xml
index 3f2c5c3..1cb8b37 100644
--- a/packages/PackageInstaller/res/values-bs/strings.xml
+++ b/packages/PackageInstaller/res/values-bs/strings.xml
@@ -16,142 +16,76 @@
 
 <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="2738748390251381682">"Alat za instaliranje paketa"</string>
-    <string name="next" msgid="3057143178373252333">"Naprijed"</string>
-    <string name="install" msgid="5896438203900042068">"Instaliraj"</string>
-    <string name="done" msgid="3889387558374211719">"Gotovo"</string>
-    <string name="cancel" msgid="8360346460165114585">"Otkaži"</string>
-    <string name="installing" msgid="8613631001631998372">"Instalacija u toku..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instaliranje <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikacija je instalirana."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Želite li instalirati ovu aplikaciju? Ona će dobiti pristup:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Želite li instalirati ovu aplikaciju? Ona ne zahtijeva poseban pristup."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Želite li ažurirati ovu postojeću aplikaciju? Vaši postojeći podaci neće biti izgubljeni. Ažurirana aplikacija će dobiti pristup:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Želite li ažurirati ovu ugrađenu aplikaciju? Vaši postojeći podaci neće biti izgubljeni. Ažurirana aplikacija će dobiti pristup:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Želite li ažurirati ovu postojeću aplikaciju? Vaši postojeći podaci neće biti izgubljeni. Za ovo nije potreban poseban pristup."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Želite li ažurirati ovu ugrađenu aplikaciju? Vaš postojeći podaci neće biti izgubljeni. Nije potreban poseban pristup."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikacija nije instalirana."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Instaliranje ovog paketa je blokirano."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacija nije instalirana jer paket nije usaglašen s postojećim paketom."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacija nije instalirana jer nije kompatibilna s vašim tabletom."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ova aplikacija nije kompatibilna s vašim TV-om."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacija nije instalirana jer nije kompatibilna s vašim telefonom."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacija nije instalirana jer izgleda da paket nije važeći."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> ne možete instalirati na svoj tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na vaš TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> ne možete instalirati na svoj telefon."</string>
-    <string name="launch" msgid="4826921505917605463">"Otvori"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Vaš administrator ne dozvoljava instaliranje aplikacija iz nepoznatih izvora."</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ovaj korisnik ne može instalirati nepoznate aplikacije."</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ovom korisniku nije dozvoljeno instaliranje aplikacija"</string>
-    <string name="ok" msgid="3468756155452870475">"Uredu"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Upravljaj aplikacijama"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nedostatak prostora"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Ne možete instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite prostora u pohrani i pokušajte ponovo."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacija nije pronađena"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacija nije pronađena na spisku instaliranih aplikacija."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nije dozvoljeno"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Trenutnom korisniku nije dozvoljeno da izvrši ovu deinstalaciju."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Greška"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Nije bilo moguće deinstalirati aplikaciju."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Uklanjanje aplikacije"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Uklanjanje ažuriranja"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je dio sljedeće aplikacije:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Želite li ukloniti ovu aplikaciju?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Želite li ukloniti ovu aplikaciju za "<b>" sve "</b>" korisnike? Aplikacija i njeni podaci će biti uklonjeni iz "<b>" svih "</b>" korisničkih računa na uređaju."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Želite li ukloniti ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Želite li ovu aplikaciju zamijeniti s fabričkom verzijom? Svi podaci će biti uklonjeni."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Želite li ovu aplikaciju zamijeniti s fabričkom verzijom? Svi podaci će biti uklonjeni. To će utjecati na sve korisnike uređaja, uključujući i one s radnim profilima."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Tekuća deinstaliranja"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neuspjela deinstaliranja"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Uklanjanje u toku..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Deinstalacija paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Uklanjanje završeno."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Deinstaliran je paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Uklanjanje nije uspjelo."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspješno deinstaliran."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nije moguće deinstalirati aktivnu aplikaciju administratora uređaja"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nije moguće deinstalirati aktivnu aplikaciju administratora uređaja za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ova aplikacija je neophodna nekim korisnicima ili profilima, a kod ostalih je deinstalirana"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ova aplikacija je potrebna za vaš profil i ne može se deinstalirati."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ova aplikacija je potrebna administratoru vašeg uređaja i ne može se ukloniti."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Upravljajte aplikacijama administratora uređaja"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Upravljanje korisnicima"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> se ne može ukloniti."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Došlo je do problema prilikom raščlanjivanja paketa."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Sve"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privatnost"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Pristup uređaju"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Za ovo ažuriranje nisu potrebne nova odobrenja."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odbij"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Više informacija"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Odbij svakako"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> od <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Dozvoliti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; da <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Uvijek dozvoliti da aplikacija &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Samo dok se koristi aplikacija"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Uvijek"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odbij i ne pitaj ponovo"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"omogućeno je <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"sve je onemogućeno"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ništa nije onemogućeno"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Dozvoli"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacije"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Odobrenja za aplikacije"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ne pitaj ponovo"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Nema odobrenja"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Dodatna odobrenja"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otvori informacije o aplikaciji"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="few">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ova aplikacija je kreirana za stariju verziju Androida. Odbijanje odobrenja može uzrokovati da ona više ne funkcionira onako kako je primarno zamišljeno."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"izvrši nepoznatu radnju"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Aplikacije sa odobrenjem: <xliff:g id="COUNT_0">%1$d</xliff:g> od <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Prikaži sistemske aplikacije"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Sakrij sistemske"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nijedna aplikacija"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Postavke lokacije"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> pruža usluge lokacije za ovaj uređaj. Pristup lokaciji se može izmijeniti u postavkama lokacije."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ukoliko odbijete ovo odobrenje, osnovne funkcije vašeg uređaja možda više neće funkcionirati onako kako je prvobitno zamišljeno."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Nametnuto je pravilima"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Pristup pozadini je onemogućen u skladu s pravilima"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Pristup pozadini je omogućen u skladu s pravilima"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Pristup u prvom planu je omogućen u skladu s pravilima"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolira administrator"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Uvijek"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Samo dok se koristi aplikacija"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nikada"</string>
-    <string name="loading" msgid="7811651799620593731">"Učitava se…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Sva odobrenja"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Ostale mogućnosti aplikacije"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Zahtjev za odobrenjem"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Otkriven je element koji prekriva sadržaj ekrana"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Da promijenite postavku ovog odobrenja, prvo morate isključiti element koji prekriva sadržaj ekrana u odjeljku Postavke &gt; Aplikacije"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Otvori postavke"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Instaliranje/deinstaliranje nije podržano na Wearu."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Odaberite čemu aplikacija &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&amp;Lt;/b&gt; može pristupiti"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacija &amp;Lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&amp;Lt;/b&gt; je ažurirana. Odaberite čemu ova aplikacija može pristupiti."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Otkaži"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Nastavi"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nova odobrenja"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Postojeća odobrenja"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Aplikacija se postavlja…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Nepoznato"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Vašem tabletu iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Vašem TV-u iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Vašem telefonu iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Vaši podaci na telefonu i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na telefonu ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Vaši podaci na tabletu i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na tabletu ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Vaši podaci na TV-u i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na TV-u ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Nastavi"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Postavke"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"(De)instaliranje wear aplikacija"</string>
+    <string name="app_name" msgid="7488448184431507488">"Alat za instalir. paketa"</string>
+    <string name="install" msgid="711829760615509273">"Instaliraj"</string>
+    <string name="done" msgid="6632441120016885253">"Gotovo"</string>
+    <string name="cancel" msgid="1018267193425558088">"Otkaži"</string>
+    <string name="installing" msgid="4921993079741206516">"Instaliranje…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instaliranje paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Želite li instalirati ovu aplikaciju?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Želite li instalirati ažuriranje za ovu postojeću aplikaciju? Vaši postojeći podaci neće biti izgubljeni."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Želite li instalirati ažuriranje za ovu ugrađenu aplikaciju? Vaš postojeći podaci neće biti izgubljeni."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje ovog paketa je blokirano."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija nije instalirana jer paket nije usaglašen s postojećim paketom."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikacija nije instalirana jer nije kompatibilna s vašim tabletom."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ova aplikacija nije kompatibilna s vašim TV-om."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikacija nije instalirana jer nije kompatibilna s vašim telefonom."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikacija nije instalirana jer izgleda da je paket nevažeći."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> ne možete instalirati na svoj tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Nije moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na vaš TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> ne možete instalirati na svoj telefon."</string>
+    <string name="launch" msgid="3952550563999890101">"Otvori"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Vaš administrator ne dozvoljava instaliranje aplikacija iz nepoznatih izvora"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ovaj korisnik ne može instalirati nepoznate aplikacije"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ovom korisniku nije dozvoljeno instaliranje aplikacija"</string>
+    <string name="ok" msgid="7871959885003339302">"UREDU"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Uprav. aplik."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nedostatak prostora"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Ne možete instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>. Oslobodite prostor u pohrani i pokušajte ponovo."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikacija nije pronađena"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikacija nije pronađena na spisku instaliranih aplikacija."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nije dozvoljeno"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Trenutnom korisniku nije dozvoljeno da izvrši ovu deinstalaciju."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Greška"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Aplikacija se ne može deinstalirati."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Deinstaliraj aplikaciju"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Deinstaliraj ažuriranje"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je dio sljedeće aplikacije:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Želite li deinstalirati ovu aplikaciju?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Želite li deinstalirati ovu aplikaciju za "<b>" sve "</b>" korisnike? Aplikacija i njeni podaci će biti uklonjeni iz "<b>" svih "</b>" korisničkih računa na uređaju."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Želite li deinstalirati ovu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Želite li ovu aplikaciju zamijeniti s fabričkom verzijom? Svi podaci će biti uklonjeni."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite li ovu aplikaciju zamijeniti s fabričkom verzijom? Svi podaci će biti uklonjeni. To će uticati na sve korisnike uređaja, uključujući i one s radnim profilima."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Tekuća deinstaliranja"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspjela deinstaliranja"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Deinstaliranje..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Deinstaliranje paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Deinstaliranje je završeno."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Deinstaliran je paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Deinstaliranje nije uspjelo."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspješno deinstaliran."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Nije moguće deinstalirati aktivnu aplikaciju administratora uređaja"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Nije moguće deinstalirati aktivnu aplikaciju administratora uređaja za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ova aplikacija je neophodna nekim korisnicima ili profilima, a za ostale je deinstalirana"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ova aplikacija je potrebna za vaš profil i ne može se deinstalirati."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ova aplikacija je potrebna administratoru vašeg uređaja i ne može se deinstalirati."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Upravljajte aplikacijama administratora uređaja"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Upravljajte korisnicima"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> se ne može deinstalirati."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Došlo je do problema prilikom raščlanjivanja paketa."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Instaliranje/deinstaliranje nije podržano na Wearu."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Pripremanje aplikacije…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Nepoznato"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Vašem tabletu iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Vašem TV-u iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Vašem telefonu iz sigurnosnih razloga nije dopušteno instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Vaši podaci na telefonu i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na telefonu ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Vaši podaci na tabletu i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na tabletu ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Vaši podaci na TV-u i vaši lični podaci izloženiji su napadima nepoznatih aplikacija. Instaliranjem ove aplikacije, saglasni ste da ste vi odgovorni za bilo kakvu štetu na TV-u ili gubitak podataka do kojih može doći korištenjem aplikacije."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Nastavi"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Postavke"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instaliranje/deinstaliranje Wear aplik."</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ca/strings.xml b/packages/PackageInstaller/res/values-ca/strings.xml
index 62d758c..f9ca139 100644
--- a/packages/PackageInstaller/res/values-ca/strings.xml
+++ b/packages/PackageInstaller/res/values-ca/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Instal·lador de paquets"</string>
-    <string name="next" msgid="3057143178373252333">"Següent"</string>
-    <string name="install" msgid="5896438203900042068">"Instal·la"</string>
-    <string name="done" msgid="3889387558374211719">"Fet"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancel·la"</string>
-    <string name="installing" msgid="8613631001631998372">"S\'està instal·lant..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"S\'està instal·lant <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplicació instal·lada."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Vols instal·lar aquesta aplicació? Tindrà els permisos següents:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vols instal·lar aquesta aplicació? No requereix cap accés especial."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Vols instal·lar una actualització per a aquesta aplicació? No es perdran les teves dades existents. L\'aplicació actualitzada tindrà els permisos següents:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vols instal·lar una actualització d\'aquesta aplicació integrada? No es perdran les teves dades. L\'aplicació actualitzada tindrà els permisos següents:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vols instal·lar una actualització a aquesta aplicació existent? Les dades existents no es perdran. No cal cap tipus d\'accés especial."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vols instal·lar una actualització a aquesta aplicació integrada? Les teves dades existents no es perdran. No cal cap tipus d\'accés especial."</string>
-    <string name="install_failed" msgid="6579998651498970899">"L\'aplicació no s\'ha instal·lat."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"El paquet s\'ha bloquejat perquè no es pugui instal·lar."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"L\'aplicació no s\'ha instal·lat perquè el paquet entra en conflicte amb un d\'existent."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"L\'aplicació no s\'ha instal·lat perquè no és compatible amb la teva tauleta."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aquesta aplicació no és compatible amb el teu televisor."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"L\'aplicació no s\'ha instal·lat perquè no és compatible amb el teu telèfon."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"L\'aplicació no s\'ha instal·lat perquè sembla que el paquet no és vàlid."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> no s\'ha pogut instal·lar a la tauleta."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> no s\'ha pogut instal·lar al televisor."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> no s\'ha pogut instal·lar al telèfon."</string>
-    <string name="launch" msgid="4826921505917605463">"Obre"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"L\'administrador no permet instal·lar aplicacions de fonts desconegudes"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Aquest usuari no pot instal·lar aplicacions desconegudes"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Aquest usuari no té permís per instal·lar aplicacions"</string>
-    <string name="ok" msgid="3468756155452870475">"D\'acord"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Gestiona les aplicacions"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Espai esgotat"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"No s\'ha pogut instal·lar <xliff:g id="APP_NAME">%1$s</xliff:g>. Allibera espai i torna-ho a provar."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"No s\'ha trobat l\'aplicació"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"No s\'ha trobat l\'aplicació a la llista d\'aplicacions instal·lades."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Sense autorització"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"L\'usuari actual no té permís per dur a terme aquesta desinstal·lació."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"No s\'ha pogut desinstal·lar l\'aplicació."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstal·la l\'aplicació"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstal·la l\'actualització"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma part de l\'aplicació següent:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Vols desinstal·lar aquesta aplicació?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vols desinstal·lar aquesta aplicació per a "<b>"tots"</b>" els usuaris? L\'aplicació i les seves dades se suprimiran per a "<b>"tots"</b>" els usuaris del dispositiu."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Vols desinstal·lar aquesta aplicació per a l\'usuari <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Si substitueixes aquesta aplicació per la versió de fàbrica, s\'esborraran totes les dades."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Si substitueixes aquesta aplicació per la versió de fàbrica, s\'esborraran totes les dades. Això afectarà tots els usuaris d\'aquest dispositiu, inclosos els que tinguin un perfil professional."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desinstal·lacions en curs"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Desinstal·lacions fallides"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"S\'està desinstal·lant..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"S\'està desinstal·lant <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Desinstal·lació finalitzada."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"S\'ha desinstal·lat <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"S\'ha produït un error en la desinstal·lació."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"No s\'ha pogut desinstal·lar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> correctament."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"No es pot desinstal·lar l\'aplicació activa de l\'administrador del dispositiu"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"No es pot desinstal·lar l\'aplicació activa de l\'administrador del dispositiu per a <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"L\'aplicació cal en alguns usuaris o perfils i s\'ha desinstal·lat per a d\'altres"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Aquesta aplicació es necessita per al teu perfil i no es pot desinstal·lar."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"L\'administrador del dispositiu necessita l\'aplicació i no la pots desinstal·lar."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gestiona aplicacions d\'administració del dispositiu"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gestiona els usuaris"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> no s\'ha pogut desinstal·lar."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"S\'ha produït un problema en analitzar el paquet."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nous"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Tots"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privadesa"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Accés al dispositiu"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Aquesta actualització no requereix permisos nous."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Denega"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Més informació"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Denega de totes maneres"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Vols permetre a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vols permetre que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Només mentre s\'utilitzi l\'aplicació"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Denega i no m\'ho tornis a preguntar"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> permisos desactivats"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"tots els permisos desactivats"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"cap permís desactivat"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permet"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicacions"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Permisos d\'aplicacions"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"No m\'ho tornis a preguntar"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Sense permisos"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Més permisos"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Obre la informació de l\'aplicació"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> més</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> més</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Aquesta aplicació es va dissenyar per a una versió anterior d\'Android. És possible que no funcioni com està previst si li denegues el permís."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"dur a terme una acció desconeguda"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicacions permeses"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Mostra aplicacions del sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Amaga aplicacions del sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Cap aplicació"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Configuració d\'ubicació"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> és un proveïdor de serveis d\'ubicació per a aquest dispositiu. L\'accés a la ubicació es pot modificar des de la configuració d\'ubicació."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Si rebutges aquest permís, és possible que funcions bàsiques del dispositiu deixin de funcionar correctament."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicat en funció de la política"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"S\'ha desactivat l\'accés en segon pla per la política"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"S\'ha activat l\'accés en segon pla per la política"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"S\'ha activat l\'accés en primer pla per la política"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlat per l\'administrador"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Només mentre s\'utilitzi l\'app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Mai"</string>
-    <string name="loading" msgid="7811651799620593731">"S\'està carregant..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Tots els permisos"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Altres competències de l\'aplicació"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Sol·licitud de permís"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"S\'ha detectat una superposició de pantalla"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Per canviar la configuració de permisos, cal que desactivis la superposició de pantalla des de Configuració &gt; Aplicacions"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Obre Configuració"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Les accions d\'instal·lar o de desinstal·lar no s\'admeten a Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Tria a què vols que tingui accés &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"S\'ha actualitzat &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;. Tria a què vols que tingui accés aquesta aplicació."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancel·la"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continua"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Permisos nous"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Permisos actuals"</string>
-    <string name="message_staging" msgid="6151794817691100003">"S\'està preparant la instal·lació de l\'aplicació…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Desconegut"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Per seguretat, la tauleta no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Per seguretat, el televisor no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Per seguretat, el telèfon no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"El telèfon i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi al telèfon o de la pèrdua de dades que pugui resultar del seu ús."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"La tauleta i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi a la tauleta o de la pèrdua de dades que pugui resultar del seu ús."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"El televisor i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi al televisor o de la pèrdua de dades que pugui resultar del seu ús."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continua"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Configuració"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instal·lant o desinstal·lant aplicacions de Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instal·lador de paquets"</string>
+    <string name="install" msgid="711829760615509273">"Instal·la"</string>
+    <string name="done" msgid="6632441120016885253">"Fet"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancel·la"</string>
+    <string name="installing" msgid="4921993079741206516">"S\'està instal·lant…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"S\'està instal·lant <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"S\'ha instal·lat l\'aplicació."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Vols instal·lar aquesta aplicació?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Vols instal·lar una actualització en aquesta aplicació? Les teves dades no es perdran."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Vols instal·lar una actualització en aquesta aplicació integrada? Les teves dades no es perdran."</string>
+    <string name="install_failed" msgid="5777824004474125469">"No s\'ha instal·lat l\'aplicació."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"El paquet s\'ha bloquejat perquè no es pugui instal·lar."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"L\'aplicació no s\'ha instal·lat perquè el paquet entra en conflicte amb un d\'existent."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"L\'aplicació no s\'ha instal·lat perquè no és compatible amb la tauleta."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Aquesta aplicació no és compatible amb el televisor."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"L\'aplicació no s\'ha instal·lat perquè no és compatible amb el telèfon."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"L\'aplicació no s\'ha instal·lat perquè sembla que el paquet no és vàlid."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"No s\'ha pogut instal·lar <xliff:g id="APP_NAME">%1$s</xliff:g> a la tauleta."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"No s\'ha pogut instal·lar <xliff:g id="APP_NAME">%1$s</xliff:g> al televisor."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"No s\'ha pogut instal·lar <xliff:g id="APP_NAME">%1$s</xliff:g> al telèfon."</string>
+    <string name="launch" msgid="3952550563999890101">"Obre"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"L\'administrador no permet instal·lar aplicacions de fonts desconegudes"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aquest usuari no pot instal·lar aplicacions desconegudes"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Aquest usuari no té permís per instal·lar aplicacions"</string>
+    <string name="ok" msgid="7871959885003339302">"D\'acord"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gestiona apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Espai esgotat"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"No s\'ha pogut instal·lar <xliff:g id="APP_NAME">%1$s</xliff:g>. Allibera espai i torna-ho a provar."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"No s\'ha trobat l\'aplicació"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"No s\'ha trobat l\'aplicació a la llista d\'aplicacions instal·lades."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Sense permís"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"L\'usuari actual no té permís per dur a terme aquesta desinstal·lació."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"No s\'ha pogut desinstal·lar l\'aplicació."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstal·la l\'aplicació"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Desinstal·la l\'actualització"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma part de l\'aplicació següent:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Vols desinstal·lar aquesta aplicació?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Vols desinstal·lar aquesta aplicació per a "<b>"tots"</b>" els usuaris? L\'aplicació i les seves dades se suprimiran per a "<b>"tots"</b>" els usuaris del dispositiu."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Vols desinstal·lar aquesta aplicació per a l\'usuari <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Vols substituir aquesta aplicació per la versió de fàbrica? Se suprimiran totes les dades."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vols substituir aquesta aplicació per la versió de fàbrica? Se suprimiran totes les dades. Això afectarà tots els usuaris d\'aquest dispositiu, inclosos els que tinguin un perfil professional."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstal·lacions en curs"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstal·lacions fallides"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"S\'està desinstal·lant…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"S\'està desinstal·lant <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"La desinstal·lació ha finalitzat."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"S\'ha desinstal·lat <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"No s\'ha pogut desinstal·lar."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"No s\'ha pogut desinstal·lar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"No es pot desinstal·lar l\'aplicació activa de l\'administrador del dispositiu"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"No es pot desinstal·lar l\'aplicació activa de l\'administrador del dispositiu per a <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Aquesta aplicació és necessària per a alguns usuaris o perfils i s\'ha desinstal·lat per a d\'altres"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Aquesta aplicació és necessària per al teu perfil i no es pot desinstal·lar."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"L\'administrador del dispositiu necessita l\'aplicació i no la pots desinstal·lar."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gestiona aplicacions d\'administració del dispositiu"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gestiona usuaris"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"No s\'ha pogut desinstal·lar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Hi ha hagut un problema en analitzar el paquet."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Les accions d\'instal·lar o de desinstal·lar no s\'admeten a Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"S\'està preparant la instal·lació de l\'aplicació…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Desconeguda"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Per seguretat, la tauleta no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Per seguretat, el televisor no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Per seguretat, el telèfon no pot instal·lar aplicacions desconegudes d\'aquesta font."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"El telèfon i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi al telèfon o de la pèrdua de dades que pugui resultar del seu ús."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"La tauleta i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi a la tauleta o de la pèrdua de dades que pugui resultar del seu ús."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"El televisor i les dades personals són més vulnerables als atacs d\'aplicacions desconegudes. En instal·lar aquesta aplicació, acceptes que ets responsable de qualsevol dany que es produeixi al televisor o de la pèrdua de dades que pugui resultar del seu ús."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continua"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Configuració"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instal·lant o desinstal·lant apps de Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-cs/strings.xml b/packages/PackageInstaller/res/values-cs/strings.xml
index a64c07a..6f68133 100644
--- a/packages/PackageInstaller/res/values-cs/strings.xml
+++ b/packages/PackageInstaller/res/values-cs/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"Nástroj k instalaci balíčků"</string>
-    <string name="next" msgid="3057143178373252333">"Další"</string>
-    <string name="install" msgid="5896438203900042068">"Instalovat"</string>
-    <string name="done" msgid="3889387558374211719">"Hotovo"</string>
-    <string name="cancel" msgid="8360346460165114585">"Zrušit"</string>
-    <string name="installing" msgid="8613631001631998372">"Probíhá instalace..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikace je nainstalována."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Chcete tuto aplikaci nainstalovat? Aplikace získá přístup k těmto oprávněním:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Chcete tuto aplikaci nainstalovat? Aplikace nevyžaduje žádná zvláštní oprávnění."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Chcete nainstalovat aktualizaci této existující aplikace? Stávající data nebudou ztracena. Aktualizovaná aplikace získá přístup k následujícímu:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Chcete nainstalovat aktualizaci této integrované aplikace? Stávající data nebudou ztracena. Aktualizovaná aplikace získá přístup k následujícímu:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Chcete nainstalovat aktualizaci této existující aplikace? Vaše existující data nebudou ztracena. Není vyžadován žádný zvláštní přístup."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Chcete nainstalovat aktualizaci této integrované aplikace? Vaše existující data nebudou ztracena. Není vyžadován žádný zvláštní přístup."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikaci nelze nainstalovat."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Instalace balíčku byla zablokována."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikaci nelze nainstalovat, protože balíček je v konfliktu se stávajícím balíčkem."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikaci nelze nainstalovat, protože s tabletem není kompatibilní."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Tato aplikace s vaší televizí není kompatibilní."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikaci nelze nainstalovat, protože s telefonem není kompatibilní."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikaci nelze nainstalovat, protože balíček zřejmě není platný."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> do tohoto tabletu nelze nainstalovat."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> se do televize nepodařilo nainstalovat."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> do tohoto telefonu nelze nainstalovat."</string>
-    <string name="launch" msgid="4826921505917605463">"Otevřít"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Váš administrátor nedovoluje instalaci aplikací z neznámých zdrojů"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Tento uživatel nemůže instalovat neznámé aplikace"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Tento uživatel nesmí instalovat aplikace"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Spravovat aplikace"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nedostatek místa"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> nelze nainstalovat. Uvolněte místo v paměti a zkuste to znovu."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikace nebyla nalezena"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikaci se nepodařilo najít na seznamu nainstalovaných aplikací."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Není povoleno"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Aktuální uživatel nemá k odinstalaci oprávnění."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Chyba"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikaci nelze odinstalovat."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Odinstalovat aplikaci"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Odinstalovat aktualizaci"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"Činnost <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je součástí následující aplikace:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Chcete tuto aplikaci odinstalovat?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Chcete  tuto aplikaci odinstalovat "<b>"všem"</b>" uživatelům? Aplikace a její údaje budou odstraněny "<b>"všem"</b>" uživatelům tohoto zařízení."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Chcete tuto aplikaci pro uživatele <xliff:g id="USERNAME">%1$s</xliff:g> odinstalovat?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Chcete tuto aplikaci nahradit tovární verzí? Všechna data budou odstraněna."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Chcete tuto aplikaci nahradit tovární verzí? Všechna data budou odstraněna. Tato akce ovlivní všechny uživatele zařízení, včetně uživatelů s pracovním profilem."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Probíhající odinstalace"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neúspěšné odinstalace"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Probíhá odinstalace..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Odinstalace byla dokončena."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Balíček <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> byl odinstalován"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Odinstalace se nezdařila."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se nezdařila."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktivní aplikaci pro správu zařízení nelze odinstalovat"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Aktivní aplikaci pro správu zařízení uživatele <xliff:g id="USERNAME">%1$s</xliff:g> nelze odinstalovat"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Tato aplikace je u některých uživatelů nebo profilů požadována, u ostatních byla odinstalována."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Tato aplikace je pro váš profil požadována a nelze ji odinstalovat."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Tato aplikace je administrátorem zařízení vyžadována a nelze ji odinstalovat."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Přejít do nastavení aplikací pro správu zařízení"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Správa uživatelů"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> nelze odinstalovat."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Při analýze balíčku došlo k chybě."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nově"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Vše"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Ochrana soukromí"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Přístup k zařízení"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Tato aktualizace nevyžaduje žádná nová oprávnění."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odmítnout"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Další informace"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Zamítnout"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> z <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vždy povolit aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Pouze při používání aplikace"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Vždy"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odmítnout a už se neptat"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"zakázáno (<xliff:g id="COUNT">%1$d</xliff:g>)"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"vše zakázáno"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"nic nezakázáno"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Povolit"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikace"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Oprávnění aplikací"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Příště se neptat"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Žádná oprávnění"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Další oprávnění"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otevřít informace o aplikaci"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="few">Ještě <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="many">Ještě <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Ještě <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Ještě <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Tato aplikace byla vytvořena pro starší verzi platformy Android. Pokud oprávnění neudělíte, může přestat fungovat podle původního záměru."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"provést neznámou akci"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Povoleno u <xliff:g id="COUNT_0">%1$d</xliff:g> z <xliff:g id="COUNT_1">%2$d</xliff:g> aplikací"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Zobrazit systémové aplikace"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Skrýt systémové aplikace"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Žádné aplikace"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Nastavení polohy"</string>
-    <string name="location_warning" msgid="8778701356292735971">"Služby určování polohy v tomto zařízení poskytuje aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>. Přístup k poloze lze upravit v nastavení polohy."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Pokud toto oprávnění zamítnete, základní funkce zařízení nemusejí fungovat správně."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Vynuceno zásadami"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Přístup na pozadí byl zakázán zásadami"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Přístup na pozadí byl povolen zásadami"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Přístup na popředí byl povolen zásadami"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Spravováno administrátorem"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Vždy"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Pouze při používání aplikace"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nikdy"</string>
-    <string name="loading" msgid="7811651799620593731">"Načítání…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Všechna oprávnění"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Ostatní oprávnění aplikace"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Žádost o oprávnění"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Byla zjištěna překryvná vrstva obrazovky"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Chcete-li změnit nastavení tohoto oprávnění, v Nastavení &gt; Aplikace je třeba nejprve vypnout překryvnou vrstvu obrazovky"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Otevřít nastavení"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Akce instalace/odinstalace nejsou v zařízení Wear podporovány."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Určete, k čemu aplikaci &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; povolíte přístup"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikace &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; byla aktualizována. Určete, k čemu jí povolíte přístup."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Zrušit"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Pokračovat"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nová oprávnění"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Aktuální oprávnění"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Příprava instalace…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Neznámá aplikace"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Z bezpečnostních důvodů do tabletu není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Z bezpečnostních důvodů do televize není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Z bezpečnostních důvodů do telefonu není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefon a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na telefonu nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tablet a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na tabletu nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Televize a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na televizi nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Pokračovat"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Nastavení"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalace/odinstalace aplikací pro Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instalátor balíčků"</string>
+    <string name="install" msgid="711829760615509273">"Instalovat"</string>
+    <string name="done" msgid="6632441120016885253">"Hotovo"</string>
+    <string name="cancel" msgid="1018267193425558088">"Zrušit"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalace…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikace je nainstalována."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Chcete tuto aplikaci nainstalovat?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Chcete nainstalovat aktualizaci této existující aplikace? Stávající data nebudou ztracena."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Chcete nainstalovat aktualizaci této integrované aplikace? Stávající data nebudou ztracena."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikaci nelze nainstalovat."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Instalace balíčku byla zablokována."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikaci nelze nainstalovat, protože balíček je v konfliktu se stávajícím balíčkem."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikaci nelze nainstalovat, protože s tabletem není kompatibilní."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Tato aplikace s vaší televizí není kompatibilní."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikaci nelze nainstalovat, protože s telefonem není kompatibilní."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikaci nelze nainstalovat, protože balíček zřejmě není platný."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> se do tabletu nepodařilo nainstalovat."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> se do televize nepodařilo nainstalovat."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> se do telefonu nepodařilo nainstalovat."</string>
+    <string name="launch" msgid="3952550563999890101">"Otevřít"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Váš administrátor nedovoluje instalaci aplikací z neznámých zdrojů"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Tento uživatel nemůže instalovat neznámé aplikace"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Tento uživatel nesmí instalovat aplikace"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Správa aplikací"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nedostatek místa"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> nelze nainstalovat. Uvolněte místo v paměti a zkuste to znovu."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikace nebyla nalezena"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikaci se nepodařilo najít na seznamu nainstalovaných aplikací."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nepovoleno"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Aktuální uživatel nemá k odinstalaci oprávnění."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Chyba"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Aplikaci nelze odinstalovat."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Odinstalovat aplikaci"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Odinstalovat aktualizaci"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"Činnost <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je součástí následující aplikace:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Chcete tuto aplikaci odinstalovat?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Chcete tuto aplikaci odinstalovat "<b>"všem"</b>" uživatelům? Aplikace a její údaje budou odstraněny "<b>"všem"</b>" uživatelům tohoto zařízení."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Chcete tuto aplikaci pro uživatele <xliff:g id="USERNAME">%1$s</xliff:g> odinstalovat?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Chcete tuto aplikaci nahradit tovární verzí? Všechna data budou odstraněna."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Chcete tuto aplikaci nahradit tovární verzí? Všechna data budou odstraněna. Tato akce ovlivní všechny uživatele zařízení, včetně uživatelů s pracovním profilem."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Probíhající odinstalace"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neúspěšné odinstalace"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Odinstalace…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Odinstalace byla dokončena."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Balíček <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> byl odinstalován"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Odinstalace se nezdařila."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Odinstalace balíčku <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> se nezdařila."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktivní aplikaci pro správu zařízení nelze odinstalovat"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Aktivní aplikaci pro správu zařízení uživatele <xliff:g id="USERNAME">%1$s</xliff:g> nelze odinstalovat"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Tato aplikace je u některých uživatelů nebo profilů požadována, u ostatních byla odinstalována"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Tato aplikace je pro váš profil požadována a nelze ji odinstalovat."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Tato aplikace je administrátorem zařízení vyžadována a nelze ji odinstalovat.required by your device administrator and can\'t be uninstalled."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Přejít do nastavení aplikací pro správu zařízení"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Správa uživatelů"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Aplikaci <xliff:g id="APP_NAME">%1$s</xliff:g> nelze odinstalovat."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Při analýze balíčku došlo k chybě."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Akce instalace/odinstalace nejsou v zařízení Wear podporovány."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Příprava instalace…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Neznámé"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Z bezpečnostních důvodů do tabletu není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Z bezpečnostních důvodů do televize není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Z bezpečnostních důvodů do telefonu není dovoleno instalovat neznámé aplikace z tohoto zdroje."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefon a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na telefonu nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tablet a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na tabletu nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Televize a osobní údaje jsou zranitelnější vůči útoku ze strany neznámých aplikací. Instalací této aplikace přijímáte odpovědnost za případné škody na televizi nebo ztrátu dat, která může být používáním aplikace způsobena."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Pokračovat"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Nastavení"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalace/odinstalace aplikací pro Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-da/strings.xml b/packages/PackageInstaller/res/values-da/strings.xml
index 73d03a5..4b40341 100644
--- a/packages/PackageInstaller/res/values-da/strings.xml
+++ b/packages/PackageInstaller/res/values-da/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Pakkeinstallationsprogram"</string>
-    <string name="next" msgid="3057143178373252333">"Næste"</string>
-    <string name="install" msgid="5896438203900042068">"Installer"</string>
-    <string name="done" msgid="3889387558374211719">"Afslut"</string>
-    <string name="cancel" msgid="8360346460165114585">"Annuller"</string>
-    <string name="installing" msgid="8613631001631998372">"Installerer..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Appen er installeret."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Vil du installere denne applikation? Den får adgang til følgende:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vil du installere denne applikation? Den kræver ingen særlig adgang."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Vil du installere en opdatering til den eksisterende app? Du mister ikke dine eksisterende data. Den opdaterede app kan gøre følgende:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vil du installere en opdatering til den indbyggede app? Du mister ikke dine eksisterende data. Den opdaterede app kan gøre følgende:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vil du installere en opdatering til denne eksisterende applikation? Dine eksisterende data vil ikke gå tabt. Det kræver ikke nogen særlig adgang."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vil du installere en opdatering til denne indbyggede applikation? Dine eksisterende data vil ikke gå tabt. Det kræver ikke nogen særlig adgang."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Appen blev ikke installeret."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Pakken blev blokeret i at blive installeret."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Appen blev ikke installeret, da pakken er i strid med en eksisterende pakke."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Appen blev ikke installeret, da den er ikke kompatibel med din tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Denne app er ikke kompatibel med dit fjernsyn."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Appen blev ikke installeret, da den ikke er kompatibel med din telefon."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Appen blev ikke installeret, da pakken ser ud til at være ugyldig."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på din tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på dit tv."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på din telefon."</string>
-    <string name="launch" msgid="4826921505917605463">"Åbn"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Din administrator tillader ikke installation af apps, der hentes fra ukendte kilder"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Denne bruger kan ikke installere ukendte apps"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Denne bruger har ikke tilladelse til at installere apps"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Administrer apps"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Der er ikke mere plads"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres. Frigør noget plads, og prøv igen."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Appen blev ikke fundet"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Appen blev ikke fundet på listen over installerede apps."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ikke tilladt"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Den nuværende bruger har ikke tilladelse til at udføre denne afinstallation."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fejl"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Appen kunne ikke afinstalleres."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Afinstaller appen"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Afinstaller opdatering"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er en del af følgende app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Vil du afinstallere denne app?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vil du afinstallere denne app for "<b>"alle"</b>" brugere? Applikationen og dens data vil blive fjernet fra "<b>"alle"</b>" brugere på denne enhed."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Vil du afinstallere denne app for brugeren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Vil du erstatte denne app med fabriksversionen? Alle data fjernes."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vil du erstatte denne app med fabriksversionen? Alle data fjernes. Dette påvirker alle brugere af denne enhed, herunder de brugere, der har arbejdsprofiler."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Igangværende afinstallationer"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mislykkede afinstallationer"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Afinstallerer..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Afinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Afinstallationen er afsluttet."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> blev afinstalleret"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Afinstallationen mislykkedes."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kunne ikke afinstalleres."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Den aktive app til enhedsadministration kan ikke afinstalleres"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Den aktive app til enhedsadministration for <xliff:g id="USERNAME">%1$s</xliff:g> kan ikke afinstalleres"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Denne app kræves for nogle brugere eller profiler og afinstalleres for andre"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Denne app er nødvendig for din profil og kan ikke afinstalleres."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Denne app er påkrævet af din enhedsadministrator og kan ikke afinstalleres."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Administrer apps til enhedsadministration"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Administrer brugere"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke afinstalleres."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Der opstod et problem med parsing af pakken."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Ny"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privatliv"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Adgang til enheden"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Denne opdatering kræver ingen nye tilladelser."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Afvis"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Få flere oplysninger"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Afvis alligevel"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ud af <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Vil du give &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tilladelse til at <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Skal &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; altid have tilladelse til at <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Kun mens appen bruges"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Altid"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Afvis, og spørg ikke igen"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> er deaktiveret"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"alle er deaktiveret"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ingen er deaktiveret"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Tillad"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Apptilladelser"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Spørg ikke igen"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Ingen tilladelser"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Flere tilladelser"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Åbn appinfo"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> mere</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> mere</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Denne app er udviklet til en ældre version af Android. Hvis du ikke giver den tilladelse, vil den muligvis ikke længere virke efter hensigten."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"udføre en ukendt handling"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> ud af <xliff:g id="COUNT_1">%2$d</xliff:g> apps har tilladelse"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Vis systemapps"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Skjul systemapps"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Ingen apps"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Placeringsindstillinger"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> udbyder placeringstjenester for denne enhed. Adgangen til din placering kan ændres i Placeringsindstillinger."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Hvis du afviser denne tilladelse, vil grundlæggende funktioner på din enhed muligvis ikke længere fungere efter hensigten."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Håndhæves af politik"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Adgang i baggrunden er deaktiveret af en politik"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Adgang i baggrunden er aktiveret af en politik"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Adgang i forgrunden er aktiveret af en politik"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Styres af administratoren"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Altid"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Kun mens appen bruges"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Aldrig"</string>
-    <string name="loading" msgid="7811651799620593731">"Indlæser…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Alle tilladelser"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Andre app-egenskaber"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Anmodning om tilladelse"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Der er registreret skærmoverlejring"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Hvis du vil ændre denne indstilling for tilladelser, skal du først slå skærmoverlejringen fra i Indstillinger &gt; Apps"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Åbn indstillingerne"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Det er ikke muligt at installere/afinstallere på Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Vælg, hvad &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; må få adgang til"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; er blevet opdateret. Vælg, hvad denne app må få adgang til."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Annuller"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Fortsæt"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nye tilladelser"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Aktuelle tilladelser"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Forbereder appen…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Ukendt"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Din tablet har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Dit fjernsyn har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Din telefon har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Din telefon og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på din telefon eller tab af data, der kan skyldes brug af appen."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Din tablet og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på din tablet eller tab af data, der kan skyldes brug af appen."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Dit fjernsyn og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på dit fjernsyn eller tab af data, der kan skyldes brug af appen."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Fortsæt"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Indstillinger"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installerer/afinstallerer Wear-apps"</string>
+    <string name="app_name" msgid="7488448184431507488">"Pakkeinstallationsprogram"</string>
+    <string name="install" msgid="711829760615509273">"Installer"</string>
+    <string name="done" msgid="6632441120016885253">"Udfør"</string>
+    <string name="cancel" msgid="1018267193425558088">"Annuller"</string>
+    <string name="installing" msgid="4921993079741206516">"Installerer…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Appen er installeret."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Vil du installere denne app?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Vil du installere en opdatering til denne eksisterende app? Du mister ikke dine eksisterende data."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Vil du installere en opdatering til denne indbyggede app? Du mister ikke dine eksisterende data."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Appen blev ikke installeret."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Pakken blev forhindret i at blive installeret."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Appen blev ikke installeret, da pakken er i strid med en eksisterende pakke."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Appen blev ikke installeret, da den ikke er kompatibel med din tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Denne app er ikke kompatibel med dit fjernsyn."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Appen blev ikke installeret, da den ikke er kompatibel med din telefon."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Appen blev ikke installeret, da pakken lader til at være ugyldig."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på din tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på dit fjernsyn."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på din telefon."</string>
+    <string name="launch" msgid="3952550563999890101">"Åbn"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Din administrator tillader ikke installation af apps, der hentes fra ukendte kilder"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Denne bruger kan ikke installere ukendte apps"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Denne bruger har ikke tilladelse til at installere apps"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Administrer apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Der er ikke mere plads"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres. Frigør noget plads, og prøv igen."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Appen blev ikke fundet"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Appen blev ikke fundet på listen over installerede apps."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Ikke tilladt"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Den nuværende bruger har ikke tilladelse til at udføre denne afinstallation."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Fejl"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Appen kunne ikke afinstalleres."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Afinstaller app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Afinstaller opdatering"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er en del af følgende app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Vil du afinstallere denne app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Vil du afinstallere denne app for "<b>"alle"</b>" brugere? Appen og dens data fjernes fra "<b>"alle"</b>" brugere på denne enhed."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Vil du afinstallere denne app for brugeren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Vil du erstatte denne app med fabriksversionen? Alle data fjernes."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vil du erstatte denne app med fabriksversionen? Alle data fjernes. Dette påvirker alle brugere af denne enhed, bl.a. brugere med arbejdsprofiler."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Igangværende afinstallationer"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mislykkede afinstallationer"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Afinstallerer…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Afinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Afinstallationen er gennemført."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> blev afinstalleret"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Appen blev ikke afinstalleret."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kunne ikke afinstalleres."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Den aktive app til enhedsadministration kan ikke afinstalleres"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Den aktive app til enhedsadministration for <xliff:g id="USERNAME">%1$s</xliff:g> kan ikke afinstalleres"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Denne app kræves for nogle brugere eller profiler og blev afinstalleret for andre"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Denne app er nødvendig for din profil og kan ikke afinstalleres."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Denne app er påkrævet af din enhedsadministrator og kan ikke afinstalleres."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Administrer apps til enhedsadministration"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Administrer brugere"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke afinstalleres."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Der opstod et problem med parsing af pakken."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Det er ikke muligt at installere/afinstallere på Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Forbereder appen…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Ukendt"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Din tablet har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Dit fjernsyn har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Din telefon har af sikkerhedshensyn ikke tilladelse til at installere ukendte apps fra denne kilde."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Din telefon og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på din telefon eller tab af data, der kan skyldes brug af appen."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Din tablet og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på din tablet eller tab af data, der kan skyldes brug af appen."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Dit fjernsyn og dine personlige data er mere sårbare over for angreb fra ukendte apps. Når du installerer denne app, accepterer du, at du er ansvarlig for skader på dit fjernsyn eller tab af data, der kan skyldes brug af appen."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Fortsæt"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Indstillinger"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installerer/afinstallerer Wear-apps"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
index 5a05c0c..27c19b8 100644
--- a/packages/PackageInstaller/res/values-de/strings.xml
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Paket-Installer"</string>
-    <string name="next" msgid="3057143178373252333">"Weiter"</string>
-    <string name="install" msgid="5896438203900042068">"Installieren"</string>
-    <string name="done" msgid="3889387558374211719">"Fertig"</string>
-    <string name="cancel" msgid="8360346460165114585">"Abbrechen"</string>
-    <string name="installing" msgid="8613631001631998372">"Wird installiert..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird installiert…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App wurde installiert."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Möchtest du diese App installieren? Sie erhält dann folgende Berechtigungen:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Möchtest du diese App installieren? Sie benötigt keinen besonderen Zugriff."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Möchtest du ein Update für diese vorhandene App installieren? Deine vorhandenen Daten bleiben erhalten. Die aktualisierte App erhält Zugriff auf:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Möchtest du ein Update für diese integrierte App installieren? Deine vorhandenen Daten bleiben erhalten. Die aktualisierte App erhält Zugriff auf:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Möchtest du ein Update für diese bestehende App installieren? Deine vorhandenen Daten bleiben erhalten. Die App benötigt keine besonderen Zugriffsrechte."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Möchtest du ein Update für diese integrierte App installieren? Deine vorhandenen Daten bleiben erhalten. Die App benötigt keine besonderen Zugriffsrechte."</string>
-    <string name="install_failed" msgid="6579998651498970899">"App wurde nicht installiert."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Die Installation des Pakets wurde blockiert."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Die App wurde nicht installiert, da das Paket in Konflikt mit einem bestehenden Paket steht."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Die App wurde nicht installiert, da sie nicht mit deinem Tablet kompatibel ist."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Diese App ist nicht mit deinem Fernseher kompatibel."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Die App wurde nicht installiert, da sie nicht mit deinem Smartphone kompatibel ist."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Die App wurde nicht installiert, da das Paket offenbar ungültig ist."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Tablet installiert werden."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Fernseher installiert werden."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Telefon installiert werden."</string>
-    <string name="launch" msgid="4826921505917605463">"Öffnen"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Dein Administrator lässt keine Installationen von Apps aus unbekannten Quellen zu"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Dieser Nutzer darf keine unbekannten Apps installieren"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Dieser Nutzer darf keine Apps installieren"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Apps verwalten"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Kein freier Speicher vorhanden"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht installiert werden. Gib Speicherplatz frei und versuche es erneut."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App nicht gefunden"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Die App wurde nicht in der Liste der installierten Apps gefunden."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Keine Berechtigung"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Der aktuelle Nutzer ist nicht dazu berechtigt, diese Deinstallation auszuführen."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fehler"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"App konnte nicht deinstalliert werden."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"App deinstallieren"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Update deinstallieren"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> gehört zu folgender App:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Möchtest du diese App deinstallieren?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Möchtest du diese App für "<b>"alle"</b>" Nutzer entfernen? Die App und alle zugehörigen Daten werden für "<b>"alle"</b>" Nutzer des Geräts entfernt."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Möchtest du diese App für den Nutzer <xliff:g id="USERNAME">%1$s</xliff:g> deinstallieren?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Diese App durch die Werksversion ersetzen? Alle Daten werden entfernt."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Diese App durch die Werksversion ersetzen? Alle Daten werden entfernt. Dies betrifft alle Nutzer des Geräts, einschließlich Arbeitsprofilen."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Laufende Deinstallationen"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Fehlgeschlagene Deinstallationen"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Wird deinstalliert..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird deinstalliert…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Deinstallation abgeschlossen"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalliert"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Deinstallation fehlgeschlagen"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Deinstallation von <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> fehlgeschlagen."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktive Apps zur Geräteverwaltung können nicht deinstalliert werden"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Die aktive App zur Geräteverwaltung kann nicht für <xliff:g id="USERNAME">%1$s</xliff:g> deinstalliert werden"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Diese App wird für einige Nutzer oder Profile benötigt und wurde für andere deinstalliert"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Diese App wird für dein Profil benötigt und kann nicht deinstalliert werden."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Die App wurde als obligatorisch festgelegt und kann nicht deinstalliert werden."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Apps zur Geräteverwaltung"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Nutzer verwalten"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht deinstalliert werden."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Beim Parsen des Pakets ist ein Problem aufgetreten."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Neu"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Datenschutz"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Gerätezugriff"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Für dieses Update sind keine neuen Berechtigungen erforderlich."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Ablehnen"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Weitere Informationen"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Trotzdem ablehnen"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> von <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Zulassen, dass die App &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g> darf?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; immer erlauben zu <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Nur während der App-Nutzung"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Immer"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Ablehnen und nicht mehr fragen"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> deaktiviert"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"Alle deaktiviert"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"Keine deaktiviert"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Zulassen"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"App-Berechtigungen"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Nicht mehr fragen"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Keine Berechtigungen"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Zusätzliche Berechtigungen"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"App-Info öffnen"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Noch <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Noch <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Diese App wurde für eine ältere Version von Android konzipiert. Wenn du keine Berechtigung erteilst, funktioniert die App möglicherweise nicht mehr ordnungsgemäß."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"Unbekannte Aktion durchführen"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> von <xliff:g id="COUNT_1">%2$d</xliff:g> Apps sind berechtigt."</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"System-Apps anzeigen"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"System ausblenden"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Keine Apps"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Standorteinstellungen"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ist ein Anbieter von Standortdiensten für dieses Gerät. Die Berechtigungen für den Zugriff auf deinen Standort kannst du in den Standorteinstellungen ändern."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Wenn du diese Berechtigung deaktivierst, funktionieren grundlegende Funktionen deines Geräts möglicherweise nicht mehr ordnungsgemäß."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Von Richtlinien durchgesetzt"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Hintergrundzugriff aufgrund der Richtlinie deaktiviert"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Hintergrundzugriff aufgrund der Richtlinie aktiviert"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Vordergrundzugriff aufgrund der Richtlinie aktiviert"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Durch den Administrator verwaltet"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Immer"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Nur während der App-Nutzung"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nie"</string>
-    <string name="loading" msgid="7811651799620593731">"Wird geladen…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Alle Berechtigungen"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Andere App-Funktionen"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Berechtigungsanfrage"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Display-Overlay erkannt"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Um diese Berechtigungseinstellung zu ändern, musst du zunächst das Display-Overlay über \"Einstellungen\" &gt; \"Apps\" deaktivieren."</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Einstellungen öffnen"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Von Android Wear nicht unterstützte Aktionen installieren/deinstallieren."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Worauf darf die App &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; zugreifen?"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Die App &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; wurde aktualisiert. Worauf darf diese App zugreifen?"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Abbrechen"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Weiter"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Neue Berechtigungen"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Aktuelle Berechtigungen"</string>
-    <string name="message_staging" msgid="6151794817691100003">"App wird vorbereitet…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Unbekannt"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Aus Sicherheitsgründen kannst du auf dem Tablet keine unbekannten Apps aus dieser Quelle installieren."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Aus Sicherheitsgründen kannst du auf dem Fernseher keine unbekannten Apps aus dieser Quelle installieren."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Aus Sicherheitsgründen kannst du auf dem Smartphone keine unbekannten Apps aus dieser Quelle installieren."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Unbekannte Apps können gefährlich für dein Smartphone und deine personenbezogenen Daten sein. Indem du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Smartphone und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Unbekannte Apps können gefährlich für dein Tablet und deine personenbezogenen Daten sein. Indem du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Tablet und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Unbekannte Apps können gefährlich für deinen Fernseher und deine personenbezogenen Daten sein. Indem du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Fernseher und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Weiter"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Einstellungen"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear-Apps installieren/deinstallieren"</string>
+    <string name="app_name" msgid="7488448184431507488">"Paketinstallation"</string>
+    <string name="install" msgid="711829760615509273">"Installieren"</string>
+    <string name="done" msgid="6632441120016885253">"Fertig"</string>
+    <string name="cancel" msgid="1018267193425558088">"Abbrechen"</string>
+    <string name="installing" msgid="4921993079741206516">"Wird installiert…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird installiert…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App wurde installiert."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Möchtest du diese App installieren?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Möchtest du ein Update dieser vorhandenen App installieren? Deine bisherigen Daten gehen dabei nicht verloren."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Möchtest du ein Update dieser integrierten App installieren? Deine bisherigen Daten gehen dabei nicht verloren."</string>
+    <string name="install_failed" msgid="5777824004474125469">"App wurde nicht installiert."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Die Installation des Pakets wurde blockiert."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Die App wurde nicht installiert, da das Paket in Konflikt mit einem bestehenden Paket steht."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Die App wurde nicht installiert, da sie nicht mit deinem Tablet kompatibel ist."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Diese App ist nicht mit deinem Fernseher kompatibel."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Die App wurde nicht installiert, da sie nicht mit deinem Smartphone kompatibel ist."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Die App wurde nicht installiert, da das Paket offenbar ungültig ist."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Tablet installiert werden."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Fernseher installiert werden."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht auf deinem Smartphone installiert werden."</string>
+    <string name="launch" msgid="3952550563999890101">"Öffnen"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Dein Administrator lässt keine Installationen von Apps aus unbekannten Quellen zu"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Dieser Nutzer darf keine unbekannten Apps installieren"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Dieser Nutzer darf keine Apps installieren"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Apps verwalten"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Kein freier Speicher vorhanden"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht installiert werden. Gib Speicherplatz frei und versuche es noch einmal."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App nicht gefunden"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Die App wurde nicht in der Liste der installierten Apps gefunden."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nicht zulässig"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Der aktuelle Nutzer ist nicht dazu berechtigt, diese Deinstallation auszuführen."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Fehler"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"App konnte nicht deinstalliert werden."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"App deinstallieren"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Update deinstallieren"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> gehört zu folgender App:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Möchtest du diese App deinstallieren?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Möchtest du diese App für "<b>"alle"</b>" Nutzer entfernen? Die App und alle zugehörigen Daten werden für "<b>"alle"</b>" Nutzer des Geräts entfernt."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Möchtest du diese App für den Nutzer <xliff:g id="USERNAME">%1$s</xliff:g> deinstallieren?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Diese App durch die Werksversion ersetzen? Alle Daten werden entfernt."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Diese App durch die Werksversion ersetzen? Alle Daten werden entfernt. Dies betrifft alle Nutzer des Geräts, einschließlich Arbeitsprofilen."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Laufende Deinstallationen"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Fehlgeschlagene Deinstallationen"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Wird deinstalliert..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird deinstalliert…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Deinstallation abgeschlossen."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalliert"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Deinstallation fehlgeschlagen."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstallation von <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> fehlgeschlagen."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktive Apps zur Geräteverwaltung können nicht deinstalliert werden"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Die aktive App zur Geräteverwaltung kann nicht für <xliff:g id="USERNAME">%1$s</xliff:g> deinstalliert werden"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Diese App wird für einige Nutzer oder Profile benötigt und wurde für andere deinstalliert"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Diese App wird für dein Profil benötigt und kann nicht deinstalliert werden."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Die App wird unbedingt benötigt und kann nicht deinstalliert werden."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Apps zur Geräteverwaltung verwalten"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Nutzer verwalten"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> konnte nicht deinstalliert werden."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Beim Parsen des Pakets ist ein Problem aufgetreten."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Installations-/Deinstallationsaktion auf Android Wear nicht unterstützt."</string>
+    <string name="message_staging" msgid="8032722385658438567">"App wird vorbereitet…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Unbekannt"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Aus Sicherheitsgründen kannst du auf dem Tablet keine unbekannten Apps aus dieser Quelle installieren."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Aus Sicherheitsgründen kannst du auf dem Fernseher keine unbekannten Apps aus dieser Quelle installieren."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Aus Sicherheitsgründen kannst du auf dem Smartphone keine unbekannten Apps aus dieser Quelle installieren."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Unbekannte Apps können gefährlich für dein Smartphone und deine personenbezogenen Daten sein. Wenn du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Smartphone und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Unbekannte Apps können gefährlich für dein Tablet und deine personenbezogenen Daten sein. Wenn du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Tablet und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Unbekannte Apps können gefährlich für deinen Fernseher und deine personenbezogenen Daten sein. Wenn du diese App installierst, erklärst du dich damit einverstanden, dass du die Verantwortung für alle Schäden an deinem Fernseher und jegliche Datenverluste trägst, die aus der Verwendung dieser App entstehen können."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Weiter"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Einstellungen"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear-Apps installieren/deinstallieren"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-el/strings.xml b/packages/PackageInstaller/res/values-el/strings.xml
index 707f7b1..fea3556 100644
--- a/packages/PackageInstaller/res/values-el/strings.xml
+++ b/packages/PackageInstaller/res/values-el/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Πρόγραμμα εγκατάστασης πακέτου"</string>
-    <string name="next" msgid="3057143178373252333">"Επόμενο"</string>
-    <string name="install" msgid="5896438203900042068">"Εγκατάσταση"</string>
-    <string name="done" msgid="3889387558374211719">"Τέλος"</string>
-    <string name="cancel" msgid="8360346460165114585">"Ακύρωση"</string>
-    <string name="installing" msgid="8613631001631998372">"Εγκατάσταση..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Εγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Εγκατάσταση εφαρμογής."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Θέλετε να εγκαταστήσετε αυτήν την εφαρμογή; Θα έχει πρόσβαση σε:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Θέλετε να εγκαταστήσετε αυτήν την εφαρμογή; Δεν απαιτείται οποιαδήποτε ειδική πρόσβαση."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Θέλετε να εγκαταστήσετε μια ενημέρωση σε αυτήν την υπάρχουσα εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν. Η ενημερωμένη εφαρμογή θα έχει πρόσβαση σε:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Θέλετε να εγκαταστήσετε μια ενημέρωση σε αυτήν την ενσωματωμένη εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν. Η ενημερωμένη εφαρμογή θα έχει πρόσβαση σε:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Θέλετε να εγκαταστήσετε μια ενημέρωση για αυτήν την υπάρχουσα εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν. Δεν απαιτείται ειδική πρόσβαση."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Θέλετε να εγκαταστήσετε μια ενημέρωση για αυτήν την ενσωματωμένη εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν. Δεν απαιτείται ειδική πρόσβαση."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Η εφαρμογή δεν έχει εγκατασταθεί."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Η εγκατάσταση του πακέτου αποκλείστηκε."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Η εφαρμογή δεν έχει εγκατασταθεί, επειδή το πακέτο έρχεται σε διένεξη με κάποιο υπάρχον πακέτο."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Η εφαρμογή δεν έχει εγκατασταθεί, επειδή δεν είναι συμβατή με το tablet που χρησιμοποιείτε."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Αυτή η εφαρμογή δεν είναι συμβατή με την τηλεόρασή σας."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Η εφαρμογή δεν έχει εγκατασταθεί, επειδή δεν είναι συμβατή με το τηλέφωνό σας."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Η εφαρμογή δεν έχει εγκατασταθεί, επειδή φαίνεται ότι το πακέτο δεν είναι έγκυρο."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g> στο tablet σας."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> δεν ήταν δυνατό να εγκατασταθεί στην τηλεόρασή σας."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g> στο τηλέφωνό σας."</string>
-    <string name="launch" msgid="4826921505917605463">"Άνοιγμα"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ο διαχειριστής σας δεν επιτρέπει την εγκατάσταση εφαρμογών που προέρχονται από άγνωστες πηγές"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Δεν είναι δυνατή η εγκατάσταση άγνωστων εφαρμογών από αυτόν τον χρήστη"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Αυτός ο χρήστης δεν έχει δυνατότητα εγκατάστασης εφαρμογών."</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Διαχείριση εφαρμογών"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Δεν υπάρχει χώρος"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g>. Απελευθερώστε λίγο χώρο και προσπαθήστε ξανά."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Δεν βρέθηκε εφαρμογή"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Η εφαρμογή δεν βρέθηκε στη λίστα με τις εγκατεστημένες εφαρμογές."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Δεν επιτρέπεται"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Δεν επιτρέπεται στον τρέχοντα χρήση να εκτελέσει την απεγκατάσταση."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Σφάλμα"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Δεν ήταν δυνατή η απεγκατάσταση της εφαρμογής."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Απεγκατάσταση εφαρμογής"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Απεγκατάσταση ενημέρωσης"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"Η δραστηριότητα <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> αποτελεί τμήμα της ακόλουθης εφαρμογής:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Θέλετε να καταργήσετε την εγκατάσταση αυτής της εφαρμογής;"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Θέλετε να καταργήσετε την εγκατάσταση αυτής της εφαρμογής για "<b>"όλους"</b>" τους χρήστες; Η εφαρμογή και τα δεδομένα της θα καταργηθούν από "<b>"όλους"</b>" τους χρήστες στη συσκευή."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Θέλετε να καταργήσετε την εγκατάσταση αυτής της εφαρμογής για το χρήστη <xliff:g id="USERNAME">%1$s</xliff:g>;"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Αντικατάσταση αυτής της εφαρμογής με την εργοστασιακή έκδοση; Όλα τα δεδομένα θα καταργηθούν."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Αντικατάσταση αυτής της εφαρμογής με την εργοστασιακή έκδοση; Όλα τα δεδομένα θα καταργηθούν. Αυτό επηρεάζει όλους τους χρήστες της συσκευής, συμπεριλαμβανομένων και αυτών με προφίλ εργασίας."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Απεγκαταστάσεις σε εξέλιξη"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Αποτυχημένες απεγκαταστάσεις"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Απεγκατάσταση..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Η κατάργηση εγκατάστασης ολοκληρώθηκε."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Απεγκαταστάθηκε <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Μη επιτυχής κατάργηση εγκατάστασης."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Επιτυχής απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Η κατάργ. εγκατάστ. της ενεργούς εφαρμογής διαχείρισης συσκευής δεν είναι δυνατή"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Η κατάργ. εγκατάστασης της ενεργούς εφαρμογής διαχείρισης συσκευής για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> δεν είναι δυνατή"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Η εφαρμογή απαιτείται για κάποιους χρήστες/προφίλ και απεγκαταστήθηκε για άλλους"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Αυτή η εφαρμογή απαιτείται για το προφίλ σας και δεν είναι δυνατή η απεγκατάστασή της."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Η εφαρμογή απαιτείται από το διαχειριστή και δεν είναι δυνατή η απεγκατάσταση."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Διαχείριση εφαρμογών διαχείρισης συσκευής"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Διαχείριση χρηστών"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Δεν ήταν δυνατή η κατάργηση της εγκατάστασης της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Παρουσιάστηκε ένα πρόβλημα κατά την ανάλυση του πακέτου."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Νέο"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Όλα"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Απόρρητο"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Πρόσβαση συσκευής"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Αυτή η ενημέρωση δεν απαιτεί νέες άδειες."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Απόρριψη"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Περισσότερες πληροφορίες"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Απόρριψη"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> από <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Να επιτρέπεται στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να <xliff:g id="ACTION">%2$s</xliff:g>;"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Να επιτρέπεται πάντα στην εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; να <xliff:g id="ACTION">%2$s</xliff:g>;"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Μόνο κατά τη χρήση της εφαρμογής"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Πάντα"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Απόρριψη και να μην ερωτηθώ ξανά"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"έχουν απενεργοποιηθεί <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"έχουν απενεργοποιηθεί όλες"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"δεν έχει απενεργοποιηθεί καμία"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Να επιτρέπεται"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Εφαρμογές"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Δικαιώματα εφ/γών"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Να μην ερωτηθώ ξανά"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Χωρίς δικαιώματα"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Πρόσθετα δικαιώματα"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Άνοιγμα πληροφοριών εφαρμογής"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Ακόμα <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Ακόμα <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Αυτή η εφαρμογή σχεδιάστηκε για παλαιότερη έκδοση του Android. Η άρνηση άδειας μπορεί να έχει ως αποτέλεσμα να διακοπεί η κανονική λειτουργία της."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"εκτέλεση άγνωστης ενέργειας"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Επιτρέπονται <xliff:g id="COUNT_0">%1$d</xliff:g> από <xliff:g id="COUNT_1">%2$d</xliff:g> εφαρμογές"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Εμφάνιση συστήματος"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Απόκρυψη συστήματος"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Δεν υπάρχουν εφαρμογές"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Ρυθμίσεις τοποθεσίας"</string>
-    <string name="location_warning" msgid="8778701356292735971">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> είναι ο πάροχος των υπηρεσιών τοποθεσίας για τη συγκεκριμένη συσκευή. Μπορείτε να τροποποιήσετε την πρόσβαση τοποθεσίας από τις ρυθμίσεις τοποθεσίας."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Εάν αρνηθείτε να παραχωρήσετε αυτήν την άδεια, η λειτουργία ορισμένων βασικών δυνατοτήτων ενδέχεται να μην είναι η αναμενόμενη."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Επιβάλλεται από την πολιτική"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Η πρόσβαση στο παρασκήνιο απενενεργοποιήθηκε βάσει πολιτικής"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Η πρόσβαση στο παρασκήνιο ενεργοποιήθηκε βάσει πολιτικής"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Η πρόσβαση στο προσκήνιο ενεργοποιήθηκε βάσει πολιτικής"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Ελέγχεται από τον διαχειριστή"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Πάντα"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Μόνο κατά τη χρήση της εφαρμ."</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Ποτέ"</string>
-    <string name="loading" msgid="7811651799620593731">"Γίνεται φόρτωση…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Όλα τα δικαιώματα"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Άλλες δυνατότητες εφαρμογής"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Αίτημα άδειας"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Εντοπίστηκε επικάλυψη οθόνης"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Για να αλλάξετε αυτή τη ρύθμιση άδειας, θα πρέπει πρώτα να απενεργοποιήσετε την επικάλυψη οθόνης από τις Ρυθμίσεις &gt; Εφαρμογές"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Άνοιγμα ρυθμίσεων"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Οι ενέργειες εγκατάστασης/απεγκατάστασης δεν υποστηρίζονται στο Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Επιλέξτε σε τι θα έχει πρόσβαση η εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Η εφαρμογή &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ενημερώθηκε. Επιλέξτε σε τι θα έχει πρόσβαση αυτή η εφαρμογή."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Ακύρωση"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Συνέχεια"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Νέες άδειες"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Τρέχουσες άδειες"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Σταδιακή διάθεση εφαρμογής…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Άγνωστη"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στο tablet σας."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στην τηλεόρασή σας."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στο τηλέφωνό σας."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Το τηλέφωνό σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για οποιαδήποτε ζημιά στο τηλέφωνο ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Το tablet σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για οποιαδήποτε ζημιά στο tablet ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Η τηλεόρασή σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για οποιαδήποτε ζημιά στην τηλεόρασή ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Συνέχεια"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Ρυθμίσεις"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Εγκατάσταση/απεγκατάσταση εφαρμογών Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Πρόγρ. εγκατάστ. πακέτου"</string>
+    <string name="install" msgid="711829760615509273">"Εγκατάσταση"</string>
+    <string name="done" msgid="6632441120016885253">"Τέλος"</string>
+    <string name="cancel" msgid="1018267193425558088">"Ακύρωση"</string>
+    <string name="installing" msgid="4921993079741206516">"Εγκατάσταση…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Εγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Η εφαρμογή εγκαταστάθηκε."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Θέλετε να εγκαταστήσετε αυτήν την εφαρμογή;"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Θέλετε να εγκαταστήσετε μια ενημέρωση σε αυτήν την υπάρχουσα εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Θέλετε να εγκαταστήσετε μια ενημέρωση σε αυτήν την ενσωματωμένη εφαρμογή; Τα υπάρχοντα δεδομένα σας δεν θα χαθούν."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Η εφαρμογή δεν εγκαταστάθηκε."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Η εγκατάσταση του πακέτου αποκλείστηκε."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Η εφαρμογή δεν εγκαταστάθηκε, επειδή το πακέτο είναι σε διένεξη με κάποιο υπάρχον πακέτο."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Η εφαρμογή δεν εγκαταστάθηκε, επειδή δεν είναι συμβατή με το tablet που χρησιμοποιείτε."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Αυτή η εφαρμογή δεν είναι συμβατή με την τηλεόρασή σας."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Η εφαρμογή δεν εγκαταστάθηκε, επειδή δεν είναι συμβατή με το τηλέφωνό σας."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Η εφαρμογή δεν εγκαταστάθηκε, επειδή φαίνεται ότι το πακέτο δεν είναι έγκυρο."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g> στο tablet σας."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Δεν είναι δυνατή η εγκατάσταση άγνωστων εφαρμογών από αυτόν τον χρήστη"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Δεν επιτρέπεται η εγκατάσταση εφαρμογών σε αυτόν τον χρήστη"</string>
+    <string name="ok" msgid="7871959885003339302">"ΟΚ"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Διαχ. εφαρμογών"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Δεν υπάρχει χώρος"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Δεν ήταν δυνατή η εγκατάσταση της εφαρμογής <xliff:g id="APP_NAME">%1$s</xliff:g>. Απελευθερώστε λίγο χώρο και προσπαθήστε ξανά."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Η εφαρμογή δεν βρέθηκε"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Η εφαρμογή δεν βρέθηκε στη λίστα εγκατεστημένων εφαρμογών."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Δεν επιτρέπεται"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Δεν επιτρέπεται στον τρέχοντα χρήση να εκτελέσει την απεγκατάσταση."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Σφάλμα"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Δεν ήταν δυνατή η απεγκατάσταση της εφαρμογής."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Απεγκατάσταση εφαρμογής"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Απεγκατάσταση ενημέρωσης"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"Η δραστηριότητα <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> αποτελεί τμήμα της ακόλουθης εφαρμογής:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Θέλετε να απεγκαταστήσετε αυτήν την εφαρμογή;"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Θέλετε να απεγκαταστήσετε αυτήν την εφαρμογή για "<b>"όλους"</b>" τους χρήστες; Η εφαρμογή και τα δεδομένα της θα καταργηθούν από "<b>"όλους"</b>" τους χρήστες στη συσκευή."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Θέλετε να απεγκαταστήσετε αυτήν την εφαρμογή για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g>;"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Να αντικατασταθεί αυτή η εφαρμογή με την εργοστασιακή έκδοση; Όλα τα δεδομένα θα καταργηθούν."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Να αντικατασταθεί αυτή η εφαρμογή με την εργοστασιακή έκδοση; Όλα τα δεδομένα θα καταργηθούν. Αυτό επηρεάζει όλους τους χρήστες της συσκευής, συμπεριλαμβανομένων και των κατόχων προφίλ εργασίας."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Απεγκαταστάσεις σε εξέλιξη"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Αποτυχημένες απεγκαταστάσεις"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Απεγκατάσταση…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Απεγκατάσταση <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Η απεγκατάσταση ολοκληρώθηκε."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Οι ενέργειες εγκατάστασης/απεγκατάστασης δεν υποστηρίζονται στο Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Σταδιακή διάθεση εφαρμογής…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Άγνωστη"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στο tablet σας."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στην τηλεόρασή σας."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Για λόγους ασφάλειας, δεν επιτρέπεται η εγκατάσταση άγνωστων εφαρμογών από αυτήν την πηγή στο τηλέφωνό σας."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Το τηλέφωνό σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για τυχόν βλάβη που μπορεί να προκληθεί στο τηλέφωνο ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Το tablet σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για τυχόν βλάβη που μπορεί να προκληθεί στο tablet ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Η τηλεόρασή σας και τα προσωπικά δεδομένα σας είναι πιο ευάλωτα σε επιθέσεις από άγνωστες εφαρμογές. Με την εγκατάσταση αυτής της εφαρμογής, συμφωνείτε ότι είστε υπεύθυνοι για τυχόν βλάβη που μπορεί να προκληθεί στην τηλεόρασή ή απώλεια δεδομένων που μπορεί να προκύψει από τη χρήση τους."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Συνέχεια"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Ρυθμίσεις"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Εγκατάσταση/απεγκατάσταση εφαρμογών Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rAU/strings.xml b/packages/PackageInstaller/res/values-en-rAU/strings.xml
index ded57bb..ff926ac7 100644
--- a/packages/PackageInstaller/res/values-en-rAU/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rAU/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Package installer"</string>
-    <string name="next" msgid="3057143178373252333">"Next"</string>
-    <string name="install" msgid="5896438203900042068">"Install"</string>
-    <string name="done" msgid="3889387558374211719">"Done"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
-    <string name="installing" msgid="8613631001631998372">"Installing…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App installed."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
-    <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
-    <string name="launch" msgid="4826921505917605463">"Open"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem while parsing the package."</string>
-    <string name="newPerms" msgid="6039428254474104210">"New"</string>
-    <string name="allPerms" msgid="1024385515840703981">"All"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
-    <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
-    <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
-    <string name="loading" msgid="7811651799620593731">"Loading…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings &gt; Apps"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; has been updated. Choose what to allow this app to access."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling Wear apps"</string>
+    <string name="app_name" msgid="7488448184431507488">"Package installer"</string>
+    <string name="install" msgid="711829760615509273">"Install"</string>
+    <string name="done" msgid="6632441120016885253">"Done"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancel"</string>
+    <string name="installing" msgid="4921993079741206516">"Installing…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App installed."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Do you want to install this application?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Do you want to install an update to this existing application? Your existing data will not be lost."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Do you want to install an update to this built-in application? Your existing data will not be lost."</string>
+    <string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"App not installed as app isn\'t compatible with your tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"This app isn\'t compatible with your TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"App not installed as app isn\'t compatible with your phone."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"App not installed as package appears to be invalid."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+    <string name="launch" msgid="3952550563999890101">"Open"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App not found"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"The app wasn\'t found in the list of installed apps."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Not allowed"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"The current user is not allowed to perform this uninstallation."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"App could not be uninstalled."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Uninstall app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Uninstall update"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Do you want to uninstall this app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstallations"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstallations"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Uninstallation finished."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Uninstallation unsuccessful."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Can\'t uninstall active device admin app"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"This app is required for some users or profiles and was uninstalled for others"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"This app is needed for your profile and can\'t be uninstalled."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"This app is required by your device administrator and can\'t be uninstalled."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Manage device admin apps"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Manage users"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"There was a problem while parsing the package."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Install/uninstall actions not supported on Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Staging app…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Unknown"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continue"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Settings"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installing/uninstalling Wear apps"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rCA/strings.xml b/packages/PackageInstaller/res/values-en-rCA/strings.xml
index ded57bb..ff926ac7 100644
--- a/packages/PackageInstaller/res/values-en-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rCA/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Package installer"</string>
-    <string name="next" msgid="3057143178373252333">"Next"</string>
-    <string name="install" msgid="5896438203900042068">"Install"</string>
-    <string name="done" msgid="3889387558374211719">"Done"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
-    <string name="installing" msgid="8613631001631998372">"Installing…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App installed."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
-    <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
-    <string name="launch" msgid="4826921505917605463">"Open"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem while parsing the package."</string>
-    <string name="newPerms" msgid="6039428254474104210">"New"</string>
-    <string name="allPerms" msgid="1024385515840703981">"All"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
-    <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
-    <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
-    <string name="loading" msgid="7811651799620593731">"Loading…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings &gt; Apps"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; has been updated. Choose what to allow this app to access."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling Wear apps"</string>
+    <string name="app_name" msgid="7488448184431507488">"Package installer"</string>
+    <string name="install" msgid="711829760615509273">"Install"</string>
+    <string name="done" msgid="6632441120016885253">"Done"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancel"</string>
+    <string name="installing" msgid="4921993079741206516">"Installing…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App installed."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Do you want to install this application?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Do you want to install an update to this existing application? Your existing data will not be lost."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Do you want to install an update to this built-in application? Your existing data will not be lost."</string>
+    <string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"App not installed as app isn\'t compatible with your tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"This app isn\'t compatible with your TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"App not installed as app isn\'t compatible with your phone."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"App not installed as package appears to be invalid."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+    <string name="launch" msgid="3952550563999890101">"Open"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App not found"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"The app wasn\'t found in the list of installed apps."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Not allowed"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"The current user is not allowed to perform this uninstallation."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"App could not be uninstalled."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Uninstall app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Uninstall update"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Do you want to uninstall this app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstallations"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstallations"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Uninstallation finished."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Uninstallation unsuccessful."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Can\'t uninstall active device admin app"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"This app is required for some users or profiles and was uninstalled for others"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"This app is needed for your profile and can\'t be uninstalled."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"This app is required by your device administrator and can\'t be uninstalled."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Manage device admin apps"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Manage users"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"There was a problem while parsing the package."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Install/uninstall actions not supported on Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Staging app…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Unknown"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continue"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Settings"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installing/uninstalling Wear apps"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rGB/strings.xml b/packages/PackageInstaller/res/values-en-rGB/strings.xml
index ded57bb..ff926ac7 100644
--- a/packages/PackageInstaller/res/values-en-rGB/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rGB/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Package installer"</string>
-    <string name="next" msgid="3057143178373252333">"Next"</string>
-    <string name="install" msgid="5896438203900042068">"Install"</string>
-    <string name="done" msgid="3889387558374211719">"Done"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
-    <string name="installing" msgid="8613631001631998372">"Installing…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App installed."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
-    <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
-    <string name="launch" msgid="4826921505917605463">"Open"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem while parsing the package."</string>
-    <string name="newPerms" msgid="6039428254474104210">"New"</string>
-    <string name="allPerms" msgid="1024385515840703981">"All"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
-    <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
-    <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
-    <string name="loading" msgid="7811651799620593731">"Loading…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings &gt; Apps"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; has been updated. Choose what to allow this app to access."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling Wear apps"</string>
+    <string name="app_name" msgid="7488448184431507488">"Package installer"</string>
+    <string name="install" msgid="711829760615509273">"Install"</string>
+    <string name="done" msgid="6632441120016885253">"Done"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancel"</string>
+    <string name="installing" msgid="4921993079741206516">"Installing…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App installed."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Do you want to install this application?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Do you want to install an update to this existing application? Your existing data will not be lost."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Do you want to install an update to this built-in application? Your existing data will not be lost."</string>
+    <string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"App not installed as app isn\'t compatible with your tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"This app isn\'t compatible with your TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"App not installed as app isn\'t compatible with your phone."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"App not installed as package appears to be invalid."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+    <string name="launch" msgid="3952550563999890101">"Open"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App not found"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"The app wasn\'t found in the list of installed apps."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Not allowed"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"The current user is not allowed to perform this uninstallation."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"App could not be uninstalled."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Uninstall app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Uninstall update"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Do you want to uninstall this app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstallations"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstallations"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Uninstallation finished."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Uninstallation unsuccessful."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Can\'t uninstall active device admin app"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"This app is required for some users or profiles and was uninstalled for others"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"This app is needed for your profile and can\'t be uninstalled."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"This app is required by your device administrator and can\'t be uninstalled."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Manage device admin apps"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Manage users"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"There was a problem while parsing the package."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Install/uninstall actions not supported on Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Staging app…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Unknown"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continue"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Settings"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installing/uninstalling Wear apps"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rIN/strings.xml b/packages/PackageInstaller/res/values-en-rIN/strings.xml
index ded57bb..ff926ac7 100644
--- a/packages/PackageInstaller/res/values-en-rIN/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rIN/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Package installer"</string>
-    <string name="next" msgid="3057143178373252333">"Next"</string>
-    <string name="install" msgid="5896438203900042068">"Install"</string>
-    <string name="done" msgid="3889387558374211719">"Done"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancel"</string>
-    <string name="installing" msgid="8613631001631998372">"Installing…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App installed."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Do you want to install this application? It will get access to:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Do you want to install this application? It does not require any special access."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access."</string>
-    <string name="install_failed" msgid="6579998651498970899">"App not installed."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"The package was blocked from being installed."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"This app isn\'t compatible with your TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
-    <string name="launch" msgid="4826921505917605463">"Open"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Unknown apps can\'t be installed by this user"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"This user is not allowed to install apps"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Manage apps"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Out of space"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App not found"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"The app wasn\'t found in the list of installed apps."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Not allowed"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"The current user is not allowed to perform this uninstallation."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"App could not be uninstalled."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstall app"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstall update"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Do you want to uninstall this app?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Replace this app with the factory version? All data will be removed."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Running uninstalls"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Failed uninstalls"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Uninstalling…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Uninstall finished"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Uninstall unsuccessful."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Can\'t uninstall active device admin app"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"This app is required for some users or profiles and was uninstalled for others"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"This app is needed for your profile and can\'t be uninstalled."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"This app is required by your device administrator and can\'t be uninstalled."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Manage device admin apps"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Manage users"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"There was a problem while parsing the package."</string>
-    <string name="newPerms" msgid="6039428254474104210">"New"</string>
-    <string name="allPerms" msgid="1024385515840703981">"All"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Device Access"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"This update requires no new permissions."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Deny"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"More info"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Deny anyway"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> of <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Always allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Only while using app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Always"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Deny and don’t ask again"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disabled"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"all disabled"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"none disabled"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Allow"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"App permissions"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Don\'t ask again"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"No permissions"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Additional permissions"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Open app info"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> more</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> more</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"perform an unknown action"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> of <xliff:g id="COUNT_1">%2$d</xliff:g> apps allowed"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Show system"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Hide system"</string>
-    <string name="no_apps" msgid="1965493419005012569">"No apps"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Location Settings"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is a provider of location services for this device. Location access can be modified from location settings."</string>
-    <string name="system_warning" msgid="7103819124542305179">"If you deny this permission, basic features of your device may no longer function as intended."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enforced by policy"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Background access disabled by policy"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Background access enabled by policy"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Foreground access enabled by policy"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlled by admin"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Always"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Only while using app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Never"</string>
-    <string name="loading" msgid="7811651799620593731">"Loading…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"All permissions"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Other app capabilities"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Permission request"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Screen overlay detected"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"To change this permission setting, you first have to turn off the screen overlay from Settings &gt; Apps"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Open settings"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Install/Uninstall actions not supported on Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Choose what to allow &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to access"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; has been updated. Choose what to allow this app to access."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancel"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continue"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"New permissions"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Current permissions"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Staging app…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Unknown"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"For your security, your TV is not allowed to install unknown apps from this source."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"For your security, your phone is not allowed to install unknown apps from this source."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continue"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Settings"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installing/uninstalling Wear apps"</string>
+    <string name="app_name" msgid="7488448184431507488">"Package installer"</string>
+    <string name="install" msgid="711829760615509273">"Install"</string>
+    <string name="done" msgid="6632441120016885253">"Done"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancel"</string>
+    <string name="installing" msgid="4921993079741206516">"Installing…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installing <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App installed."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Do you want to install this application?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Do you want to install an update to this existing application? Your existing data will not be lost."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Do you want to install an update to this built-in application? Your existing data will not be lost."</string>
+    <string name="install_failed" msgid="5777824004474125469">"App not installed."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"The package was blocked from being installed."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"App not installed as package conflicts with an existing package."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"App not installed as app isn\'t compatible with your tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"This app isn\'t compatible with your TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"App not installed as app isn\'t compatible with your phone."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"App not installed as package appears to be invalid."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed on your phone."</string>
+    <string name="launch" msgid="3952550563999890101">"Open"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Your admin doesn\'t allow installation of apps obtained from unknown sources"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Unknown apps can\'t be installed by this user"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"This user is not allowed to install apps"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Manage apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Out of space"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be installed. Free up some space and try again."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App not found"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"The app wasn\'t found in the list of installed apps."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Not allowed"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"The current user is not allowed to perform this uninstallation."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"App could not be uninstalled."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Uninstall app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Uninstall update"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> is part of the following app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Do you want to uninstall this app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Do you want to uninstall this app for "<b>"all"</b>" users? The application and its data will be removed from "<b>"all"</b>" users on the device."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Do you want to uninstall this app for the user <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Replace this app with the factory version? All data will be removed."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Running uninstallations"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Failed uninstallations"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Uninstalling…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Uninstallation finished."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Uninstalled <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Uninstallation unsuccessful."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Uninstalling <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> unsuccessful."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Can\'t uninstall active device admin app"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Can\'t uninstall active device admin app for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"This app is required for some users or profiles and was uninstalled for others"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"This app is needed for your profile and can\'t be uninstalled."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"This app is required by your device administrator and can\'t be uninstalled."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Manage device admin apps"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Manage users"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> couldn\'t be uninstalled."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"There was a problem while parsing the package."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Install/uninstall actions not supported on Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Staging app…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Unknown"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"For your security, your tablet is not allowed to install unknown apps from this source."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"For your security, your TV is not allowed to install unknown apps from this source."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"For your security, your phone is not allowed to install unknown apps from this source."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continue"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Settings"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installing/uninstalling Wear apps"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-en-rXC/strings.xml b/packages/PackageInstaller/res/values-en-rXC/strings.xml
index ca392cc..1dc8cee 100644
--- a/packages/PackageInstaller/res/values-en-rXC/strings.xml
+++ b/packages/PackageInstaller/res/values-en-rXC/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‎‏‏‎‎‏‎‎Package installer‎‏‎‎‏‎"</string>
-    <string name="next" msgid="3057143178373252333">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‎‏‏‎‏‎Next‎‏‎‎‏‎"</string>
-    <string name="install" msgid="5896438203900042068">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‎‏‏‎‏‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‏‎‎‎Install‎‏‎‎‏‎"</string>
-    <string name="done" msgid="3889387558374211719">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‏‏‎Done‎‏‎‎‏‎"</string>
-    <string name="cancel" msgid="8360346460165114585">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‏‎‏‏‎‏‏‎‎‏‎Cancel‎‏‎‎‏‎"</string>
-    <string name="installing" msgid="8613631001631998372">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‏‎‎‎Installing…‎‏‎‎‏‎"</string>
-    <string name="installing_app" msgid="4097935682329028894">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎Installing ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
-    <string name="install_done" msgid="3682715442154357097">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎App installed.‎‏‎‎‏‎"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‎‎‎‎‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‎Do you want to install this application? It will get access to:‎‏‎‎‏‎"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‏‏‎‎‎‎‎Do you want to install this application? It does not require any special access.‎‏‎‎‏‎"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‏‎‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‎‎‏‏‎‏‎‎‎‏‎‏‏‏‎‎‎Do you want to install an update to this existing application? Your existing data will not be lost. The updated application will get access to:‎‏‎‎‏‎"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‏‎‎‏‏‏‎‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‎‎‎Do you want to install an update to this built-in application? Your existing data will not be lost. The updated application will get access to:‎‏‎‎‏‎"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‏‏‎‎‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‎‎Do you want to install an update to this existing application? Your existing data will not be lost. It does not require any special access.‎‏‎‎‏‎"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‏‎‏‏‎‎Do you want to install an update to this built-in application? Your existing data will not be lost. It does not require any special access.‎‏‎‎‏‎"</string>
-    <string name="install_failed" msgid="6579998651498970899">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‏‏‎App not installed.‎‏‎‎‏‎"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‏‎‏‎‎‏‎The package was blocked from being installed.‎‏‎‎‏‎"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‎App not installed as package conflicts with an existing package.‎‏‎‎‏‎"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎App not installed as app isn\'t compatible with your tablet.‎‏‎‎‏‎"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎This app isn\'t compatible with your TV.‎‏‎‎‏‎"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‏‎‎‎‎App not installed as app isn\'t compatible with your phone.‎‏‎‎‏‎"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎App not installed as package appears to be invalid.‎‏‎‎‏‎"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‎‎‎‎‎‏‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be installed on your tablet.‎‏‎‎‏‎"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‎‎‎‏‎‎‏‎‎‎‎‏‎‎‎‏‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be installed on your TV.‎‏‎‎‏‎"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be installed on your phone.‎‏‎‎‏‎"</string>
-    <string name="launch" msgid="4826921505917605463">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‏‎Open‎‏‎‎‏‎"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‎‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‏‎‏‏‎‎Your admin doesn\'t allow installation of apps obtained from unknown sources‎‏‎‎‏‎"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‎‎‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎Unknown apps can\'t be installed by this user‎‏‎‎‏‎"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‏‏‏‎‏‎‎‏‎‎‎This user is not allowed to install apps‎‏‎‎‏‎"</string>
-    <string name="ok" msgid="3468756155452870475">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‏‏‎OK‎‏‎‎‏‎"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎Manage apps‎‏‎‎‏‎"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎Out of space‎‏‎‎‏‎"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be installed. Free up some space and try again.‎‏‎‎‏‎"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‏‏‎‎‎App not found‎‏‎‎‏‎"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎The app wasn\'t found in the list of installed apps.‎‏‎‎‏‎"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‎‏‎‏‏‎‎‏‏‎‏‎‎‎‎‏‎‎‎‎‏‏‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎Not allowed‎‏‎‎‏‎"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‏‏‎‎‏‎The current user is not allowed to perform this uninstallation.‎‏‎‎‏‎"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎‎‎‏‎‎‏‎‏‏‎‎‏‎‏‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‎Error‎‏‎‎‏‎"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‎‏‎‎‎‏‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎App could not be uninstalled.‎‏‎‎‏‎"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‏‎Uninstall app‎‏‎‎‏‎"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‎‎Uninstall update‎‏‎‎‏‎"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‎‏‎‏‏‏‏‎‏‏‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‎‎‎‎‏‏‎‎‎‏‎‎‏‏‎<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is part of the following app:‎‏‎‎‏‎"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‏‏‏‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‎‎Do you want to uninstall this app?‎‏‎‎‏‎"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‎Do you want to uninstall this app for ‎‏‎‎‏‏‎"<b>"‎‏‎‎‏‏‏‎all‎‏‎‎‏‏‎"</b>"‎‏‎‎‏‏‏‎ users? The application and its data will be removed from ‎‏‎‎‏‏‎"<b>"‎‏‎‎‏‏‏‎all‎‏‎‎‏‏‎"</b>"‎‏‎‎‏‏‏‎ users on the device.‎‏‎‎‏‎"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‎‏‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‏‏‏‏‎‎‎‎‏‎‎‏‎‏‎Do you want to uninstall this app for the user ‎‏‎‎‏‏‎<xliff:g id="USERNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‏‎‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‏‎‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎Replace this app with the factory version? All data will be removed.‎‏‎‎‏‎"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‏‏‏‎Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles.‎‏‎‎‏‎"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎Running uninstalls‎‏‎‎‏‎"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎Failed uninstalls‎‏‎‎‏‎"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‏‏‎‏‎‎‏‏‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‎Uninstalling…‎‏‎‎‏‎"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎Uninstalling ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‎‏‎‎‎‎‎‎Uninstall finished.‎‏‎‎‏‎"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‏‏‏‏‏‎Uninstalled ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‏‏‏‎‎‎‎Uninstall unsuccessful.‎‏‎‎‏‎"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‏‏‎‎‏‎‏‎‏‏‏‎‎Uninstalling ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ unsuccessful.‎‏‎‎‏‎"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎Can\'t uninstall active device admin app‎‏‎‎‏‎"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‏‎‎‎Can\'t uninstall active device admin app for ‎‏‎‎‏‏‎<xliff:g id="USERNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‎‎This app is required for some users or profiles and was uninstalled for others‎‏‎‎‏‎"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‏‏‎‏‏‏‎‏‎‏‎‎‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‎This app is needed for your profile and can\'t be uninstalled.‎‏‎‎‏‎"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‎‎‏‎‎‎‎‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‎‏‎‏‎‏‎‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‎‎‏‏‏‎This app is required by your device administrator and can\'t be uninstalled.‎‏‎‎‏‎"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‏‎‎‎‏‏‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‎Manage device admin apps‎‏‎‎‏‎"</string>
-    <string name="manage_users" msgid="3125018886835668847">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‎‏‎‎‎‏‏‏‎‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‏‏‏‎Manage users‎‏‎‎‏‎"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‏‏‎‏‏‏‏‎‎‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be uninstalled.‎‏‎‎‏‎"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‏‎‏‎‏‏‎‏‏‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎‏‏‎There was a problem parsing the package.‎‏‎‎‏‎"</string>
-    <string name="newPerms" msgid="6039428254474104210">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‎‎New‎‏‎‎‏‎"</string>
-    <string name="allPerms" msgid="1024385515840703981">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‏‏‎‎‎‎‎‎‎‎‏‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎All‎‏‎‎‏‎"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‎‏‎‎‏‎Privacy‎‏‎‎‏‎"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‎‎‎‏‎‎‏‎‏‎‎‎‎Device Access‎‏‎‎‏‎"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‎‏‎‏‎‏‎‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‎‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‏‏‏‎This update requires no new permissions.‎‏‎‎‏‎"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‎‏‎‎‎‎‏‎‎‏‏‏‎‎‏‏‎‎‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎Deny‎‏‎‎‏‎"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎More info‎‏‎‎‏‎"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‎‎‏‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‎‏‎‎‎‎‏‎‎Deny anyway‎‏‎‎‏‎"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‏‎‎‏‎‎‏‏‎<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‏‏‎‎Allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to ‎‏‎‎‏‏‎<xliff:g id="ACTION">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‎‏‏‏‏‎‎‏‎‏‎‏‎‏‎Always allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to ‎‏‎‎‏‏‎<xliff:g id="ACTION">%2$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‎‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‏‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‎‎Only while using app‎‏‎‎‏‎"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‏‎‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‏‏‏‎Always‎‏‎‎‏‎"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‎‏‎Deny and don’t ask again‎‏‎‎‏‎"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT">%1$d</xliff:g>‎‏‎‎‏‏‏‎ disabled‎‏‎‎‏‎"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‎‏‏‎‎‎‏‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎all disabled‎‏‎‎‏‎"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‏‎‏‎‏‏‎‏‎‏‏‏‏‏‎‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‏‏‏‎‎none disabled‎‏‎‎‏‎"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‎‎‎‏‎‎‎‏‏‏‎Allow‎‏‎‎‏‎"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‎‎‎Apps‎‏‎‎‏‎"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‎‎‏‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‎‏‎‎App permissions‎‏‎‎‏‎"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‎‏‎‎‏‏‏‏‎Don\'t ask again‎‏‎‎‏‎"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‎‎‎‎‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎No permissions‎‏‎‎‏‎"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‏‏‏‎‎‏‏‎‎‎‎‏‏‏‎‏‎‎‎‎‏‎‏‎‎‏‎‎‏‎‎‏‏‎Additional permissions‎‏‎‎‏‎"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎Open app info‎‏‎‎‏‎"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ more‎‏‎‎‏‎</item>
-      <item quantity="one">‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‏‎‎‎‏‎‎‎‎‏‎‎‏‎‎‏‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ more‎‏‎‎‏‎</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‎‏‏‏‎‏‏‏‎This app was designed for an older version of Android. Denying permission may cause it to no longer function as intended.‎‏‎‎‏‎"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‎‎perform an unknown action‎‏‎‎‏‎"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‎‏‎‏‎‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="COUNT_0">%1$d</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="COUNT_1">%2$d</xliff:g>‎‏‎‎‏‏‏‎ apps allowed‎‏‎‎‏‎"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‎‎‎‎‏‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‎‏‎Show system‎‏‎‎‏‎"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‏‎‎‎‏‎‎‎‏‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‎‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‏‎‎‎‏‎Hide system‎‏‎‎‏‎"</string>
-    <string name="no_apps" msgid="1965493419005012569">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‎‎‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‏‎No apps‎‏‎‎‏‎"</string>
-    <string name="location_settings" msgid="1774875730854491297">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎Location Settings‎‏‎‎‏‎"</string>
-    <string name="location_warning" msgid="8778701356292735971">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‎‏‎‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‏‎‎‏‏‏‎‏‏‎‎‎‏‎‎‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is a provider of location services for this device. Location access can be modified from location settings.‎‏‎‎‏‎"</string>
-    <string name="system_warning" msgid="7103819124542305179">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‏‎‏‏‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‏‎‏‏‎If you deny this permission, basic features of your device may no longer function as intended.‎‏‎‎‏‎"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‎‎‎‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎Enforced by policy‎‏‎‎‏‎"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‎‏‏‎‎‎‏‏‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‏‎Background access disabled by policy‎‏‎‎‏‎"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‏‏‎‎Background access enabled by policy‎‏‎‎‏‎"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‏‎‏‎‏‎‎‎Foreground access enabled by policy‎‏‎‎‏‎"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‎‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‏‎‎‎‏‏‏‏‎‎‏‏‏‎‏‏‏‏‎‏‏‏‎‎‎‎‎‎Controlled by admin‎‏‎‎‏‎"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎‎‎‏‎‎‎‎Always‎‏‎‎‏‎"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‏‎‏‏‏‏‎‎‏‎‎‏‎Only while using app‎‏‎‎‏‎"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‎‎‏‎‏‏‏‎‎‎‎‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎Never‎‏‎‎‏‎"</string>
-    <string name="loading" msgid="7811651799620593731">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎‎‏‎‎‎‎‏‏‎Loading…‎‏‎‎‏‎"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‎‏‎‏‏‎‎‏‎‎‏‎‎‎‎‏‏‎‎‎‏‎‏‎‎‎‏‎‎‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‎‎All permissions‎‏‎‎‏‎"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‎‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎Other app capabilities‎‏‎‎‏‎"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎Permission request‎‏‎‎‏‎"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‎‎‏‏‎‎‎‎‏‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‎Screen overlay detected‎‏‎‎‏‎"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‎‏‏‎‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎To change this permission setting, you first have to turn off the screen overlay from Settings &gt; Apps‎‏‎‎‏‎"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‎‏‎‎‎‎‏‎‏‎‏‎‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎Open settings‎‏‎‎‏‎"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‎‎‏‏‎‎‎‏‏‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‎‎‏‎Android Wear‎‏‎‎‏‎"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‏‎‏‏‏‎‏‎‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‏‎‎‎‎Install/Uninstall actions not supported on Wear.‎‏‎‎‏‎"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‏‏‎‎‏‎‏‎‎‎‎‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‎‏‎‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‏‎‏‏‏‎Choose what to allow &lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; to access‎‏‎‎‏‎"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‏‎‏‎‏‎‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎&lt;b&gt;‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎&lt;/b&gt; has been updated. Choose what to allow this app to access.‎‏‎‎‏‎"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‏‎‏‎‏‏‎‎‏‎‏‏‎‎‏‏‏‎‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‏‎Cancel‎‏‎‎‏‎"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‎‏‎‎Continue‎‏‎‎‏‎"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‎‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‏‏‏‎New permissions‎‏‎‎‏‎"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‎‏‏‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‎‎‏‏‏‎‎Current permissions‎‏‎‎‏‎"</string>
-    <string name="message_staging" msgid="6151794817691100003">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‎‎‏‎‏‏‎‎‎‎‎‏‏‏‏‎‎‏‎‎‎‏‎‎‏‎‎‎‏‏‎‏‏‎‎‎‏‏‎Staging app…‎‏‎‎‏‎"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‎‎‏‏‎‎‏‎‎‏‎‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‎‎‎‎‎‎‎‏‎Unknown‎‏‎‎‏‎"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‎‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‎‎‎‏‏‏‏‏‎‏‏‏‏‎For your security, your tablet is not allowed to install unknown apps from this source.‎‏‎‎‏‎"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎‏‎‎‏‏‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‎For your security, your TV is not allowed to install unknown apps from this source.‎‏‎‎‏‎"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‎‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎For your security, your phone is not allowed to install unknown apps from this source.‎‏‎‎‏‎"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‎‏‏‎‏‎‏‎‏‎‎‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‎‎Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use.‎‏‎‎‏‎"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‎‎‎‏‎‏‎‏‏‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‏‎‎Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use.‎‏‎‎‏‎"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‎‎‎‏‎‏‏‎‏‎‎‎‎‎Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use.‎‏‎‎‏‎"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‎‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‏‎‏‎‎‎‎‏‎‎‎Continue‎‏‎‎‏‎"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‏‎‎‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‏‎‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎Settings‎‏‎‎‏‎"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‏‏‎‏‏‎‎‎Installing/uninstalling wear apps‎‏‎‎‏‎"</string>
+    <string name="app_name" msgid="7488448184431507488">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‎Package installer‎‏‎‎‏‎"</string>
+    <string name="install" msgid="711829760615509273">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‏‎‎‎‏‏‎‎‏‎Install‎‏‎‎‏‎"</string>
+    <string name="done" msgid="6632441120016885253">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‎‎‎‏‎‏‎Done‎‏‎‎‏‎"</string>
+    <string name="cancel" msgid="1018267193425558088">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‎Cancel‎‏‎‎‏‎"</string>
+    <string name="installing" msgid="4921993079741206516">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‎‏‎‏‎‎‎‎‎‏‏‎‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎Installing…‎‏‎‎‏‎"</string>
+    <string name="installing_app" msgid="1165095864863849422">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‏‎‏‏‎‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‏‏‏‎‎‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‎‎Installing ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
+    <string name="install_done" msgid="5987363587661783896">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‎‎‏‏‎‏‎‏‏‎‎‎‎App installed.‎‏‎‎‏‎"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎Do you want to install this application?‎‏‎‎‏‎"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‎‎‏‏‎‏‎‏‏‏‏‏‎‏‏‏‏‎‏‎‎‏‎‎‎‎‎‏‎‏‏‎Do you want to install an update to this existing application? Your existing data will not be lost.‎‏‎‎‏‎"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎Do you want to install an update to this built-in application? Your existing data will not be lost.‎‏‎‎‏‎"</string>
+    <string name="install_failed" msgid="5777824004474125469">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎App not installed.‎‏‎‎‏‎"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‏‏‎‎‎‏‏‎‏‏‎‎‏‎‏‏‏‏‎‎The package was blocked from being installed.‎‏‎‎‏‎"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‏‏‎‏‎‎‏‎‎‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‎‎‏‎‎‏‏‏‏‎‎‏‏‎‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎App not installed as package conflicts with an existing package.‎‏‎‎‏‎"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‏‏‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‎‎‎‏‏‏‎‎‎‎App not installed as app isn\'t compatible with your tablet.‎‏‎‎‏‎"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‎‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‏‏‎This app isn\'t compatible with your TV.‎‏‎‎‏‎"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‏‎‏‏‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎‎App not installed as app isn\'t compatible with your phone.‎‏‎‎‏‎"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‎‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‏‏‎‏‎‎App not installed as package appears to be invalid.‎‏‎‎‏‎"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‎‎‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‏‎‎‎‏‎‏‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be installed on your tablet.‎‏‎‎‏‎"</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be installed on your TV.‎‏‎‎‏‎"</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‏‏‏‎‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be installed on your phone.‎‏‎‎‏‎"</string>
+    <string name="launch" msgid="3952550563999890101">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‏‏‎‎‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‎‏‎Open‎‏‎‎‏‎"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‎‏‎‎‏‏‎‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‏‎‎‏‏‎‏‏‏‏‏‎Your admin doesn\'t allow installation of apps obtained from unknown sources‎‏‎‎‏‎"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‏‎‎‎‏‎‎‎‏‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‏‎‏‏‏‎‎‏‏‎‎‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‎Unknown apps can\'t be installed by this user‎‏‎‎‏‎"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‎‎‏‏‏‏‏‎‎‎‎‏‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‏‎‎‏‎‏‎‏‏‎‎‏‏‎‎This user is not allowed to install apps‎‏‎‎‏‎"</string>
+    <string name="ok" msgid="7871959885003339302">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‎‎‏‎‎‏‏‎‎OK‎‏‎‎‏‎"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‏‏‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‎‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎‎Manage apps‎‏‎‎‏‎"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‏‎‏‏‎‎‏‏‏‎‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‎‎‎‏‏‏‏‎‎Out of space‎‏‎‎‏‎"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be installed. Free up some space and try again.‎‏‎‎‏‎"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‏‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎App not found‎‏‎‎‏‎"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‎‏‏‏‎‎‏‎‏‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‎‎‏‎‎‎‎‏‎‎‏‏‎‏‏‎The app wasn\'t found in the list of installed apps.‎‏‎‎‏‎"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‎‏‎‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‎‎‏‏‎‎‎‏‏‏‎‎‎‎Not allowed‎‏‎‎‏‎"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‎‎‎‎‎‏‎‎‎‏‎‎‏‏‎‎‏‏‎‏‏‏‎‎‎‏‏‏‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‎‎‎‏‎The current user is not allowed to perform this uninstallation.‎‏‎‎‏‎"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‎‎‎‏‎‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‎‏‏‏‎‏‏‎‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‏‎‏‎‎‎‎Error‎‏‎‎‏‎"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‏‏‏‏‎‎‏‎‏‎‎‏‎‏‎‎‎‎‎‎App could not be uninstalled.‎‏‎‎‏‎"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‏‏‎Uninstall app‎‏‎‎‏‎"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‎‏‏‎‏‏‏‎Uninstall update‎‏‎‎‏‎"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‎‎‏‎‎‎‎‏‎‏‎‎‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‏‎<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ is part of the following app:‎‏‎‎‏‎"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‏‏‎‏‏‎‎‎‏‏‎‎‏‏‎‎‏‎‏‎‎‎‎‏‏‎‎‏‏‏‎‏‏‎‎‎Do you want to uninstall this app?‎‏‎‎‏‎"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‏‏‏‏‎Do you want to uninstall this app for ‎‏‎‎‏‏‎"<b>"‎‏‎‎‏‏‏‎all‎‏‎‎‏‏‎"</b>"‎‏‎‎‏‏‏‎ users? The application and its data will be removed from ‎‏‎‎‏‏‎"<b>"‎‏‎‎‏‏‏‎all‎‏‎‎‏‏‎"</b>"‎‏‎‎‏‏‏‎ users on the device.‎‏‎‎‏‎"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‎‏‏‎‏‎‏‎‎‎‎‏‏‏‎‎Do you want to uninstall this app for the user ‎‏‎‎‏‏‎<xliff:g id="USERNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎?‎‏‎‎‏‎"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‏‏‏‏‏‎‎‎‏‎‎‏‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‎‏‎‎‎‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‎‎‎‎‏‎Replace this app with the factory version? All data will be removed.‎‏‎‎‏‎"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‎‎‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎Replace this app with the factory version? All data will be removed. This affects all users of this device, including those with work profiles.‎‏‎‎‏‎"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‏‎‏‎‏‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‏‏‏‎‏‎Running uninstalls‎‏‎‎‏‎"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‎‎‎‏‏‏‎‏‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎Failed uninstalls‎‏‎‎‏‎"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‎‏‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‏‎‏‎‏‎‏‏‏‏‎‏‎Uninstalling…‎‏‎‎‏‎"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‎‎‏‏‏‏‏‏‎‎‏‎‎‏‎‏‏‏‎‏‎‎‏‎‏‎‏‎Uninstalling ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎…‎‏‎‎‏‎"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎‏‏‎‎‎‏‏‏‎‎‏‏‎‎‏‎‎‎‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‏‎‏‎Uninstall finished.‎‏‎‎‏‎"</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‏‏‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‎‎‎‎‎‎‎‏‏‎‏‏‎‏‎‎‎‏‎‎‎‎Uninstalled ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‎‏‏‎‏‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‎‏‎‏‏‎‎‎Uninstall unsuccessful.‎‏‎‎‏‎"</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‎‎‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‏‏‏‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‏‎‏‏‎‎‎‎‏‎‎‎Uninstalling ‎‏‎‎‏‏‎<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>‎‏‎‎‏‏‏‎ unsuccessful.‎‏‎‎‏‎"</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‏‎‎‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‎‎‎‏‏‎‏‎‎‎‏‎Can\'t uninstall active device admin app‎‏‎‎‏‎"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‎‎‏‎‎‏‏‏‎‎‎‎‏‏‏‎‏‎‏‎‎‏‎‏‎‏‎‎‏‎‎‎‏‎‎‎‎‎‎‎‎‎‎Can\'t uninstall active device admin app for ‎‏‎‎‏‏‎<xliff:g id="USERNAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‏‏‏‎‎‎‏‏‎‎‎‎‎‏‏‎‏‎This app is required for some users or profiles and was uninstalled for others‎‏‎‎‏‎"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‏‏‏‏‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‏‎‎‏‎‏‏‎‎‏‏‏‏‏‏‏‎‎‎‎‎This app is needed for your profile and can\'t be uninstalled.‎‏‎‎‏‎"</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‎‏‎‏‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎This app is required by your device administrator and can\'t be uninstalled.‎‏‎‎‏‎"</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎‎‎‎‎‎‎‎Manage device admin apps‎‏‎‎‏‎"</string>
+    <string name="manage_users" msgid="1243995386982560813">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‎‎‎‏‏‏‎‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‎‎‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‎‎‏‎‏‏‎‏‎Manage users‎‏‎‎‏‎"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‏‎‎‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‏‎‎‏‏‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_NAME">%1$s</xliff:g>‎‏‎‎‏‏‏‎ couldn\'t be uninstalled.‎‏‎‎‏‎"</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‏‏‎‎‎‎‏‏‏‎‎‏‏‏‏‏‏‎‎‎‏‎‎‎‏‎‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‏‎There was a problem parsing the package.‎‏‎‎‏‎"</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‏‏‎‏‏‎‏‎‎‏‏‎‏‎Android Wear‎‏‎‎‏‎"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‏‎‏‏‎‏‎‎‏‎‏‎‎‎‏‎‏‎‎‏‏‎‏‎‎‎‏‏‎‎‏‎‏‎Install/Uninstall actions not supported on Wear.‎‏‎‎‏‎"</string>
+    <string name="message_staging" msgid="8032722385658438567">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‎‎‏‏‏‎‏‎‎‏‏‏‎Staging app…‎‏‎‎‏‎"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‏‎‎‎‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‏‏‎‏‏‏‏‎‏‎‏‏‎‎Unknown‎‏‎‎‏‎"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‏‎‏‏‎‎‎‎‎‎‏‎‏‎‎‎‎‎‏‏‏‏‏‎‎‎‏‏‎‏‎‎‎‎‏‏‏‏‎‎‏‏‏‏‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎For your security, your tablet is not allowed to install unknown apps from this source.‎‏‎‎‏‎"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‏‏‏‎‎‎‏‏‏‏‎‏‎‏‎‎‏‏‏‏‎‏‎‎‏‏‎‎‎‏‎‏‎‎‎For your security, your TV is not allowed to install unknown apps from this source.‎‏‎‎‏‎"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‎‎‏‏‎‏‏‎‏‎‏‎‎‎‏‎‎‏‎‏‎‏‏‏‎‎‎‎‎‏‏‎‎‎‎‏‎‎‎‏‎‏‎‏‎‏‎‎‏‏‏‎‏‎For your security, your phone is not allowed to install unknown apps from this source.‎‏‎‎‏‎"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‏‎‏‎‏‎‎‏‎‏‏‏‏‏‎‏‏‎‎‎‎‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‏‎‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‎Your phone and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your phone or loss of data that may result from its use.‎‏‎‎‏‎"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‎‏‏‎‏‏‏‏‏‎‎‎‎‎‎‎‎‎‏‏‏‎‎‏‏‏‎‎‏‎‏‎‏‏‏‎‎‎Your tablet and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your tablet or loss of data that may result from its use.‎‏‎‎‏‎"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‎‏‎‏‎‏‎‏‏‏‎‎‏‎‎‏‏‏‎‎‏‎‏‎‎‎‏‏‎‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‎‏‏‏‎‏‏‎‎Your TV and personal data are more vulnerable to attack by unknown apps. By installing this app, you agree that you are responsible for any damage to your TV or loss of data that may result from its use.‎‏‎‎‏‎"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‎‎‏‏‏‎‎‎‏‎‏‎‏‎‎‏‎‏‏‎‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎Continue‎‏‎‎‏‎"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‎‎‏‎‏‎‎‏‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‏‎‎‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‎‏‏‏‏‎Settings‎‏‎‎‏‎"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‎‏‎‎‎‎‎‎‎‏‎‏‎‏‎‎‏‎‏‎‎‏‎‏‏‏‏‏‎‎‎‎‏‎‎‏‎‎‎‏‎‏‎‎Installing/uninstalling wear apps‎‏‎‎‏‎"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
index 178f551..887f380 100644
--- a/packages/PackageInstaller/res/values-es-rUS/strings.xml
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Programa de instalación del paquete"</string>
-    <string name="next" msgid="3057143178373252333">"Siguiente"</string>
-    <string name="install" msgid="5896438203900042068">"Instalar"</string>
-    <string name="done" msgid="3889387558374211719">"Finalizado"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
-    <string name="installing" msgid="8613631001631998372">"Instalando…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Se instaló la aplicación."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"¿Deseas instalar la aplicación? Esta tendrá acceso a lo siguiente:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"¿Deseas instalar esta aplicación? No requiere accesos especiales."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"¿Deseas instalar una actualización para esta aplicación? Tus datos no se perderán. La aplicación actualizada tendrá acceso a lo siguiente:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"¿Deseas instalar una actualización para esta aplicación integrada? Tus datos no se perderán. La aplicación actualizada tendrá acceso a lo siguiente:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"¿Quieres instalar una actualización de esta aplicación existente? Los datos existentes no se perderán. No se requiere ningún acceso especial."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"¿Quieres instalar una actualización de esta aplicación integrada? Los datos existentes no se perderán. No se requiere ningún acceso especial."</string>
-    <string name="install_failed" msgid="6579998651498970899">"No se instaló la aplicación."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Se bloqueó el paquete para impedir la instalación."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"No se instaló la app ya que está en conflicto con un paquete existente."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"No se instaló la app porque no es compatible con tu tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Esta app no es compatible con la TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"No se instaló la app porque no es compatible con tu teléfono."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"No se instaló la app porque parece que el paquete no es válido."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en tu tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en la TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en tu dispositivo."</string>
-    <string name="launch" msgid="4826921505917605463">"Abrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Tu administrador no permite la instalación de apps que se obtuvieron de fuentes desconocidas"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Este usuario no puede instalar apps desconocidas"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuario no puede instalar apps"</string>
-    <string name="ok" msgid="3468756155452870475">"Aceptar"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Administrar aplicaciones"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sin espacio"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espacio y vuelve a intentarlo."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"No se encontró la aplicación."</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"La aplicación no se encontró en la lista de aplicaciones instaladas."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"No tiene permiso"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"El usuario actual no tiene permiso para llevar a cabo esta desinstalación."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"No se pudo desinstalar la app."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar la aplicación"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar la actualización"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> es parte de la siguiente aplicación:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"¿Deseas desinstalar esta aplicación?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"¿Quieres desinstalar esta aplicación para "<b>"todos"</b>" los usuarios? La aplicación y sus datos se eliminarán de "<b>"todos"</b>" los usuarios del dispositivo."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"¿Deseas desinstalar esta aplicación para el usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos. Esta acción afectará a todos los usuarios de este dispositivo, incluidos los que poseen perfiles de trabajo."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desinstalaciones activas"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Desinstalaciones con errores"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Desinstalando…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"La desinstalación finalizó."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Se desinstaló <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Desinstalación incorrecta"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"No se pudo desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"No se puede desinstalar la app de administración activa del dispositivo"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"No se puede desinstalar la app de administración activa del dispositivo para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"App necesaria en algunos usuarios o perfiles, y desinstalada en otros"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Esta app es necesaria en tu perfil y no la puedes desinstalar."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"El admin. del dispositivo necesita esta aplicación y no se puede desinstalar."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Administrar apps del dispositivo del administrador"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Administrar usuarios"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"No se pudo desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Se produjo un error durante el análisis del paquete."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nuevo"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Todo"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacidad"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Acceso al dispositivo"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Esta actualización no requiere permisos nuevos."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Rechazar"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Más información"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Denegar de todos modos"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"¿Quieres que la app de &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; realice la siguiente acción: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"¿Permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pueda <xliff:g id="ACTION">%2$s</xliff:g> siempre?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Solo cuando se usa la app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Siempre"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Denegar el permiso y no volver a preguntar"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> inhabilitados"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"todos inhabilitados"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ninguno inhabilitado"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicaciones"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Permisos de apps"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"No volver a preguntar"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Sin permisos"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Permisos adicionales"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir información de la app"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> más</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> más</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Esta aplicación se diseñó para una versión de Android anterior. Si deniegas el permiso, es posible que deje de funcionar de la forma prevista."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"realizar una acción desconocida"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Se otorgó el permiso a <xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicaciones."</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Ninguna aplicación"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Configuración de la ubicación"</string>
-    <string name="location_warning" msgid="8778701356292735971">"La aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> provee servicios de ubicación a este dispositivo. El acceso a la ubicación puede modificarse desde la configuración de la ubicación."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Si no concedes este permiso, es posible que algunas funciones básicas del dispositivo dejen de funcionar correctamente."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Se aplica en función de la política"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acceso en segundo plano inhabilitado por la política"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acceso en segundo plano habilitado por la política"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acceso en primer plano habilitado por la política"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlado por el administrador"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Siempre"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Solo cuando se usa la app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
-    <string name="loading" msgid="7811651799620593731">"Cargando…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Todos los permisos"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Otras funciones de la aplicación"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Solicitud de permiso"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Se detectó una superposición de pantalla"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Para cambiar esta configuración de permisos, primero debes desactivar la superposición de pantalla en Configuración &gt; Aplicaciones"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir configuración"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear no admite las acciones de instalación y desinstalación"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Selecciona los permisos de acceso para &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Se actualizó &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;. Selecciona los permisos de acceso para esta app."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Permisos nuevos"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Permisos actuales"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Preparando app…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Desconocido"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Por tu seguridad, tu tablet no tiene permitido instalar apps desconocidas de esta fuente."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Por tu seguridad, tu TV no tiene permitido instalar apps desconocidas de esta fuente."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Por tu seguridad, tu teléfono no tiene permitido instalar apps desconocidas de esta fuente."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Tu teléfono y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra tu teléfono y la pérdida de datos que pueda ocasionar su uso."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tu tablet y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra tu tablet y la pérdida de datos que pueda ocasionar su uso."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tu TV y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra tu TV y la pérdida de datos que pueda ocasionar su uso."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Configuración"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps para Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instalador del paquete"</string>
+    <string name="install" msgid="711829760615509273">"Instalar"</string>
+    <string name="done" msgid="6632441120016885253">"Listo"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancelar"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalando…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Se instaló la app."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"¿Deseas instalar esta aplicación?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"¿Quieres instalar una actualización de esta app? No se perderán los datos."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"¿Quieres instalar una actualización de esta app integrada? No se perderán los datos."</string>
+    <string name="install_failed" msgid="5777824004474125469">"No se instaló la app."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Se bloqueó el paquete para impedir la instalación."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"No se instaló la app debido a un conflicto con un paquete."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"No se instaló la app porque no es compatible con la tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Esta app no es compatible con la TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"No se instaló la app porque no es compatible con el teléfono."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"No se instaló la app porque parece que el paquete no es válido."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en la tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en la TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en el teléfono."</string>
+    <string name="launch" msgid="3952550563999890101">"Abrir"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"El administrador no permite instalar apps de fuentes desconocidas"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este usuario no puede instalar apps desconocidas"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuario no puede instalar apps"</string>
+    <string name="ok" msgid="7871959885003339302">"Aceptar"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gestionar apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sin espacio"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"No se pudo instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espacio y vuelve a intentarlo."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"No se encontró la app"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"La app no está en la lista de apps instaladas."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"No permitida"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"El usuario actual no tiene permiso para llevar a cabo esta desinstalación."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"No se pudo desinstalar la app."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalar app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar actualización"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> es parte de la siguiente app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"¿Quieres desinstalar esta app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"¿Quieres desinstalar esta app para "<b>"todos"</b>" los usuarios? Se quitarán la aplicación y sus datos de "<b>"todos"</b>" los usuarios del dispositivo."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"¿Quieres desinstalar esta app para el usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos. Esta acción afectará a todos los usuarios de este dispositivo, incluidos los que tengan perfiles de trabajo."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalaciones activas"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalaciones con errores"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Se completó la desinstalación."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Se desinstaló <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"No se pudo completar la desinstalación."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"No se pudo desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"No se puede desinstalar la app de administración activa del dispositivo"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"No se puede desinstalar la app de administración activa del dispositivo para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Esta app es necesaria para algunos usuarios o perfiles, y se desinstaló en otros casos"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"No se puede desinstalar esta app porque es necesaria en tu perfil."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"El administrador del dispositivo necesita esta app y no se puede desinstalar."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gestionar apps de administración de dispositivos"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Administrar usuarios"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"No se pudo desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Se produjo un error durante el análisis del paquete."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear no admite las acciones de instalación y desinstalación"</string>
+    <string name="message_staging" msgid="8032722385658438567">"Preparando app…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Desconocido"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Por tu seguridad, la tablet no tiene permitido instalar apps desconocidas de esta fuente."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Por tu seguridad, la TV no tiene permitido instalar apps desconocidas de esta fuente."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Por tu seguridad, el teléfono no tiene permitido instalar apps desconocidas de esta fuente."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"El teléfono y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra el teléfono y de la pérdida de datos que pueda ocasionar su uso."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"La tablet y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra la tablet y de la pérdida de datos que pueda ocasionar su uso."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"La TV y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra la TV y de la pérdida de datos que pueda ocasionar su uso."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuar"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Configuración"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalando/desinstalando apps para Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-es/strings.xml b/packages/PackageInstaller/res/values-es/strings.xml
index bffaa0f..26203b0 100644
--- a/packages/PackageInstaller/res/values-es/strings.xml
+++ b/packages/PackageInstaller/res/values-es/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Instalador de paquetes"</string>
-    <string name="next" msgid="3057143178373252333">"Siguiente"</string>
-    <string name="install" msgid="5896438203900042068">"Instalar"</string>
-    <string name="done" msgid="3889387558374211719">"Listo"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
-    <string name="installing" msgid="8613631001631998372">"Instalando…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplicación instalada"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"¿Quieres instalar esta aplicación? Tendrá los siguientes permisos:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"¿Quieres instalar esta aplicación? No requiere accesos especiales."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"¿Quieres instalar una actualización de la aplicación? Tus datos no se perderán. La aplicación actualizada podrá acceder a:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"¿Quieres instalar una actualización de esta aplicación integrada? Tus datos no se perderán. La aplicación actualizada podrá acceder a:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"¿Quieres instalar una actualización de esta aplicación? Tus datos no se perderán. No requiere ningún acceso especial."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"¿Quieres instalar una actualización de esta aplicación integrada? Tus datos no se perderán. No requiere ningún acceso especial."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplicación no instalada"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Se ha bloqueado la instalación del paquete."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"La aplicación no se ha instalado debido a un conflicto con un paquete actual."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"La aplicación no se ha instalado porque no es compatible con tu tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Esta aplicación no es compatible con tu TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"La aplicación no se ha instalado porque no es compatible con tu teléfono."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"La aplicación no se ha instalado porque parece que el paquete no es válido."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en el tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> no se ha podido instalar en tu TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en el teléfono."</string>
-    <string name="launch" msgid="4826921505917605463">"Abrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"El administrador no permite instalar aplicaciones de fuentes desconocidas"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Este usuario no puede instalar aplicaciones desconocidas"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuario no tiene permiso para instalar aplicaciones"</string>
-    <string name="ok" msgid="3468756155452870475">"Aceptar"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Administrar aplicaciones"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sin espacio"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"No se ha podido instalar la aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espacio y vuelve a intentarlo."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplicación no encontrada"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"No se ha encontrado la aplicación en la lista de aplicaciones instaladas."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"No permitido"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"El usuario actual no puede iniciar el proceso de desinstalación."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"No se ha podido desinstalar la aplicación."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar aplicación"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar actualización"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma parte de esta aplicación:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"¿Quieres desinstalar esta aplicación?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"¿Quieres desinstalar esta aplicación para "<b>"todos"</b>" los usuarios? La aplicación y sus datos se eliminarán de "<b>"todos"</b>" los usuarios del dispositivo."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"¿Quieres desinstalar esta aplicación para el usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"¿Quieres sustituir esta aplicación con la versión de fábrica? Ten en cuenta que se eliminarán todos los datos."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"¿Quieres sustituir esta aplicación con la versión de fábrica? Ten en cuenta que se eliminarán todos los datos. Esto afecta a todos los usuarios del dispositivo, incluidos los que tienen perfiles de trabajo."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desinstalaciones en curso"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Desinstalaciones fallidas"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Desinstalando..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Desinstalación completada"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Se ha desinstalado <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Desinstalación correcta"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"No se ha podido desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"No se puede desinstalar la aplicación de administración de dispositivos activa"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"No se ha podido desinstalar la aplicación de administración de dispositivos activa de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Aplicación necesaria para algunos usuarios o perfiles y desinstalada en otros casos"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Esta aplicación es necesaria para tu perfil y no se puede desinstalar."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Esta aplicación es necesaria para el administrador de tu dispositivo y no se puede desinstalar."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gestionar aplicaciones de admón. de dispositivos"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Administrar usuarios"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"No se ha podido desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Se ha producido un error al analizar el paquete."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nuevo"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Todos"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacidad"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Acceso al dispositivo"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Esta actualización no requiere permisos nuevos."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Denegar"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Más información"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Denegar de todos modos"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"¿Permitir a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"¿Quieres permitir siempre que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Solo mientras se usa la aplicación"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Siempre"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Denegar y no volver a preguntar"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Inhabilitados: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"todos inhabilitados"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ninguno inhabilitado"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicaciones"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Permisos de aplicaciones"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"No volver a preguntar"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Sin permisos"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Permisos adicionales"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir la información de la aplicación"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> más</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> más</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Esta aplicación está diseñada para una versión anterior de Android. Si se le deniega el permiso, puede dejar de funcionar de la forma prevista."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"realizar una acción desconocida"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicaciones permitidas"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Mostrar aplicaciones del sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar aplicaciones del sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"No hay aplicaciones"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Ajustes de ubicación"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> es un proveedor de servicios de ubicación de este dispositivo. El acceso a la ubicación se puede modificar en los ajustes de ubicación."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Si rechazas este permiso, es posible que funciones básicas de tu dispositivo dejen de funcionar correctamente."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicado por política"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acceso en segundo plano inhabilitado por política"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acceso en segundo plano habilitado por política"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acceso en primer plano habilitado por política"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlado por el administrador"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Siempre"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Solo mientras se usa la app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
-    <string name="loading" msgid="7811651799620593731">"Cargando..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Todos los permisos"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Otras funciones de la aplicación"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Solicitud de permiso"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Superposición de pantalla detectada"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Para cambiar la configuración de este permiso, desactiva la superposición de pantalla en Ajustes &gt; Aplicaciones"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir ajustes"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Las acciones de instalar y desinstalar no pueden realizarse en Wear"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Elige los permisos de acceso que quieres conceder a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; se ha actualizado. Elige los permisos de acceso que quieres conceder a esta aplicación."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Permisos nuevos"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Permisos actuales"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Preparando aplicación…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Desconocido"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Por motivos de seguridad, tu tablet no puede instalar aplicaciones desconocidas de esta fuente."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Por motivos de seguridad, tu TV no puede instalar aplicaciones desconocidas de esta fuente."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Por motivos de seguridad, tu teléfono no puede instalar aplicaciones desconocidas de esta fuente."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Tu teléfono y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu teléfono o la pérdida de datos que se pueda derivar de su uso."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tu tablet y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu tablet o la pérdida de datos que se pueda derivar de su uso."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tu TV y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu TV o la pérdida de datos que se pueda derivar de su uso."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Ajustes"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps para Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instalador de paquetes"</string>
+    <string name="install" msgid="711829760615509273">"Instalar"</string>
+    <string name="done" msgid="6632441120016885253">"Listo"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancelar"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalando…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Se ha instalado la aplicación."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"¿Quieres instalar esta aplicación?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"¿Quieres instalar una actualización de esta aplicación? Tus datos no se perderán."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"¿Quieres instalar una actualización de esta aplicación integrada? Tus datos no se perderán."</string>
+    <string name="install_failed" msgid="5777824004474125469">"No se ha instalado la aplicación."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Se ha bloqueado la instalación del paquete."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"La aplicación no se ha instalado debido a un conflicto con un paquete."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"La aplicación no se ha instalado porque no es compatible con tu tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Esta aplicación no es compatible con tu TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"La aplicación no se ha instalado porque no es compatible con tu teléfono."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"La aplicación no se ha instalado porque parece que el paquete no es válido."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en tu tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en tu TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> en tu teléfono."</string>
+    <string name="launch" msgid="3952550563999890101">"Abrir"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"El administrador no permite instalar aplicaciones de fuentes desconocidas"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este usuario no puede instalar aplicaciones desconocidas"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuario no tiene permiso para instalar aplicaciones"</string>
+    <string name="ok" msgid="7871959885003339302">"Aceptar"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gestionar aplicaciones"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sin espacio"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"No se ha podido instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espacio y vuelve a intentarlo."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplicación no encontrada"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"No se ha encontrado la aplicación en la lista de aplicaciones instaladas."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"No permitida"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"El usuario actual no puede iniciar el proceso de desinstalación."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"No se ha podido desinstalar la aplicación."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalar aplicación"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar actualización"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma parte de esta aplicación:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"¿Quieres desinstalar esta aplicación?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"¿Quieres desinstalar esta aplicación para "<b>"todos"</b>" los usuarios? La aplicación y sus datos se borrarán de "<b>"todos"</b>" los usuarios del dispositivo."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"¿Quieres desinstalar esta aplicación para el usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"¿Quieres sustituir esta aplicación con la versión de fábrica? Ten en cuenta que se borrarán todos los datos."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"¿Quieres sustituir esta aplicación con la versión de fábrica? Ten en cuenta que se borrarán todos los datos. Esto afecta a todos los usuarios del dispositivo, incluidos los que tienen perfiles de trabajo."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalaciones en curso"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalaciones fallidas"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Se ha completado la desinstalación."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Se ha desinstalado <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"No se ha podido completar la desinstalación."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"No se ha podido desinstalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"No se puede desinstalar la aplicación de administración de dispositivos activa"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"No se ha podido desinstalar la aplicación de administración de dispositivos activa de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Esta aplicación es necesaria para algunos usuarios o perfiles y se ha desinstalado en otros casos"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Esta aplicación es necesaria para tu perfil y no se puede desinstalar."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Esta aplicación es necesaria para el administrador y no se puede desinstalar."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gestionar apps de administración de dispositivos"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gestionar usuarios"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"No se ha podido desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"No se ha podido analizar el paquete."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Las acciones de instalar y desinstalar no pueden realizarse en Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Preparando aplicación…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Desconocida"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Por motivos de seguridad, tu tablet no puede instalar aplicaciones desconocidas de esta fuente."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Por motivos de seguridad, tu TV no puede instalar aplicaciones desconocidas de esta fuente."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Por motivos de seguridad, tu teléfono no puede instalar aplicaciones desconocidas de esta fuente."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Tu teléfono y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu teléfono o la pérdida de datos que se pueda derivar de su uso."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tu tablet y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu tablet o la pérdida de datos que se pueda derivar de su uso."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Tu TV y tus datos personales son más vulnerables a los ataques de aplicaciones desconocidas. Al instalar esta aplicación, aceptas ser responsable de cualquier daño que sufra tu TV o la pérdida de datos que se pueda derivar de su uso."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuar"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Ajustes"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalando/desinstalando apps para Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-et/strings.xml b/packages/PackageInstaller/res/values-et/strings.xml
index 1754411..cf9dd56 100644
--- a/packages/PackageInstaller/res/values-et/strings.xml
+++ b/packages/PackageInstaller/res/values-et/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Paketiinstaller"</string>
-    <string name="next" msgid="3057143178373252333">"Järgmine"</string>
-    <string name="install" msgid="5896438203900042068">"Installi"</string>
-    <string name="done" msgid="3889387558374211719">"Valmis"</string>
-    <string name="cancel" msgid="8360346460165114585">"Tühista"</string>
-    <string name="installing" msgid="8613631001631998372">"Installimine ..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Paketi <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installimine …"</string>
-    <string name="install_done" msgid="3682715442154357097">"Rakendus on installitud."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Kas soovite rakenduse installida? See pääseb järgmiste üksuste juurde:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Kas soovite rakenduse installida? See ei nõua spetsiaalseid juurdepääsuõigusi."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Kas soovite olemasoleva rakenduse värskenduse installida? Teie olemasolevad andmed jäävad alles. Värskendatud rakendus pääseb järgmiste funktsioonide juurde:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Kas soovite sisseehitatud rakenduse värskenduse installida? Teie olemasolevad andmed jäävad alles. Värskendatud rakendus pääseb järgmiste funktsioonide juurde:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Kas soovite installida olemasoleva rakenduse värskenduse? Olemasolevad andmed ei lähe kaduma. See ei nõua erijuurdepääsu."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Kas soovite installida sisseehitatud rakenduse värskenduse? Olemasolevad andmed ei lähe kaduma. See ei nõua erijuurdepääsu."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Rakendus pole installitud."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Paketi installimine blokeeriti."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Rakendust ei installitud, kuna pakett on olemasoleva paketiga vastuolus."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Rakendust ei installitud, kuna rakendus ei ühildu teie tahvelarvutiga."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Rakendus ei ühildu teie teleriga."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Rakendust ei installitud, kuna rakendus ei ühildu teie telefoniga."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Rakendust ei installitud, kuna pakett näib olevat sobimatu."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saa teie tahvelarvutisse installida."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saa teie telerisse installida."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saa teie telefoni installida."</string>
-    <string name="launch" msgid="4826921505917605463">"Ava"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administraator ei luba installida tundmatutest allikatest pärinevaid rakendusi"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"See kasutaja ei saa installida tundmatuid rakendusi"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Kasutajal ei ole lubatud rakendusi installida"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Rakenduste haldamine"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Pole ruumi"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saa installida. Vabastage mälu ja proovige uuesti."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Rakendust ei leitud"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Rakendust ei leitud installitud rakenduste loendist."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ei ole lubatud"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Praegusel kasutajal ei ole lubatud seda desinstallimist teha."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Viga"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Rakendust ei saanud desinstallida."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Rakenduse desinstallimine"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Värskenduse desinstallimine"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> on osa järgmisest rakendusest:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Kas soovite selle rakenduse desinstallida?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Kas soovite desinstallida selle rakenduse "<b>"kõikidelt"</b>" kasutajatelt? Rakendus ja selle andmed eemaldatakse "<b>"kõikidelt"</b>" seadme kasutajatelt."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Kas soovite kasutaja <xliff:g id="USERNAME">%1$s</xliff:g> puhul rakenduse desinstallida?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Kas asendada see rakendus tehaseversiooniga? Kõik andmed eemaldatakse."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Kas asendada see rakendus tehaseversiooniga? Kõik andmed eemaldatakse. See mõjutab kõiki seadme kasutajaid, sh neid, kellel on tööprofiilid."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Käimasolevad desinstallimised"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Ebaõnnestunud desinstallimised"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Desinstallimine ..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine …"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Desinstallimine on lõpetatud."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Üksus <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on desinstallitud"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Desinstallimine ebaõnnestus."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine ebaõnnestus."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktiivset seadme administraatori rakendust ei saa desinstallida"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Kasutaja <xliff:g id="USERNAME">%1$s</xliff:g> puhul ei saa aktiivset seadme administraatori rakendust desinstallida"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Rakendus on mõne kasutaja ja profiili puhul vajalik, teiste puhul see desinstalliti"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"See rakendus on vajalik teie profiili jaoks ja seda ei saa desinstallida."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Seadme administraator vajab seda rakendust ja seda ei saa desinstallida."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Halda seadme administraatori rakendusi"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Halda kasutajaid"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saanud desinstallida."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Probleem paketi sõelumisel."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Uus"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Kõik"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privaatsus"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Seadme juurdepääs"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"See värskendus ei nõua uusi lube."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Keela"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Lisateave"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Keela ikkagi"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>-st"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Kas lubada rakendusel &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Kas lubada rakenduse puhul &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; alati toiming <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Ainult rakenduse kasutamise ajal"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Alati"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Keela ja ära enam küsi"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> on keelatud"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"kõik on keelatud"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"mitte ükski pole keelatud"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Luba"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Rakendused"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Rakenduste load"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ära enam küsi"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Lube ei ole"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Täiendavad load"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ava rakenduse teave"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Veel <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Veel <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Rakendus on mõeldud Androidi vanemale versioonile. Kui keeldute loa andmisest, ei pruugi see ootuspäraselt töötada."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"tundmatu toiming"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> rakendust <xliff:g id="COUNT_1">%2$d</xliff:g>-st on lubatud"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Kuva süsteem"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Peida süsteem"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Rakendusi pole"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Asukohaseaded"</string>
-    <string name="location_warning" msgid="8778701356292735971">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> on selle seadme asukohateenuste pakkuja. Asukoha juurdepääsu saab muuta asukohaseadetes."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Kui keelate loa, ei pruugi seadme põhifunktsioonid enam ootuspäraselt töötada."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Eeskirjadega jõustatud"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Reegli alusel on taustale juurdepääs keelatud"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Reegli alusel on taustale juurdepääs lubatud"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Reegli alusel on esiplaanile juurdepääs lubatud"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Juhib administraator"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Alati"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Ainult rakenduse kasutamisel"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Mitte kunagi"</string>
-    <string name="loading" msgid="7811651799620593731">"Laadimine ..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Kõik load"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Rakenduse muud funktsioonid"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Loa taotlus"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Tuvastati ekraani ülekate"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Selle loa seade muutmiseks peate esmalt välja lülitama ekraani ülekatte menüüs Seaded &gt; Rakendused"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Ava seaded"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ei toeta installimist/desinstallimist."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Valige, millele lubate rakendusel &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; juurde pääseda"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Rakendust &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; värskendati. Valige, millele lubate sellel rakendusel juurde pääseda."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Tühista"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Jätka"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Uued load"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Praegused load"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Rakenduse ettevalmistamine …"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Tundmatu"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Teie turvalisuse huvides ei ole tahvelarvutil lubatud installida sellest allikast tundmatuid rakendusi."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Teie turvalisuse huvides ei ole TV-l lubatud installida sellest allikast tundmatuid rakendusi."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Teie turvalisuse huvides ei ole telefonil lubatud installida sellest allikast tundmatuid rakendusi."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Teie telefon ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate telefoni kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Teie tahvelarvuti ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate tahvelarvuti kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Teie teler ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate teleri kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Jätka"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Seaded"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Weari rak. installimine/desinstallimine"</string>
+    <string name="app_name" msgid="7488448184431507488">"Paketi installiprogramm"</string>
+    <string name="install" msgid="711829760615509273">"Installi"</string>
+    <string name="done" msgid="6632441120016885253">"Valmis"</string>
+    <string name="cancel" msgid="1018267193425558088">"Tühista"</string>
+    <string name="installing" msgid="4921993079741206516">"Installimine …"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Paketi <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installimine …"</string>
+    <string name="install_done" msgid="5987363587661783896">"Rakendus on installitud."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Kas soovite selle rakenduse installida?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Kas soovite olemasoleva rakenduse värskenduse installida? Teie olemasolevad andmed jäävad alles."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Kas soovite sisseehitatud rakenduse värskenduse installida? Teie olemasolevad andmed jäävad alles."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Rakendus pole installitud."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paketi installimine blokeeriti."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Rakendust ei installitud, kuna pakett on olemasoleva paketiga vastuolus."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Rakendust ei installitud, kuna rakendus ei ühildu teie tahvelarvutiga."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Rakendus ei ühildu teie teleriga."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Rakendust ei installitud, kuna rakendus ei ühildu teie telefoniga."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Rakendust ei installitud, kuna pakett näib olevat sobimatu."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saanud teie tahvelarvutisse installida."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saanud teie telerisse installida."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saanud teie telefoni installida."</string>
+    <string name="launch" msgid="3952550563999890101">"Ava"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administraator ei luba installida tundmatutest allikatest pärinevaid rakendusi"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"See kasutaja ei saa installida tundmatuid rakendusi"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Kasutajal ei ole lubatud rakendusi installida"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Rakend. haldam."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Pole ruumi"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saanud installida. Vabastage ruumi ja proovige uuesti."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Rakendust ei leitud"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Rakendust installitud rakenduste loendist ei leitud."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Pole lubatud"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Praegusel kasutajal ei ole lubatud seda desinstallimist teha."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Viga"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Rakendust ei saanud desinstallida."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalli rakendus"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Värskenduse desinstallimine"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> on osa järgmisest rakendusest:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Kas soovite selle rakenduse desinstallida?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Kas soovite selle rakenduse "<b>"kõikide"</b>" kasutajate kontodelt desinstallida? Rakendus ja selle andmed eemaldatakse "<b>"kõikide"</b>" seadme kasutajate kontodelt."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Kas soovite selle rakenduse kasutaja <xliff:g id="USERNAME">%1$s</xliff:g> kontolt desinstallida?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Kas asendada see rakendus tehaseversiooniga? Kõik andmed eemaldatakse."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Kas asendada see rakendus tehaseversiooniga? Kõik andmed eemaldatakse. See mõjutab kõiki seadme kasutajaid, sh neid, kellel on tööprofiilid."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Käimasolevad desinstallimised"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ebaõnnestunud desinstallimised"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Desinstallimine …"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Paketi <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine …"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Desinstallimine on lõpetatud."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Üksus <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on desinstallitud"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Desinstallimine ebaõnnestus."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstallimine ebaõnnestus."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktiivset seadme administraatori rakendust ei saa desinstallida"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Kasutaja <xliff:g id="USERNAME">%1$s</xliff:g> puhul ei saa aktiivset seadme administraatori rakendust desinstallida"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Rakendus on mõne kasutaja või profiili puhul vajalik, teiste puhul see desinstalliti."</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"See rakendus on vajalik teie profiili jaoks ja seda ei saa desinstallida."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Seadme administraator vajab seda rakendust ja seda ei saa desinstallida."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Halda seadme administraatori rakendusi"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Halda kasutajaid"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Rakendust <xliff:g id="APP_NAME">%1$s</xliff:g> ei saanud desinstallida."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Probleem paketi sõelumisel."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear ei toeta installimist/desinstallimist."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Rakenduse koondamine …"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Teadmata"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Teie turvalisuse huvides ei ole tahvelarvutil lubatud installida sellest allikast tundmatuid rakendusi."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Teie turvalisuse huvides ei ole teleril lubatud installida sellest allikast tundmatuid rakendusi."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Teie turvalisuse huvides ei ole telefonil lubatud installida sellest allikast tundmatuid rakendusi."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Teie telefon ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate telefoni kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Teie tahvelarvuti ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate tahvelarvuti kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Teie teler ja isiklikud andmed on tundmatute rakenduste rünnakute suhtes haavatavamad. Selle rakenduse installimisel nõustute, et vastutate teleri kahjude ja andmekao eest, mis võivad tuleneda selliste rakenduste kasutamisest."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Jätka"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Seaded"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Weari rak. installimine/desinstallimine"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index 0cb7e4c..a73a99c 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Pakete-instalatzailea"</string>
-    <string name="next" msgid="3057143178373252333">"Hurrengoa"</string>
-    <string name="install" msgid="5896438203900042068">"Instalatu"</string>
-    <string name="done" msgid="3889387558374211719">"Eginda"</string>
-    <string name="cancel" msgid="8360346460165114585">"Utzi"</string>
-    <string name="installing" msgid="8613631001631998372">"Instalatzen…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> instalatzen…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikazioa instalatu da."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Aplikazioa instalatu nahi duzu? Elementu hauetarako sarbidea izango du:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Aplikazioa instalatu nahi duzu? Ez du sarbide berezirik behar."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Aplikazioaren eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko. Eguneratutako aplikazioak elementu hauetarako sarbidea izango du:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Aplikazio integratu honen eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko. Eguneratutako aplikazioak elementu hauetarako sarbidea izango du:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Aplikazioaren eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko. Ez du sarbide berezirik behar."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Aplikazio integratu honen eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko. Ez du sarbide berezirik behar."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Ez da aplikazioa instalatu."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Blokeatu egin da paketea instalatzeko aukera."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Ez da instalatu aplikazioa, gatazka bat sortu delako lehendik dagoen pakete batekin."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Ez da instalatu aplikazioa, ez delako tabletarekin bateragarria."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aplikazioa ez da telebistarekin bateragarria."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Ez da instalatu aplikazioa, ez delako telefonoarekin bateragarria."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Ez da instalatu aplikazioa, paketeak ez duelako balio."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Ezin izan da <xliff:g id="APP_NAME">%1$s</xliff:g> tabletan instalatu."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Ezin izan da instalatu <xliff:g id="APP_NAME">%1$s</xliff:g> telebistan."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Ezin izan da <xliff:g id="APP_NAME">%1$s</xliff:g> telefonoan instalatu."</string>
-    <string name="launch" msgid="4826921505917605463">"Ireki"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratzaileak ez du onartzen iturburu ezezagunetako aplikazioak instalatzea"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Erabiltzaile honek ezin ditu instalatu aplikazio ezezagunak"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Erabiltzaile honek ez du baimenik aplikazioak instalatzeko"</string>
-    <string name="ok" msgid="3468756155452870475">"Ados"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Kudeatu aplikazioak"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Ez dago behar adina toki"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Ezin izan da <xliff:g id="APP_NAME">%1$s</xliff:g> instalatu. Egin toki pixka bat eta saiatu berriro."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Ez da aplikazioa aurkitu"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikazioa ez da aurkitu instalatutako aplikazioen zerrendan."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ez dauka baimenik"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Erabiltzaile honek ez dauka desinstalatzeko baimenik."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Errorea"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Ezin izan da desinstalatu aplikazioa."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalatu aplikazioa"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalatu eguneratzea"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> aplikazio honen zati da:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Aplikazioa desinstalatu nahi duzu?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Aplikazioa erabiltzaile "<b>"guztientzat"</b>" desinstalatu nahi duzu? Aplikazioa eta bere datu guztiak gailuko erabiltzaile "<b>"guztiei"</b>" ezabatuko zaizkie."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> erabiltzailearen aplikazioa desinstalatu nahi duzu?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Aplikazio hau jatorrizko bertsioarekin ordeztu nahi duzu? Datu guztiak ezabatuko dira."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Aplikazio hau jatorrizko bertsioarekin ordeztu nahi duzu? Datu guztiak ezabatuko dira. Gailuaren erabiltzaile guztiengan izango du eragina, laneko profilak dituztenengan barne."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Abian diren desinstalatze-eragiketak"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Huts egin duten desinstalatze-eragiketak"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Desinstalatzen…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalatzen…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Desinstalatu da."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Desinstalatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Ezin izan da desinstalatu."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Ezin izan da desinstalatu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Ezin da desinstalatu gailua administratzeko aplikazio aktiboa"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Ezin da desinstalatu <xliff:g id="USERNAME">%1$s</xliff:g> erabiltzailearen gailua administratzeko aplikazio aktiboa"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Erabiltzaile edo profil batzuek behar dute aplikazio hau, baina desinstalatu egin da beste guztientzat."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Zure profilak behar du aplikazio hau eta ezin da desinstalatu."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Gailuaren administratzaileak aplikazio hori behar du eta ezin da desinstalatu."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Kudeatu gailua administratzeko aplikazioak"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Kudeatu erabiltzaileak"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Ezin izan da <xliff:g id="APP_NAME">%1$s</xliff:g> desinstalatu."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Arazo bat izan da paketea analizatzean."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Berriak"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Guztiak"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Pribatutasuna"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Gailurako sarbidea"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Eguneratze honek ez du baimen berririk behar."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Ukatu"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Informazio gehiago"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Ukatu hala ere"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari \"<xliff:g id="ACTION">%2$s</xliff:g>\" izeneko baimena eman nahi diozu?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Beti eman nahi diozu \"<xliff:g id="ACTION">%2$s</xliff:g>\" baimena &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioari?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Aplikazioa erabiltzean soilik"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Beti"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Baztertu eta ez galdetu berriro"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desgaituta"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"guztiak desgaituta"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"guztiak gaituta"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Baimendu"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikazioak"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Aplikazio-baimenak"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ez galdetu berriro"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Ez dago baimenik"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Baimen gehigarriak"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ireki aplikazioaren informazioa"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> gehiago</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> gehiago</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Aplikazio hau Android-en bertsio zaharrago baterako diseinatuta dago. Baimena ukatzen baduzu, agian aurrerantzean ez du behar bezain ondo funtzionatuko."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"Gauzatu ekintza ezezagunak"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> aplikaziok dute baimena"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Erakutsi sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ezkutatu sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Ez dago aplikaziorik"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Kokapen-ezarpenak"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> gailu honen kokapen-zerbitzuen hornitzailea da. Kokapenerako sarbidea kokapen-ezarpenetatik alda daiteke."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Baimena ematen ez baduzu, baliteke gailuaren oinarrizko eginbide batzuek behar bezala ez funtzionatzea."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Gidalerroen bidez aplikatzen da"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Gidalerro batek eskatuta, atzeko planoa atzitzeko aukera desgaitu da"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Gidalerro batek eskatuta, atzeko planoa atzitzeko aukera gaitu da"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Gidalerro batek eskatuta, aurreko planoa atzitzeko aukera gaitu da"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Administratzaileak kontrolatzen du"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Beti"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Aplikazioa erabiltzean soilik"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Inoiz ez"</string>
-    <string name="loading" msgid="7811651799620593731">"Kargatzen…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Baimen guztiak"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Aplikazioaren beste gaitasun batzuk"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Baimen-eskaera"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Pantailaren gainjartzea detektatu da"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Baimen-ezarpen hau aldatzeko, pantailaren gainjartzea desaktibatu behar duzu Ezarpenak &gt; Aplikazioak atalean"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Ireki ezarpenak"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Instalatzeko eta desinstalatzeko ekintzak ezin dira gauzatu Wear gailuetan."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Aukeratu zer atzi dezakeen &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aplikazioak"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Eguneratu egin da &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;. Aukeratu aplikazioak zer atzi dezakeen."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Utzi"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Jarraitu"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Baimen berriak"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Uneko baimenak"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Aplikazioa prestatzen…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Ezezaguna"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Segurtasuna bermatzeko, tableta honetan ezin dira instalatu iturburu honetako aplikazio ezezagunak."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Segurtasuna bermatzeko, telebista honetan ezin dira instalatu iturburu honetako aplikazio ezezagunak."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Segurtasuna bermatzeko, telefono honetan ezin dira instalatu iturburu honetako aplikazio ezezagunak."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartzen duzu hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea zeu zarela."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartzen duzu hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea zeu zarela."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Iturburu honetako aplikazioak instalatzen badituzu, onartzen duzu haiek erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea zeu zarela."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Egin aurrera"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Ezarpenak"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear aplikazioak instalatzea/desinstalatzea"</string>
+    <string name="app_name" msgid="7488448184431507488">"Pakete-instalatzailea"</string>
+    <string name="install" msgid="711829760615509273">"Instalatu"</string>
+    <string name="done" msgid="6632441120016885253">"Eginda"</string>
+    <string name="cancel" msgid="1018267193425558088">"Utzi"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalatzen…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> instalatzen…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Instalatu da aplikazioa."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Aplikazio hau instalatu nahi duzu?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Aplikazioaren eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Aplikazio integratu honen eguneratzea instalatu nahi duzu? Lehendik dauden datuak ez dira galduko."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Ez da instalatu aplikazioa."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paketea instalatzeko aukera blokeatu egin da."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Ez da instalatu aplikazioa, gatazka bat sortu delako lehendik dagoen pakete batekin."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Ez da instalatu aplikazioa, ez delako bateragarria tabletarekin."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Aplikazioa ez da bateragarria telebistarekin."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Ez da instalatu aplikazioa, ez delako bateragarria telefonoarekin."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Ez da instalatu aplikazioa, paketeak ez duelako balio."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Ezin izan da instalatu <xliff:g id="APP_NAME">%1$s</xliff:g> tabletan."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Ezin izan da instalatu <xliff:g id="APP_NAME">%1$s</xliff:g> telebistan."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Ezin izan da instalatu <xliff:g id="APP_NAME">%1$s</xliff:g> telefonoan."</string>
+    <string name="launch" msgid="3952550563999890101">"Ireki"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administratzaileak ez du onartzen iturburu ezezagunetako aplikazioak instalatzea"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Erabiltzaile honek ezin ditu instalatu aplikazio ezezagunak"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Erabiltzaile honek ez du baimenik aplikazioak instalatzeko"</string>
+    <string name="ok" msgid="7871959885003339302">"Ados"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Kudeatu aplikazioak"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Ez dago behar adina toki"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Ezin izan da instalatu <xliff:g id="APP_NAME">%1$s</xliff:g>. Egin toki pixka bat eta saiatu berriro."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Ez da aurkitu aplikazioa"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Ez da aurkitu aplikazioa instalatutako aplikazioen zerrendan."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Ez du baimenik"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Erabiltzaile honek ez dauka desinstalatzeko baimenik."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Errorea"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Ezin izan da desinstalatu aplikazioa."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalatu aplikazioa"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalatu eguneratzea"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> aplikazio honen zati da:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Aplikazioa desinstalatu nahi duzu?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Erabiltzaile "<b>"guztiei"</b>" desinstalatu nahi diezu aplikazioa? Aplikazioa eta bere datu guztiak ezabatuko zaizkie gailuko erabiltzaile "<b>"guztiei"</b>"."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> erabiltzaileari desinstalatu nahi diozu aplikazioa?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Aplikazio hau jatorrizko bertsioarekin ordeztu nahi duzu? Datu guztiak ezabatuko dira."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Aplikazio hau jatorrizko bertsioarekin ordeztu nahi duzu? Datu guztiak ezabatuko dira. Gailuaren erabiltzaile guztiengan izango du eragina, laneko profilak dituztenengan barne."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Abian diren desinstalatze-eragiketak"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalatu ezin izan direnak"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Desinstalatzen…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalatzen…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Desinstalatu da."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Desinstalatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Ezin izan da desinstalatu."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Ezin izan da desinstalatu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Ezin da desinstalatu gailua administratzeko aplikazio aktiboa"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Ezin da desinstalatu <xliff:g id="USERNAME">%1$s</xliff:g> erabiltzailearen gailua administratzeko aplikazio aktiboa"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Erabiltzaile edo profil batzuek aplikazio hau behar dute, baina desinstalatu egin da gainerakoentzat"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Zure profilak aplikazio hau behar du, eta ezin da desinstalatu."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Gailuaren administratzaileak aplikazio hau behar du, eta ezin da desinstalatu."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Kudeatu gailua administratzeko aplikazioak"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Kudeatu erabiltzaileak"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Ezin izan da desinstalatu <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Arazo bat izan da paketea analizatzean."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Ezin dira gauzatu instalatzeko eta desinstalatzeko ekintzak Wear gailuetan."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Aplikazioa prestatzen…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Ezezaguna"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak tableta honetan."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telebista honetan."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Segurtasuna bermatzeko, ezin dira instalatu iturburu honetako aplikazio ezezagunak telefono honetan."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonoak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telefonoak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik tabletak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Telebistak eta datu pertsonalek aplikazio ezezagunen erasoak jaso ditzakete. Aplikazio hau instalatzen baduzu, onartu egingo duzu zeu zarela hura erabiltzeagatik telebistak jasan ditzakeen kalteen edo datu-galeren erantzulea."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Egin aurrera"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Ezarpenak"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear aplikazioak instalatzea/desinstalatzea"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-fa/strings.xml b/packages/PackageInstaller/res/values-fa/strings.xml
index 22f1a25..be685a9 100644
--- a/packages/PackageInstaller/res/values-fa/strings.xml
+++ b/packages/PackageInstaller/res/values-fa/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"نصب‌کننده بسته"</string>
-    <string name="next" msgid="3057143178373252333">"بعدی"</string>
-    <string name="install" msgid="5896438203900042068">"نصب"</string>
-    <string name="done" msgid="3889387558374211719">"تمام"</string>
-    <string name="cancel" msgid="8360346460165114585">"لغو"</string>
-    <string name="installing" msgid="8613631001631998372">"در حال نصب…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"درحال نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"برنامه نصب شد."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"آیا می‌خواهید این برنامه را نصب کنید؟ این برنامه به این موارد دسترسی خواهد یافت:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"آیا می‌خواهید این برنامه را نصب کنید؟ این برنامه به دسترسی خاصی نیاز ندارد."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"آیا میٰ‌خواهید بهٰ‌روزرسانی این برنامه کنونی را نصب کنید؟ داده کنونی شما از بین نمی‌رود. برنامه به‌روزرسانی شده دسترسی خواهد داشت به:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"آیا می‌خواهید به‌روزرسانی این برنامه جاسازی شده را نصب کنید؟ داده‌های کنونی شما از بین نمی‌رود. برنامه به‌روزرسانی شده دسترسی خواهد داشت به:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"آیا می‌خواهید یک به‌روزرسانی برای این برنامه کاربردی موجود نصب کنید؟ داده‌های موجود شما از دست نخواهد رفت. به دسترسی ویژه‌ای نیاز ندارد."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"آیا می‌خواهید یک به‌روزرسانی برای این برنامه کاربردی داخلی نصب کنید؟ داده‌های موجود شما از دست نخواهد رفت. به دسترسی ویژه‌ای نیاز ندارد."</string>
-    <string name="install_failed" msgid="6579998651498970899">"برنامه نصب نشد."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"از نصب شدن بسته جلوگیری شد."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"برنامه نصب نشد چون بسته با بسته موجود تداخل دارد."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"برنامه نصب نشد چون با رایانه لوحی‌تان سازگار نیست."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"این برنامه با تلویزیون شما سازگار نیست."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"برنامه نصب نشد چون با تلفنتان سازگار نیست."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"برنامه نصب نشد چون به نظر می‌رسد بسته معتبر نیست."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> در رایانهٔ لوحی شما نصب نشد."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> را نمی‌توان روی تلویزیون شما نصب کرد."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> در تلفن شما نصب نشد."</string>
-    <string name="launch" msgid="4826921505917605463">"باز کردن"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"سرپرست سیستم شما اجازه نمی‌دهد برنامه‌های دریافت‌شده از منابع ناشناس را نصب کنید"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"این کاربر نمی‌تواند برنامه‌های ناشناس نصب کند"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"این کاربر مجاز به نصب برنامه‌ نیست"</string>
-    <string name="ok" msgid="3468756155452870475">"تأیید"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"مدیریت برنامه‌ها"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"فضا کافی نیست"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> نصب نمی‌شود. مقداری از فضا را آزاد کرده و دوباره امتحان کنید."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"برنامه یافت نشد"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"برنامه در فهرست برنامه‌های نصب شده یافت نشد."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"مجاز نیست"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"کاربر کنونی مجاز به انجام این حذف نصب نیست."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"خطا"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"برنامه را نمی‌توان حذف نصب کرد."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"حذف نصب برنامه"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"حذف نصب به‌روزرسانی"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> قسمتی از برنامه زیر است:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"می‌خواهید این برنامه را حذف نصب کنید؟"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"آیا می‌خواهید این برنامه را برای "<b>"همه"</b>" کاربران حذف کنید؟ این برنامه کاربردی و داده‌های آن برای "<b>"همه"</b>" کاربران این دستگاه حذف خواهد شد."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"آیا می‌خواهید این برنامه را برای این کاربر <xliff:g id="USERNAME">%1$s</xliff:g> حذف نصب کنید؟"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"این برنامه با نسخه کارخانه جایگزین شود؟ همه داده‌ها پاک می‌شوند."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"این برنامه با نسخه کارخانه جایگزین شود؟ همه داده‌ها پاک می‌شوند. این کار همه کاربران این دستگاه (از جمله کاربرانی که نمایه کاری دارند) را تحت تأثیر قرار خواهد داد."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"حذف‌نصب‌های درحال انجام"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"حذف‌نصب‌های ناموفق"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"در حال حذف نصب..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"درحال حذف نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"حذف نصب پایان یافت."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> را حذف نصب کرد"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"حذف نصب انجام نشد."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> باموفقیت حذف نصب شد."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"نمی‌توان برنامه فعال سرپرست دستگاه را حذف نصب کرد"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"نمی‌توان برنامه فعال سرپرست دستگاه را برای <xliff:g id="USERNAME">%1$s</xliff:g> حذف نصب کرد"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"این برنامه برای برخی کاربران یا نمایه‌ها ضروری است و برای بقیه حذف نصب شد"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"این برنامه برای نمایه شما لازم است و نمی‌توان آن را حذف نصب کرد."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"سرپرست دستگاه شما این برنامه را لازم کرده است و نمی‌تواند حذف نصب شود."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"مدیریت برنامه‌های سرپرست دستگاه"</string>
-    <string name="manage_users" msgid="3125018886835668847">"مدیریت کاربران"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> حذف نصب نشد."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"مشکلی در تجزیه این بسته وجود داشت."</string>
-    <string name="newPerms" msgid="6039428254474104210">"جدید"</string>
-    <string name="allPerms" msgid="1024385515840703981">"همه موارد"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"حریم خصوصی"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"دسترسی به دستگاه"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"این به‌روزرسانی به مجوز جدیدی نیاز ندارد."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"اجازه ندارد"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"اطلاعات بیشتر"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"در هر صورت نادیده گرفته شود"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> از <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"‏به&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه <xliff:g id="ACTION">%2$s</xliff:g> را می‌دهید؟"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"‏همیشه به &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; برای <xliff:g id="ACTION">%2$s</xliff:g> اجازه داده شود؟"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"فقط هنگام استفاده از برنامه"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"همیشه"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"رد شود و دیگر سؤال نشود"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> مجوز غیرفعال هستند"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"همه مجوزها غیرفعال هستند"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"هیچ‌ موردی غیرفعال نیست"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"مجاز است"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"برنامه‌ها"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"مجوزهای برنامه"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"دوباره سؤال نشود"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"مجوزی موجود نیست"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"مجوزهای بیشتر"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"باز کردن اطلاعات برنامه"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد دیگر</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد دیگر</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"‏این برنامه برای یک نسخه قدیمی‌تر از Android طراحی شده بود. نپذیرفتن اجازه ممکن است باعث شود که برنامه دیگر به صورتی که موردنظر است کار نکند."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"انجام یک اقدام ناشناس"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> برنامه از <xliff:g id="COUNT_1">%2$d</xliff:g> برنامه مجاز است"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"نمایش سیستم"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"پنهان کردن سیستم"</string>
-    <string name="no_apps" msgid="1965493419005012569">"برنامه‌ای موجود نیست"</string>
-    <string name="location_settings" msgid="1774875730854491297">"تنظیمات مکان"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> یکی از ارائه‌دهندگان سرویس‌های مکان برای این دستگاه است. با رفتن به تنظیمات مکان می‌توانید دسترسی به موقعیت مکانی را تغییر دهید."</string>
-    <string name="system_warning" msgid="7103819124542305179">"اگر این اجازه را رد کنید، ممکن است قابلیت‌های اصلی دستگاهتان دیگر عملکرد موردانتظار را نداشته باشند."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"اجرا توسط خط‌مشی"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"دسترسی به پس‌زمینه به‌موجب خط‌مشی غیرفعال شد"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"دسترسی به پس‌زمینه به‌موجب خط‌مشی فعال شد"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"دسترسی به پیش‌زمینه به‌موجب خط‌مشی فعال شد"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"توسط سرپرست سیستم کنترل می‌شود"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"همیشه"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"فقط هنگام استفاده از برنامه"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"هرگز"</string>
-    <string name="loading" msgid="7811651799620593731">"درحال بارگیری…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"همه مجوزها"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"سایر قابلیت‌های برنامه"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"درخواست مجوز"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"هم‌پوشانی صفحه شناسایی شد"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"‏برای تغییر این تنظیم مجوز، ابتدا باید هم‌پوشانی صفحه را از «تنظیمات &gt; برنامه‌ها» خاموش کنید"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"باز کردن تنظیمات"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"‏کنش‌های نصب/حذف نصب در Wear پشتیبانی نمی‌شود."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"‏انتخاب کنید &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اجازه دارد به چه چیزی دسترسی پیدا کند"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; به‌روزرسانی شده است. انتخاب کنید این برنامه اجازه دارد به چه چیزی دسترسی پیدا کند."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"لغو"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"ادامه"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"مجوزهای جدید"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"مجوزهای کنونی"</string>
-    <string name="message_staging" msgid="6151794817691100003">"مرحله‌بندی برنامه…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"نامشخص"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"برای امنیت شما، رایانه لوحی‌تان اجازه نمی‌دهد از این منبع برنامه‌های ناشناس نصب شوند."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"برای امنیت شما، تلویزیونتان اجازه نمی‌دهد از این منبع برنامه‌های ناشناس نصب شوند."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"برای امنیت شما، تلفنتان اجازه نمی‌دهد از این منبع برنامه‌های ناشناس نصب شوند."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"تلفن و داده‌های شخصی‌تان در برابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به تلفن یا از دست رفتن داده‌ای هستید که ممکن است در نتیجه استفاده از آن به وجود آید."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"رایانه لوحی و داده‌های شخصی‌تان در برابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به رایانه لوحی یا از دست رفتن داده‌ای هستید که ممکن است در نتیجه استفاده از آن به وجود آید."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"تلویزیون و داده‌های شخصی‌تان در برابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به تلویزیون یا از دست رفتن داده‌ای هستید که ممکن است در نتیجه استفاده از آن به وجود آید."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ادامه"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"تنظیمات"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"نصب/حذف نصب برنامه‌های پوشیدنی"</string>
+    <string name="app_name" msgid="7488448184431507488">"نصب‌کننده بسته"</string>
+    <string name="install" msgid="711829760615509273">"نصب"</string>
+    <string name="done" msgid="6632441120016885253">"تمام"</string>
+    <string name="cancel" msgid="1018267193425558088">"لغو"</string>
+    <string name="installing" msgid="4921993079741206516">"درحال نصب…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"درحال نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"برنامه نصب شد."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"می‌خواهید این برنامه را نصب کنید؟"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"آیا می‌خواهید به‌روزرسانی‌ این برنامه کنونی را نصب کنید؟ داده کنونی شما از بین نمی‌رود."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"آیا می‌خواهید به‌روزرسانی این برنامه داخلی را نصب کنید؟ داده‌های کنونی شما از بین نمی‌رود."</string>
+    <string name="install_failed" msgid="5777824004474125469">"برنامه نصب نشد."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"از نصب شدن بسته جلوگیری شد."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"برنامه نصب نشد چون بسته با بسته موجود تداخل دارد."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"برنامه نصب نشد چون با رایانه لوحی‌تان سازگار نیست."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"این برنامه با تلویزیون شما سازگار نیست."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"برنامه نصب نشد چون با تلفنتان سازگار نیست."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"برنامه نصب نشد چون به نظر می‌رسد بسته معتبر نیست."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> در رایانه لوحی شما نصب نشد."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"این کاربر نمی‌تواند برنامه‌های ناشناس نصب کند"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"این کاربر مجاز به نصب برنامه‌ نیست"</string>
+    <string name="ok" msgid="7871959885003339302">"بسیار خوب"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"مدیریت برنامه‌ها"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"فضا کافی نیست"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> نصب نمی‌شود. مقداری از فضا را آزاد و دوباره امتحان کنید."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"برنامه یافت نشد"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"برنامه در فهرست برنامه‌های نصب‌شده یافت نشد."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"مجاز نیست"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"کاربر کنونی مجاز به انجام این حذف نصب نیست."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"خطا"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"برنامه را نمی‌توان حذف نصب کرد."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"حذف نصب برنامه"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"حذف نصب به‌روزرسانی"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> قسمتی از برنامه زیر است:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"می‌خواهید این برنامه را حذف نصب کنید؟"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"آیا می‌خواهید این برنامه را برای "<b>"همه"</b>" کاربران حذف کنید؟ این برنامه و داده‌های آن برای "<b>"همه"</b>" کاربران این دستگاه حذف خواهد شد."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"آیا می‌خواهید این برنامه را برای این کاربر <xliff:g id="USERNAME">%1$s</xliff:g> حذف نصب کنید؟"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"این برنامه با نسخه کارخانه جایگزین شود؟ همه داده‌ها پاک می‌شود."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"این برنامه با نسخه کارخانه جایگزین شود؟ همه داده‌ها پاک می‌شود. این کار همه کاربران این دستگاه (ازجمله کاربرانی که نمایه کاری دارند) را تحت تأثیر قرار خواهد داد."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"حذف‌نصب‌های درحال انجام"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"حذف‌نصب‌های ناموفق"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"درحال حذف نصب..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"درحال حذف نصب <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"حذف نصب انجام شد."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"‏کنش‌های نصب/حذف نصب در Wear پشتیبانی نمی‌شود."</string>
+    <string name="message_staging" msgid="8032722385658438567">"مرحله‌بندی برنامه…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"نامشخص"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"برای امنیت شما، رایانه لوحی‌تان اجازه نمی‌دهد از این منبع برنامه‌های ناشناس نصب شود."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"برای امنیت شما، تلویزیونتان اجازه نمی‌دهد از این منبع برنامه‌های ناشناس نصب شود."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"برای امنیت شما، تلفنتان اجازه نمی‌دهد از این منبع برنامه‌های ناشناس نصب شود."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"تلفن و داده‌های شخصی‌تان دربرابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به تلفن یا از دست رفتن داده‌ای هستید که ممکن است درنتیجه استفاده از آن به وجود آید."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"رایانه لوحی و داده‌های شخصی‌تان دربرابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به رایانه لوحی یا از دست رفتن داده‌ای هستید که ممکن است درنتیجه استفاده از آن به وجود آید."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"تلویزیون و داده‌های شخصی‌تان دربرابر حمله برنامه‌های ناشناس آسیب‌پذیرتر هستند. با نصب این برنامه، موافقت می‌کنید که مسئول هرگونه آسیب به تلویزیون یا از دست رفتن داده‌ای هستید که ممکن است درنتیجه استفاده از آن به وجود آید."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"ادامه"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"تنظیمات"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"نصب/حذف نصب برنامه‌های پوشیدنی"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-fi/strings.xml b/packages/PackageInstaller/res/values-fi/strings.xml
index 7ce75d1..df73ed7 100644
--- a/packages/PackageInstaller/res/values-fi/strings.xml
+++ b/packages/PackageInstaller/res/values-fi/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Paketin asentaja"</string>
-    <string name="next" msgid="3057143178373252333">"Seuraava"</string>
-    <string name="install" msgid="5896438203900042068">"Asenna"</string>
-    <string name="done" msgid="3889387558374211719">"Valmis"</string>
-    <string name="cancel" msgid="8360346460165114585">"Peruuta"</string>
-    <string name="installing" msgid="8613631001631998372">"Asennetaan…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Asennetaan kohdetta <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Sovellus on asennettu."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Haluatko asentaa tämän sovelluksen? Se saa käyttöönsä seuraavat ominaisuudet:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Haluatko asentaa tämän sovelluksen? Se ei vaadi erityisiä käyttöoikeuksia."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Haluatko asentaa päivityksen tähän olemassa olevaan sovellukseen? Olemassa olevat tiedot eivät katoa. Päivitetty sovellus saa käyttöönsä seuraavat ominaisuudet:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Haluatko asentaa päivityksen tähän sisäiseen sovellukseen? Olemassa olevat tiedot eivät katoa. Päivitetty sovellus saa käyttöönsä seuraavat ominaisuudet:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Haluatko asentaa päivityksen tähän sovellukseen? Et menetä nykyisiä tietojasi. Päivitys ei edellytä erityisiä käyttöoikeuksia."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Haluatko asentaa päivityksen tähän laitteen mukana tulleeseen sovellukseen? Et menetä nykyisiä tietojasi. Päivitys ei edellytä erityisiä käyttöoikeuksia."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Sovellusta ei asennettu."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Paketin asennus estettiin."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Sovellusta ei asennettu, koska paketti on ristiriidassa nykyisen paketin kanssa."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Sovellusta ei asennettu, koska se ei ole yhteensopiva tabletin kanssa."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Tämä sovellus ei ole yhteensopiva televisiosi kanssa."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Sovellusta ei asennettu, koska se ei ole yhteensopiva puhelimen kanssa."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Sovellusta ei asennettu, koska paketti vaikuttaa virheelliseltä."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> asentaminen tähän tablet-laitteeseen epäonnistui."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei asennu televisioosi."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> asentaminen puhelimeesi ei onnistunut."</string>
-    <string name="launch" msgid="4826921505917605463">"Avaa"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Järjestelmänvalvoja ei salli sovellusten asentamista tuntemattomista lähteistä."</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Tämä käyttäjä ei voi asentaa tuntemattomia sovelluksia."</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Tämä käyttäjä ei voi asentaa sovelluksia."</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Hallinnoi sovelluksia"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Tallennustila loppu"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> asentaminen epäonnistui. Vapauta tallennustilaa ja yritä uudelleen."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Sovellusta ei löydy"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Sovellusta ei löydy asennettujen sovelluksien luettelosta."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ei sallittu"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Nykyisellä käyttäjällä ei ole oikeutta suorittaa tätä poistoa."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Virhe"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Sovelluksen poistaminen epäonnistui."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Poista sovellus"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Poista päivitys"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> on osa seuraavaa sovellusta:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Haluatko poistaa tämän sovelluksen?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Haluatko poistaa tämän sovelluksen "<b>"kaikilta"</b>" käyttäjiltä? Sovellus ja sen tiedot poistetaan "<b>"kaikilta"</b>" laitteen käyttäjiltä."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Haluatko poistaa tämän sovelluksen käyttäjältä <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Haluatko korvata tämän sovelluksen tehdasversiolla? Kaikki tiedot poistetaan."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Haluatko korvata tämän sovelluksen tehdasversiolla? Kaikki tiedot poistetaan. Tämä vaikuttaa kaikkiin laitteen käyttäjiin, myös työprofiileihin."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Käynnissä olevat poistot"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Epäonnistuneet poistot"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Poistetaan..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Poistetaan pakettia <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Poisto valmis."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> poistettu"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Poisto epäonnistui."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on poistettu."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktiivista laitteenhallintasovellusta ei voi poistaa käytöstä."</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Käyttäjän <xliff:g id="USERNAME">%1$s</xliff:g> aktiivista laitteenhallintasovellusta ei voi poistaa käytöstä."</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Jotkin käyttäjät/profiilit tarvitsevat tätä sovellusta ja se poistettiin muista."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Profiilisi käyttö edellyttää tätä sovellusta. Sovellusta ei voi poistaa."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Laitteen järjestelmänvalvoja tarvitsee tätä sovellusta eikä sitä voi poistaa."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Hallinnoi laitteenhallintasovelluksia"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Hallinnoi käyttäjiä"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> poistaminen epäonnistui"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Paketin jäsentämisessä esiintyi ongelma."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Uusi"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Kaikki"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Tietosuoja"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Laitteen käyttö"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Tämä päivitys ei vaadi uusia käyttöoikeuksia."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Estä"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Lisätietoja"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Kiellä silti"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Saako &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aina <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Vain sovelluksen käytön aikana"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Aina"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Hylkää äläkä kysy uudelleen"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> pois käytöstä"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"kaikki pois käytöstä"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"kaikki käytössä"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Salli"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Sovellukset"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Sovellusten käyttöoikeudet"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Älä kysy uudestaan"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Ei käyttöoikeuksia"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Lisäkäyttöoikeudet"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Avaa sovelluksen tiedot"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> lisää</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> lisää</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Tämä sovellus on suunniteltu vanhemmalle Android-versiolle. Se ei välttämättä toimi oikein, jos käyttöoikeuksia ei sallita."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"suorita tuntematon toiminto"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Sallitut sovellukset: <xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Näytä järjestelmä"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Piilota järjestelmä"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Ei sovelluksia"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Sijaintiasetukset"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> on tämän laitteen sijaintipalveluiden tarjoaja. Sijainnin käyttöoikeutta voi muokata sijaintiasetuksissa."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Jos peruutat tämän käyttöoikeuden, laitteesi perustoiminnot eivät välttämättä enää toimi oikein."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Käytännön vahvistama"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Käytäntö estää taustakäytön"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Käytäntö sallii taustakäytön"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Käytäntö sallii käytön etualalla"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Järjestelmänvalvoja hallinnoi tätä"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Aina"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Vain sovelluksen käytön aikana"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Ei koskaan"</string>
-    <string name="loading" msgid="7811651799620593731">"Ladataan…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Kaikki käyttöoikeudet"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Muut sovellusluvat"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Lupapyyntö"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Näytön peittokuva havaittiin"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Ennen kuin voit muokata tätä käyttöoikeusasetusta, sinun täytyy poistaa näytön peittokuva käytöstä Asetukset-valikon Sovellukset-kohdasta."</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Avaa Asetukset"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ei tue asennus- ja poistotoimintoja."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Valitse, mitä käyttöoikeuksia sovellukselle &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; myönnetään."</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; on päivitetty. Valitse, mitä käyttöoikeuksia tälle sovellukselle myönnetään."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Peruuta"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Jatka"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Uudet käyttöoikeudet"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Nykyiset käyttöoikeudet"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Valmistellaan sovellusta…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Tuntematon"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Turvallisuussyistä tabletti ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Turvallisuussyistä televisiosi ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Turvallisuussyistä puhelin ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Tuntemattomat sovellukset voivat helpommin kaapata puhelimesi ja henkilötietosi. Lataamalla sovelluksia tästä lähteestä hyväksyt, että olet itse vastuussa puhelimellesi aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tuntemattomat sovellukset voivat helpommin kaapata tablettisi ja henkilötietosi. Lataamalla sovelluksia tästä lähteestä hyväksyt, että olet itse vastuussa tabletillesi aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tuntemattomat sovellukset voivat helpommin kaapata televisiosi ja henkilötietosi. Lataamalla sovelluksen hyväksyt, että olet itse vastuussa mahdollisista televisiolle aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Jatka"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Asetukset"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear-sovellusten asennus/poistaminen"</string>
+    <string name="app_name" msgid="7488448184431507488">"Paketin asentaja"</string>
+    <string name="install" msgid="711829760615509273">"Asenna"</string>
+    <string name="done" msgid="6632441120016885253">"Valmis"</string>
+    <string name="cancel" msgid="1018267193425558088">"Peruuta"</string>
+    <string name="installing" msgid="4921993079741206516">"Asennetaan…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Asennetaan <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Sovellus on asennettu."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Haluatko asentaa tämän sovelluksen?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Haluatko asentaa päivityksen tähän asennettuun sovellukseen? Aiempi data ei katoa."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Haluatko asentaa päivityksen tähän valmiiksi asennettuun sovellukseen? Aiempi data ei katoa."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Sovellusta ei asennettu."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paketin asennus estettiin."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Sovellusta ei asennettu, koska paketti on ristiriidassa nykyisen paketin kanssa."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Sovellusta ei asennettu, koska se ei ole yhteensopiva tabletin kanssa."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Tämä sovellus ei ole yhteensopiva televisiosi kanssa."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Sovellusta ei asennettu, koska se ei ole yhteensopiva puhelimen kanssa."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Sovellusta ei asennettu, koska paketti vaikuttaa virheelliseltä."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole asennettavissa tablettiin."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole asennettavissa televisioon."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> ei ole asennettavissa puhelimeen."</string>
+    <string name="launch" msgid="3952550563999890101">"Avaa"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Järjestelmänvalvoja ei salli sovellusten asentamista tuntemattomista lähteistä."</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Tämä käyttäjä ei voi asentaa tuntemattomia sovelluksia."</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Tämä käyttäjä ei voi asentaa sovelluksia."</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Sovellusvalinnat"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Tallennustila ei riitä"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Sovelluksen <xliff:g id="APP_NAME">%1$s</xliff:g> asentaminen epäonnistui. Vapauta tallennustilaa ja yritä uudelleen."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Sovellusta ei löydy"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Sovellusta ei löydy asennettujen sovelluksien luettelosta."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Ei sallittu"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Nykyisellä käyttäjällä ei ole oikeutta suorittaa tätä poistoa."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Virhe"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Sovelluksen poistaminen epäonnistui."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Poista sovellus"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Poista päivitys"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> on osa seuraavaa sovellusta:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Haluatko poistaa tämän sovelluksen?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Haluatko poistaa tämän sovelluksen "<b>"kaikilta"</b>" käyttäjiltä? Sovellus ja sen data poistetaan "<b>"kaikilta"</b>" laitteen käyttäjiltä."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Haluatko poistaa tämän sovelluksen käyttäjältä <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Haluatko korvata tämän sovelluksen tehdasversiolla? Kaikki data poistetaan."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Haluatko korvata tämän sovelluksen tehdasversiolla? Kaikki data poistetaan. Tämä vaikuttaa kaikkiin laitteen käyttäjiin, myös työprofiileihin."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Käynnissä olevat poistot"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Epäonnistuneet poistot"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Poistetaan…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Poistetaan pakettia <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Poisto valmis"</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> poistettu"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Poisto epäonnistui."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> on poistettu."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktiivista laitteenhallintasovellusta ei voi poistaa käytöstä."</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Käyttäjän <xliff:g id="USERNAME">%1$s</xliff:g> aktiivista laitteenhallintasovellusta ei voi poistaa käytöstä."</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Jotkin käyttäjät tai profiilit tarvitsevat tätä sovellusta, ja se poistettiin muilta."</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Profiilisi käyttö edellyttää tätä sovellusta. Sovellusta ei voi poistaa."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Laitteen järjestelmänvalvoja tarvitsee tätä sovellusta – sitä ei voi poistaa."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Laitteenhallintasovellusten valinnat"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Käyttäjävalinnat"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Poisto (<xliff:g id="APP_NAME">%1$s</xliff:g>) epäonnistui."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Ongelma paketin jäsentämisessä"</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear ei tue asennus- ja poistotoimintoja."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Valmistellaan sovellusta…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Tuntematon"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Turvallisuussyistä tabletti ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Turvallisuussyistä televisiosi ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Turvallisuussyistä puhelin ei voi asentaa tuntemattomia sovelluksia tästä lähteestä."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Tuntemattomat sovellukset voivat helpommin kaapata puhelimesi ja henkilökohtaiset tietosi. Lataamalla sovelluksia tästä lähteestä hyväksyt, että olet itse vastuussa puhelimellesi aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tuntemattomat sovellukset voivat helpommin kaapata tablettisi ja henkilökohtaiset tietosi. Lataamalla sovelluksia tästä lähteestä hyväksyt, että olet itse vastuussa tabletillesi aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Tuntemattomat sovellukset voivat helpommin kaapata televisiosi ja henkilökohtaiset tietosi. Lataamalla sovelluksen hyväksyt, että olet itse vastuussa mahdollisista televisiolle aiheutuvista vahingoista tai tietojen menetyksestä, jotka voivat johtua sovellusten käytöstä."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Jatka"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Asetukset"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear-sovellusten asennus/poistaminen"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index e44e465..809d20c 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Programme installation trousse"</string>
-    <string name="next" msgid="3057143178373252333">"Suivante"</string>
-    <string name="install" msgid="5896438203900042068">"Installer"</string>
-    <string name="done" msgid="3889387558374211719">"Terminé"</string>
-    <string name="cancel" msgid="8360346460165114585">"Annuler"</string>
-    <string name="installing" msgid="8613631001631998372">"Installation..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Application installée."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Voulez-vous installer cette application? Elle pourra :"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Voulez-vous installer cette application? Elle n\'exige aucun accès particulier."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Voulez-vous installer une mise à jour pour cette application? Vos données existantes seront conservées. L\'application mise à jour aura accès à :"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Voulez-vous installer une mise à jour pour cette application intégrée? Vos données existantes seront conservées. L\'application mise à jour aura accès à :"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Voulez-vous installer une mise à jour pour cette application? Vos données ne seront pas perdues. Aucun droit d\'accès spécial n\'est requis."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Voulez-vous installer une mise à jour pour cette application intégrée? Vos données existantes ne seront pas perdues. Aucun droit d\'accès spécial n\'est requis."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Application non installée."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"L\'installation du paquet a été bloquée."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"L\'application n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Cette application n\'est pas compatible avec votre téléviseur."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"L\'application n\'a pas été installée, car elle ne semble pas être valide."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur cette tablette."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'a pas pu être installée sur votre téléviseur."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur ce téléphone."</string>
-    <string name="launch" msgid="4826921505917605463">"Ouvrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Votre administrateur n\'autorise pas l\'installation d\'applications obtenues à partir de sources inconnues"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Cet utilisateur ne peut pas installer les applications inconnues"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Gérer les applications"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Espace insuffisant"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace, puis réessayer."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Application non trouvée"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"L\'application ne figure pas dans la liste des applications installées."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Non autorisé"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"L\'utilisateur actuel n\'est pas autorisé à effectuer cette désinstallation."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erreur"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"L\'application n\'a pas pu être désinstallée."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Désinstaller l\'application"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Désinstaller mise à jour"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'application suivante :"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Voulez-vous désinstaller cette application?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Voulez-vous désinstaller cette application pour "<b>"tous"</b>" les utilisateurs? L\'application et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Désinstallations en cours"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Désinstallations échouées"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Désinstallation..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Désinstallation terminée."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"L\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a bien été désinstallée"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Échec de la désinstallation."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"La désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> n\'a pas réussi."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Impossible de désinstaller une application d\'administration de l\'appareil active"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Impossible de désinstaller une application d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Cette application est nécessaire pour certains utilisateurs ou profils, et elle a été désinstallée pour d\'autres."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Cette application est nécessaire pour votre profil et ne peut pas être désinstallée."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Impossible de désinstaller l\'application : requise par administrateur appareil."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gérer les applications d\'administration d\'appareils"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gérer les utilisateurs"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Impossible de désinstaller <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Un problème est survenu lors de l\'analyse du paquet."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nouvelles"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Toutes"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Confidentialité"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Accès à l\'appareil"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Cette mise à jour n\'exige pas de nouvelles autorisations."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Refuser"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"En savoir plus"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Refuser quand même"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Toujours autoriser « <xliff:g id="APP_NAME">%1$s</xliff:g> » à <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Seulement durant l\'utilisation de l\'application"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Toujours"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Refuser et ne plus demander"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> autorisation(s) désactivée(s)"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"toutes les autorisations sont désactivées"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"aucune autorisation n\'est désactivée"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Autoriser"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Applications"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Autorisations applis"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ne plus demander"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Aucune autorisation"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Autorisations supplémentaires"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ouvrir l\'information sur l\'application"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> autre</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> autres</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Cette application a été conçue pour une version antérieure d\'Android. Si vous n\'accordez pas l\'autorisation, il se peut qu\'elle ne fonctionne plus correctement."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"effectuer une action inconnue"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> application(s) autorisée(s) sur <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Afficher le système"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Masquer le système"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Aucune application"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Paramètres de localisation"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> est un fournisseur de services de localisation pour cet appareil. L\'accès à la position peut être modifié dans le menu des paramètres de localisation."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Si vous refusez cette autorisation, il est possible que cela touche certaines fonctionnalités de base de votre appareil."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Activé conformément à la politique"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"L\'accès en arrière-plan est désactivé par la politique"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"L\'accès en arrière-plan est activé par la politique"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"L\'accès en avant-plan est activé par la politique"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Contrôlé par l\'administrateur"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Toujours"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Seulement durant l\'util. de l\'appli"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Jamais"</string>
-    <string name="loading" msgid="7811651799620593731">"Chargement en cours…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Toutes les autorisations"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Autres autorisations de l\'application"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Demande d\'autorisation"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"La superposition d\'écran a été détectée"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Pour modifier ce paramètre d\'autorisation, vous devez tout d\'abord désactiver la superposition d\'écran en accédant à Paramètres &gt; Applications."</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Ouvrir les paramètres"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Les actions d\'installation et de désinstallation ne sont pas prises en charge par Android Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Définissez les autorisations d\'accès de l\'application « <xliff:g id="APP_NAME">%1$s</xliff:g> »"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"L\'application « <xliff:g id="APP_NAME">%1$s</xliff:g> » a été mise à jour. Définissez ses autorisations d\'accès."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Annuler"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuer"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nouvelles autorisations"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Autorisations actuelles"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Pré-production de l\'application en cours…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Inconnue"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette tablette."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléphone."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Votre téléphone et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Votre tablette et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Votre téléviseur et vos données personnelles sont plus vulnérables face aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuer"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Paramètres"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installer/désinstaller applis Google Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Progr. d\'inst. de paquet"</string>
+    <string name="install" msgid="711829760615509273">"Installer"</string>
+    <string name="done" msgid="6632441120016885253">"Terminé"</string>
+    <string name="cancel" msgid="1018267193425558088">"Annuler"</string>
+    <string name="installing" msgid="4921993079741206516">"Installation en cours…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Application installée."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Voulez-vous installer cette application?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Voulez-vous installer une mise à jour pour cette application existante? Vos données existantes ne seront pas perdues."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Voulez-vous installer une mise à jour pour cette application intégrée? Vos données existantes ne seront pas perdues."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du paquet a été bloquée."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le paquet entre en conflit avec un paquet existant."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Cette application n\'est pas compatible avec votre téléviseur."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"L\'application n\'a pas été installée, car elle ne semble pas être valide."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre tablette."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> n\'a pas pu être installée sur votre téléviseur."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre téléphone."</string>
+    <string name="launch" msgid="3952550563999890101">"Ouvrir"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Votre administrateur n\'autorise pas l\'installation d\'applications obtenues à partir de sources inconnues"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Cet utilisateur ne peut pas installer d\'applications inconnues"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gérer les applis"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Espace insuffisant"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace, puis réessayer."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Application non trouvée"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"L\'application ne figure pas dans la liste des applications installées."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Non autorisée"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"L\'utilisateur actuel n\'est pas autorisé à effectuer cette désinstallation."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Erreur"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"L\'application n\'a pas pu être désinstallée."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Désinstaller l\'application"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Désinstaller mise à jour"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'application suivante :"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Voulez-vous désinstaller cette application?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Voulez-vous désinstaller cette application pour "<b>"tous"</b>" les utilisateurs? L\'application et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Désinstallations en cours…"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Désinstallations échouées"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Désinstallation en cours…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> en cours…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Désinstallation terminée."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"L\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a bien été désinstallée"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Échec de la désinstallation."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"La désinstallation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> n\'a pas réussi."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Impossible de désinstaller une application d\'administration de l\'appareil active"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Impossible de désinstaller une application d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Cette application est nécessaire pour certains utilisateurs ou profils, et elle a été désinstallée pour d\'autres"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Cette application est nécessaire pour votre profil et ne peut pas être désinstallée."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Imposs. de désinst. l\'application : elle est requise par l\'admin de l\'appareil."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gérer les applications d\'administration d\'appareils"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gérer les utilisateurs"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Impossible de désinstaller <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Un problème est survenu lors de l\'analyse du paquet."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Les actions d\'installation et de désinstallation ne sont pas prises en charge par Android Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Pré-production de l\'application en cours…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Inconnue"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette tablette."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléphone."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données personnelles sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuer"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Paramètres"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installer/désinstaller applis Google Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml
index 58d9123..6bbd7e8 100644
--- a/packages/PackageInstaller/res/values-fr/strings.xml
+++ b/packages/PackageInstaller/res/values-fr/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Programme d\'installation du kit"</string>
-    <string name="next" msgid="3057143178373252333">"Suivant"</string>
-    <string name="install" msgid="5896438203900042068">"Installer"</string>
-    <string name="done" msgid="3889387558374211719">"OK"</string>
-    <string name="cancel" msgid="8360346460165114585">"Annuler"</string>
-    <string name="installing" msgid="8613631001631998372">"Installation..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installation de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Application installée."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Voulez-vous installer cette application ? Elle permet les actions suivantes :"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Voulez-vous installer cette application ? Elle n\'exige aucun accès particulier."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Voulez-vous installer une mise à jour pour cette application ? Vos données existantes seront conservées. L\'application mise à jour pourra :"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Voulez-vous installer une mise à jour pour cette application intégrée ? Vos données existantes seront conservées. L\'application mise à jour pourra :"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Voulez-vous installer une mise à jour pour cette application ? Vos données ne seront pas perdues. Aucun droit d\'accès spécial n\'est requis."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Voulez-vous installer une mise à jour pour cette application intégrée ? Vos données existantes ne seront pas perdues. Aucun droit d\'accès spécial n\'est requis."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Application non installée."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"L\'installation du package a été bloquée."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"L\'application n\'a pas été installée, car le package entre en conflit avec un package existant."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre tablette."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Cette application n\'est pas compatible avec votre téléviseur."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"L\'application n\'a pas été installée, car elle n\'est pas compatible avec votre téléphone."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"L\'application n\'a pas été installée, car le package semble ne pas être valide."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur cette tablette."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre téléviseur."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g> sur ce téléphone."</string>
-    <string name="launch" msgid="4826921505917605463">"Ouvrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Votre administrateur n\'autorise pas l\'installation d\'applications obtenues à partir de sources inconnues"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Cet utilisateur ne peut pas installer d\'applications inconnues"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Gérer les applications"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Mémoire insuffisante"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Impossible d\'installer <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace, puis réessayer."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Application non trouvée"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"L\'application ne figure pas dans la liste des applications installées."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Non autorisé"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"L\'utilisateur actuel n\'est pas autorisé à effectuer cette désinstallation."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erreur"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Impossible de désinstaller l\'application."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Désinstaller l\'application"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Désinstaller la mise à jour"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'application suivante :"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Voulez-vous désinstaller cette application ?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Voulez-vous désinstaller cette application pour "<b>"tous"</b>" les utilisateurs ? L\'application et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g> ?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées. Tous les utilisateurs de cet appareil seront affectés, y compris ceux qui ont un profil professionnel."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Désinstallations en cours"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Désinstallations non abouties"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Désinstallation..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Désinstallation de l\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Désinstallation terminée."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"L\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a été désinstallée"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Échec de la désinstallation."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Échec de la désinstallation de l\'application <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Impossible de désinstaller une application d\'administration de l\'appareil active"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Impossible de désinstaller une application d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Cette application nécessaire pour certains utilisateurs ou profils a été désinstallée pour d\'autres."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Impossible de désinstaller l\'application, car elle est nécessaire pour votre profil."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Impossible désinstaller appli, car elle est requise par administrateur appareil."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gérer les applis d\'administration de l\'appareil"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gérer les utilisateurs"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Impossible de désinstaller <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Un problème est survenu lors de l\'analyse du package."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nouveautés"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Toutes"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Confidentialité"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Accès à l\'appareil"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Cette mise à jour n\'exige pas de nouvelles autorisations."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Refuser"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Plus d\'infos"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Refuser quand même"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> sur <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Autoriser l\'application &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à <xliff:g id="ACTION">%2$s</xliff:g> ?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Toujours autoriser &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; à <xliff:g id="ACTION">%2$s</xliff:g> ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Seulement lors de l\'utilisation de l\'application"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Toujours"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Refuser et ne plus demander"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> désactivées"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"toutes désactivées"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"aucune désactivée"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Autoriser"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Applications"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Autorisations applis"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ne plus demander"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Aucune autorisation"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Autorisations supplémentaires"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ouvrir les informations sur l\'application"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> autre</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> autres</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Cette application a été conçue pour une ancienne version d\'Android. Si vous désactivez les autorisations, l\'application risque de ne plus fonctionner comme prévu."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"effectuer une action inconnue"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> application(s) autorisée(s) sur <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Afficher les processus système"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Masquer les processus système"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Aucune application"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Paramètres de géolocalisation"</string>
-    <string name="location_warning" msgid="8778701356292735971">"Les services de localisation pour cet appareil sont fournis via <xliff:g id="APP_NAME">%1$s</xliff:g>. Vous pouvez modifier l\'accès aux données de localisation dans les paramètres de localisation."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Si vous refusez cette autorisation, il est possible que cela affecte certaines fonctionnalités de base de votre appareil."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Activé conformément aux règles"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Accès en arrière-plan désactivé conformément au règlement"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Accès en arrière-plan activé conformément au règlement"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Accès au premier plan activé conformément au règlement"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Contrôlé par l\'administrateur"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Toujours"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Seulement lors utilisation appli"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Jamais"</string>
-    <string name="loading" msgid="7811651799620593731">"Chargement en cours…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Toutes les autorisations"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Autres autorisations de l\'application"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Demande d\'autorisation"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Superposition d\'écran détectée"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Pour modifier ce paramètre d\'autorisation, vous devez tout d\'abord désactiver la superposition d\'écran en accédant à Paramètres &gt; Applications."</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Ouvrir les paramètres"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Opérations d\'installation et de désinstallation impossibles sur Android Wear"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Sélectionner les éléments auxquels &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; peut accéder"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"L\'application &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; a été mise à jour. Sélectionnez les éléments auxquels elle peut accéder."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Annuler"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuer"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nouvelles autorisations"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Autorisations actuelles"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Pré-production de l\'application…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Inconnu"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette tablette."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléphone."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Votre téléphone et vos données personnelles sont plus vulnérables face aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de son utilisation."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Votre tablette et vos données personnelles sont plus vulnérables face aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de son utilisation."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Votre téléviseur et vos données personnelles sont plus vulnérables face aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuer"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Paramètres"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installer/Désinstaller les applis Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Programme installation kit"</string>
+    <string name="install" msgid="711829760615509273">"Installer"</string>
+    <string name="done" msgid="6632441120016885253">"OK"</string>
+    <string name="cancel" msgid="1018267193425558088">"Annuler"</string>
+    <string name="installing" msgid="4921993079741206516">"Installation…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installation du package <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Application installée."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Voulez-vous installer cette application ?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Voulez-vous mettre à jour cette application ? Vos données actuelles ne seront pas perdues."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Voulez-vous mettre à jour cette application intégrée ? Vos données actuelles ne seront pas perdues."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Application non installée."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"L\'installation du package a été bloquée."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"L\'application n\'a pas été installée, car le package est en conflit avec un package déjà présent."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"L\'application n\'a pas été installée, car elle est incompatible avec votre tablette."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Cette application n\'est pas compatible avec votre téléviseur."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"L\'application n\'a pas été installée, car elle est incompatible avec votre téléphone."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"L\'application n\'a pas été installée, car le package semble ne pas être valide."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Impossible d\'installer l\'application <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre tablette."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Impossible d\'installer l\'application <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre téléviseur."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Impossible d\'installer l\'application <xliff:g id="APP_NAME">%1$s</xliff:g> sur votre téléphone."</string>
+    <string name="launch" msgid="3952550563999890101">"Ouvrir"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Votre administrateur n\'autorise pas l\'installation d\'applications obtenues à partir de sources inconnues"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Cet utilisateur ne peut pas installer d\'applications inconnues"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Cet utilisateur n\'est pas autorisé à installer des applications"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gérer applis"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Mémoire insuffisante"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossible d\'installer l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>. Veuillez libérer de l\'espace et réessayer."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Application non trouvée"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"L\'application ne figure pas dans la liste des applications installées."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Non autorisé"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"L\'utilisateur actuel n\'est pas autorisé à effectuer cette désinstallation."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Erreur"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Impossible de désinstaller l\'application."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Désinstaller l\'application"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Désinstaller la mise à jour"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fait partie de l\'application suivante :"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Voulez-vous désinstaller cette application ?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Voulez-vous désinstaller cette application pour "<b>"tous"</b>" les utilisateurs ? L\'application et ses données seront supprimées pour "<b>"tous"</b>" les utilisateurs de l\'appareil."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Voulez-vous désinstaller cette application pour l\'utilisateur <xliff:g id="USERNAME">%1$s</xliff:g> ?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées. Tous les utilisateurs de cet appareil seront affectés, y compris ceux qui ont un profil professionnel."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Désinstallations en cours"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Échec des désinstallations"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Désinstallation…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Désinstallation du package <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Désinstallation terminée."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Le package <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a été désinstallé"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Échec de la désinstallation."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Échec de la désinstallation du package <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Impossible de désinstaller une application d\'administration de l\'appareil active"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Impossible de désinstaller une application d\'administration de l\'appareil active pour <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Cette application nécessaire pour certains utilisateurs ou profils a été désinstallée pour d\'autres"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Impossible de désinstaller l\'application, car elle est nécessaire pour votre profil."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Impossible désinstaller appli, car elle est requise par administrateur appareil."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gérer les applis d\'administration de l\'appareil"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gérer les utilisateurs"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Impossible de désinstaller l\'application <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Un problème est survenu lors de l\'analyse du package."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Opérations d\'installation et de désinstallation impossibles sur Android Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Préparation de l\'installation de l\'appli…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Inconnu"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur cette tablette."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléviseur."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"À des fins de sécurité, l\'installation d\'applications inconnues provenant de cette source n\'est pas autorisée sur ce téléphone."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de son utilisation."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de son utilisation."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuer"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Paramètres"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installer/Désinstaller les applis Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-gl/strings.xml b/packages/PackageInstaller/res/values-gl/strings.xml
index f7bf98d..4f28411 100644
--- a/packages/PackageInstaller/res/values-gl/strings.xml
+++ b/packages/PackageInstaller/res/values-gl/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Instalador de paquetes"</string>
-    <string name="next" msgid="3057143178373252333">"Seguinte"</string>
-    <string name="install" msgid="5896438203900042068">"Instalar"</string>
-    <string name="done" msgid="3889387558374211719">"Feito"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
-    <string name="installing" msgid="8613631001631998372">"Instalando…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplicación instalada"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Queres instalar esta aplicación? Poderá acceder a:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Queres instalar esta aplicación? Non require ningún acceso especial."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Queres instalar unha actualización para esta aplicación? Non se perderán os teus datos existentes. A aplicación actualizada disporá de acceso a:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Queres instalar unha actualización para esta aplicación integrada?  Non se perderán os teus datos existentes. A aplicación actualizada disporá de acceso a:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Queres instalar unha actualización para esta aplicación? Non se perderán os teus datos existentes. Non require ningún acceso especial."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Queres instalar unha actualización para esta aplicación integrada? Non se perderán os teus datos existentes. Non require ningún acceso especial."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplicación non instalada"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Bloqueouse a instalación do paquete."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"A aplicación non se instalou porque o paquete presenta un conflito cun paquete existente."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"A aplicación non se instalou porque a aplicación non é compatible coa tableta."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Esta aplicación non é compatible coa túa televisión."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"A aplicación non se instalou porque a aplicación non é compatible co teléfono."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"A aplicación non se instalou porque parece que o paquete non é válido."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Non se puido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> na túa tableta."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> non se puido instalar na túa televisión."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Non se puido instalar <xliff:g id="APP_NAME">%1$s</xliff:g> no teu teléfono."</string>
-    <string name="launch" msgid="4826921505917605463">"Abrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"O teu administrador non permite a instalación de aplicacións obtidas a partir de fontes descoñecidas"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Este usuario non pode instalar aplicacións descoñecidas"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuario non ten permiso para instalar aplicacións"</string>
-    <string name="ok" msgid="3468756155452870475">"Aceptar"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Xestionar aplicacións"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Espazo esgotado"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Non se puido instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espazo e téntao de novo."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Non se encontrou a aplicación"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Non se atopou a aplicación na lista de aplicacións instaladas."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Non permitido"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"O usuario actual non pode realizar esta desinstalación."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erro"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Non se puido desinstalar a aplicación."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar aplicación"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar actualización"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma parte da seguinte aplicación:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Queres desinstalar esta aplicación?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Queres desinstalar esta aplicación para "<b>"todos"</b>" os usuarios? A aplicación e os seus datos eliminaranse de "<b>"todos"</b>" os usuarios do dispositivo."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Queres desinstalar esta aplicación para o usuario <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos. Isto afectará a todos os usuarios do dispositivo, incluídos os que teñan perfís de traballo."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desintalacións en curso"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Erros nas desinstalacións"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Desinstalando…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Desinstalación finalizada"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Desinstalouse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Desinstalación incorrecta"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"A desinstalación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> non se realizou correctamente."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Non se puido desinstalar a aplicación de administración de dispositivos activa"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Non se puido desinstalar a aplicación de administración de dispositivos activa para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"A aplicación é necesaria para algúns usuarios ou perfís e estaba desinstalada para outros"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"O teu perfil necesita esta aplicación e non se pode desinstalar."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"O administrador do teu dispositivo necesita esta aplicación e non se pode desinstalar."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Xestionar apps de administración de dispositivos"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Administrar usuarios"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Non se puido desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Produciuse un problema ao analizar o paquete."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Todos"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacidade"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Acceso dispositivo"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Esta actualización non require novos permisos."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Denegar"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Máis información"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Denegar igualmente"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Queres permitir á aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Permitir sempre á aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Só ao usar a aplicación"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Denegar e non volver preguntar"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desactivados"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"todos desactivados"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ningún desactivado"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicacións"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Permisos de aplicacións"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Non preguntar de novo"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Sen permisos"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Permisos adicionais"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir información da aplicación"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> permisos máis</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> permiso máis</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Esta aplicación deseñouse para unha versión anterior de Android. Denegar o permiso pode provocar que non funcione como está previsto."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"realiza unha acción descoñecida"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicacións con permiso"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Ningunha aplicación"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Configuración da localización"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> é un fornecedor de servizos de localización para este dispositivo. O acceso de localización pode modificarse desde a configuración de localización."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Se denegas este permiso, é posible que as funcións básicas do teu dispositivo deixen de funcionar segundo o previsto."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicado pola política"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"O acceso en segundo plano está desactivado pola política"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"O acceso en segundo plano está activado pola política"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"O acceso en primeiro plano está activado pola política"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Opción controlada polo administrador"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Só ao usar a aplicación"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
-    <string name="loading" msgid="7811651799620593731">"Cargando…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Todos os permisos"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Outras funcionalidades da aplicación"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Solicitude de permiso"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Detectouse unha superposición na pantalla"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Para cambiar a configuración deste permiso, primeiro tes que desactivar a superposición na pantalla, en Configuración &gt; Aplicacións"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir configuración"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"As accións de instalar e desinstalar non son compatibles con Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Seleccionar os permisos de acceso que queres dar a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Actualizouse a aplicación &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;. Selecciona os permisos de acceso que lle queres dar."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Novos permisos"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Permisos actuais"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Probando aplicación…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Descoñecida"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Por cuestións de seguranza, na tableta non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Por cuestións de seguranza, na televisión non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Por cuestións de seguranza, no teléfono non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"O teléfono e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados no teléfono ou da perda dos datos que se poidan derivar do seu uso."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"A tableta e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados na tableta ou da perda dos datos que se poidan derivar do seu uso."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"A televisión e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados na televisión ou da perda dos datos que se poidan derivar do seu uso."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Configuración"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instalador de paquetes"</string>
+    <string name="install" msgid="711829760615509273">"Instalar"</string>
+    <string name="done" msgid="6632441120016885253">"Feito"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancelar"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalando…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Instalouse a aplicación"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Queres instalar esta aplicación?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Queres instalar unha actualización para esta aplicación? Non se perderán os datos que teñas."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Queres instalar unha actualización para esta aplicación integrada? Non se perderán os datos que teñas."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Non se instalou a aplicación"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Bloqueouse a instalación do paquete."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"A aplicación non se instalou porque o paquete presenta un conflito cun paquete que xa hai."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"A aplicación non se instalou porque a aplicación non é compatible coa tableta."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Esta aplicación non é compatible coa túa televisión."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"A aplicación non se instalou porque a aplicación non é compatible co teléfono."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"A aplicación non se instalou porque parece que o paquete non é válido."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Non se puido instalar a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> na túa tableta."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Non se puido instalar a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> na túa televisión."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Non se puido instalar a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> no teu teléfono."</string>
+    <string name="launch" msgid="3952550563999890101">"Abrir"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"O teu administrador non permite a instalación de aplicacións obtidas a partir de fontes descoñecidas"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este usuario non pode instalar aplicacións descoñecidas"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuario non ten permiso para instalar aplicacións"</string>
+    <string name="ok" msgid="7871959885003339302">"Aceptar"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Xestionar apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Esgotouse o espazo"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Non se puido instalar a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera espazo e téntao de novo."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Non se atopou a aplicación"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Non se atopou a aplicación na lista de aplicacións instaladas."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Acción non-permitida"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"O usuario actual non pode realizar esta desinstalación."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Erro"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Non se puido desinstalar a aplicación."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalar aplicación"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar actualización"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> forma parte da seguinte aplicación:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Queres desinstalar esta aplicación?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Queres desinstalar esta aplicación para "<b>"todos"</b>" os usuarios? A aplicación e os seus datos eliminaranse de "<b>"todos"</b>" os usuarios do dispositivo."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Queres desinstalar esta aplicación para o usuario que se chama <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Queres substituír esta aplicación pola versión que viña de fábrica? Eliminaranse todos os datos. Isto afectará a todos os usuarios do dispositivo, incluídos os que teñan perfís de traballo."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalacións en curso"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Erros nas desinstalacións"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Finalizou a desinstalación."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Desinstalouse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Produciuse un erro na desinstalación."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"A desinstalación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> non se realizou correctamente."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Non se puido desinstalar a aplicación de administración de dispositivos activa"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Non se puido desinstalar a aplicación de administración de dispositivos activa para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Esta aplicación é necesaria para algúns usuarios ou perfís, pero desinstalouse para os outros"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"O teu perfil necesita esta aplicación e non se pode desinstalar."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"O administrador do dispositivo necesita a aplicación e non se pode desinstalar."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Xestionar apps de administración de dispositivos"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Administrar usuarios"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Non se puido desinstalar a aplicación <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Produciuse un problema ao analizar o paquete."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"As accións de instalar e desinstalar non son compatibles con Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Preparando aplicación…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Nome descoñecido"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Por cuestións de seguranza, na tableta non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Por cuestións de seguranza, na televisión non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Por cuestións de seguranza, no teléfono non se poden instalar aplicacións descoñecidas procedentes desta fonte."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"O teléfono e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados no teléfono ou da perda dos datos que se poidan derivar do seu uso."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"A tableta e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados na tableta ou da perda dos datos que se poidan derivar do seu uso."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"A televisión e os datos persoais son máis vulnerables aos ataques de aplicacións descoñecidas. Ao instalar esta aplicación, aceptas que es responsable dos danos ocasionados na televisión ou da perda dos datos que se poidan derivar do seu uso."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuar"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Configuración"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalando/desinstalando apps para Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-gu/strings.xml b/packages/PackageInstaller/res/values-gu/strings.xml
index 5e0a2b3..4aa04d3 100644
--- a/packages/PackageInstaller/res/values-gu/strings.xml
+++ b/packages/PackageInstaller/res/values-gu/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"પૅકેજ ઇન્સ્ટોલર"</string>
-    <string name="next" msgid="3057143178373252333">"આગલું"</string>
-    <string name="install" msgid="5896438203900042068">"ઇન્સ્ટોલ કરો"</string>
-    <string name="done" msgid="3889387558374211719">"થઈ ગયું"</string>
-    <string name="cancel" msgid="8360346460165114585">"રદ કરો"</string>
-    <string name="installing" msgid="8613631001631998372">"ઇન્સ્ટોલ કરી રહ્યું છે…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ને ઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string>
-    <string name="install_done" msgid="3682715442154357097">"ઍપ્લિકેશન ઇન્સ્ટોલ કરી."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"શું તમે આ ઍપ્લિકેશન ઇન્સ્ટોલ કરવા માંગો છો? તે આની ઍક્સેસ મેળવશે:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"શું તમે આ એપ્લિકેશનને ઇન્સ્ટોલ કરવા માંગો છો? તેને કોઈપણ વિશિષ્ટ ઍક્સેસની જરૂર નથી."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"શું તમે આ અસ્તિત્વમાંની એપ્લિકેશનના અપડેટને ઇન્સ્ટોલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં. અપડેટ કરેલ એપ્લિકેશનને આની ઍક્સેસ મળશે:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"શું તમે આ બિલ્ટ-ઇન એપ્લિકેશનના અપડેટને ઇન્સ્ટોલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં. અપડેટ કરેલ એપ્લિકેશનને આની ઍક્સેસ મળશે:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"શું તમે આ અસ્તિત્વમાંની એપ્લિકેશનના અપડેટને ઇન્સ્ટોલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં. તેને કોઈ વિશિષ્ટ ઍક્સેસની જરૂર હોતી નથી."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"શું તમે આ બિલ્ટ-ઇન એપ્લિકેશનના અપડેટને ઇન્સ્ટોલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં. તેને કોઈ વિશિષ્ટ ઍક્સેસની જરૂર હોતી નથી."</string>
-    <string name="install_failed" msgid="6579998651498970899">"ઍપ્લિકેશન ઇન્સ્ટોલ કરેલ નથી."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"પૅકેજને ઇન્સ્ટૉલ થવાથી અવરોધિત કરવામાં આવ્યું હતું."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"પૅકેજનો અસ્તિત્વમાંના પૅકેજ સાથે વિરોધાભાસ હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"તમારા ટેબ્લેટ સાથે ઍપ્લિકેશન સુસંગત ન હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"આ અ‍ૅપ્લિકેશન તમારા ટીવી સાથે સુસંગત નથી."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"તમારા ફોન સાથે ઍપ્લિકેશન સુસંગત ન હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"પૅકેજ અમાન્ય લાગી રહ્યું હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"તમારા ટેબ્લેટ પર <xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટોલ કરી શકાયું નથી."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"તમારા ટીવી પર <xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટોલ કરી શકાયું નથી."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"તમારા ફોન પર <xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટોલ કરી શકાયું નથી."</string>
-    <string name="launch" msgid="4826921505917605463">"ખોલો"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"તમારા વ્યવસ્થાપક અજાણ્યા સ્રોતોથી મેળવેલ ઍપ્લિકેશનોના ઇન્સ્ટૉલેશનની મંજૂરી આપતા નથી"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"આ વપરાશકર્તા અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરી શકશે નહીં"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"આ વપરાશકર્તાને ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી"</string>
-    <string name="ok" msgid="3468756155452870475">"ઓકે"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"એપ્લિકેશન્સનું સંચાલન કરો"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"જગ્યાની બહાર"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટોલ કરી શકાઈ નથી. થોડી સ્પેસ ખાલી કરો અને ફરીથી પ્રયાસ કરો."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ઍપ્લિકેશન મળી નથી"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ઇન્સ્ટોલ કરેલ ઍપ્લિકેશન્સની સૂચિમાં ઍપ્લિકેશન મળી નહોતી."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"મંજૂરી નથી"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"વર્તમાન વપરાશકર્તાને આ અનઇન્સ્ટૉલેશન કરવાની મંજૂરી નથી."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"ભૂલ"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ઍપ્લિકેશન અનઇન્સ્ટૉલ કરી શકાઈ નહીં."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ઍપ્લિકેશન અનઇન્સ્ટોલ કરો"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"અપડેટ અનઇન્સ્ટોલ કરો"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> એ નીચેની એપ્લિકેશનનો એક ભાગ છે:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"શું તમે આ એપ્લિકેશનને અનઇન્સ્ટોલ કરવા માંગો છો?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"શું તમે "<b>"તમામ"</b>" વપરાશકર્તાઓ માટે આ ઍપ્લિકેશનને અનઇન્સ્ટોલ કરવા માગો છો? ઉપકરણ પરના "<b>"તમામ"</b>" વપરાશકર્તાઓમાંથી ઍપ્લિકેશન અને તેનો ડેટા દૂર કરવામાં આવશે."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"શું તમે <xliff:g id="USERNAME">%1$s</xliff:g> વપરાશકર્તા માટે આ એપ્લિકેશનને અનઇન્સ્ટોલ કરવા માગો છો?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"આ ઍપ્લિકેશનને ફેક્ટરી સંસ્કરણથી બદલીએ? તમામ ડેટા દૂર કરવામાં આવશે."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"આ ઍપ્લિકેશનને ફેક્ટરી સંસ્કરણથી બદલીએ? તમામ ડેટા દૂર કરવામાં આવશે. આનાથી કાર્ય પ્રોફાઇલ્સ સાથેના વપરાશકર્તાઓ સહિત આ ઉપકરણના તમામ વપરાશકર્તાઓ પ્રભાવિત થશે."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ચાલી રહેલા અનઇન્સ્ટૉલ"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"નિષ્ફળ થયેલા અનઇન્સ્ટૉલ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"અનઇન્સ્ટોલ કરી રહ્યું છે..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ને અનઇન્સ્ટૉલ કરી રહ્યાં છે…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"અનઇન્સ્ટોલ કરો સમાપ્ત થયું."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> અનઇન્સ્ટૉલ કર્યું"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"અનઇન્સ્ટોલ કરવું અસફળ રહ્યું."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ને અનઇન્સ્ટૉલ કરવું અસફળ રહ્યું."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"સક્રિય ઉપકરણ વ્યવસ્થાપક ઍપ્લિકેશનોને અનઇન્સ્ટૉલ કરી શકાતી નથી"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> માટે સક્રિય ઉપકરણ વ્યવસ્થાપક ઍપ્લિકેશનોને અનઇન્સ્ટૉલ કરી શકાતી નથી"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"આ અ‍ૅપ્લિકેશન અમુક વપરાશકર્તાઓ અથવા પ્રોફાઇલ્સ માટે જરૂરી છે અને તે અન્ય લોકો માટે અનઇન્સ્ટૉલ કરી હતી"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"તમારી કાર્યાલયની પ્રોફાઇલ માટે ઍપ્લિકેશન જરૂરી છે અને અનઇન્સ્ટૉલ કરી શકાતી નથી."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"આ ઍપ્લિકેશન તમારા ઉપકરણ વ્યવસ્થાપક માટે આવશ્યક છે અને તે અનઇન્સ્ટોલ કરી શકાતી નથી."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"ઉપકરણ વ્યવસ્થાપક ઍપ્લિકેશનોનું સંચાલન કરો"</string>
-    <string name="manage_users" msgid="3125018886835668847">"વપરાશકર્તાઓનું સંચાલન કરો"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> અનઇન્સ્ટોલ કરી શકાઈ નથી."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"પૅકેજનું વિશ્લેષણ કરવામાં એક સમસ્યા આવી હતી."</string>
-    <string name="newPerms" msgid="6039428254474104210">"નવું"</string>
-    <string name="allPerms" msgid="1024385515840703981">"તમામ"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"ગોપનીયતા"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ઉપકરણ ઍક્સેસ"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"આ અપડેટને કોઈ નવી પરવાનગીઓની જરૂર નથી."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"નકારો"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"વધુ માહિતી"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"કોઇપણ રીતે નકારો"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> માંથી <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ને <xliff:g id="ACTION">%2$s</xliff:g> મંજૂરી આપીએ?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ને હંમેશા <xliff:g id="ACTION">%2$s</xliff:g>ની મંજૂરી આપીએ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"માત્ર ઍપનો ઉપયોગ કરતી વખતે જ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"હંમેશા"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"નકારો અને ફરીથી પૂછશો નહીં"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> અક્ષમ કરી"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"તમામ અક્ષમ કરી"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"કોઈપણ અક્ષમ કરેલ નથી"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"મંજૂરી આપો"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ઍપ્લિકેશનો"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ઍપ્લિકેશન પરવાનગીઓ"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"ફરીથી પૂછશો નહીં"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"કોઈ પરવાનગીઓ નથી"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"વધારાની પરવાનગીઓ"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ઍપ માહિતી ખોલો"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> વધુ</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> વધુ</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"આ ઍપ્લિકેશન Android ના જુના સંસ્કરણ માટે તૈયાર કરવામાં આવી હતી. પરવાનગી નકારવાથી તે ધાર્યા પ્રમાણે બિલકુલ કાર્ય કરશે નહી."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"એક અજાણી ક્રિયા કરો"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> માંથી <xliff:g id="COUNT_0">%1$d</xliff:g> એપ્લિકેશન્સને મંજૂરી છે"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"સિસ્ટમ બતાવો"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"સિસ્ટમ છુપાવો"</string>
-    <string name="no_apps" msgid="1965493419005012569">"કોઇ ઍપ્લિકેશનો નથી"</string>
-    <string name="location_settings" msgid="1774875730854491297">"સ્થાન સેટિંગ્સ"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> એ આ ઉપકરણ માટે સ્થાન સેવાઓના પ્રદાતા છે. સ્થાન સેટિંગ્સમાંથી સ્થાન ઍક્સેસ સંશોધિત કરી શકાય છે."</string>
-    <string name="system_warning" msgid="7103819124542305179">"જો તમે આ પરવાનગી નકારો છો, તો તમારા ઉપકરણની મૂળભૂત સુવિધાઓ અપેક્ષા પ્રમાણે કાર્ય કરી શકશે નહીં."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"નીતિ દ્વારા લાગુ"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"નીતિ દ્વારા બૅકગ્રાઉન્ડ ઍક્સેસને બંધ કરવામાં આવ્યો છે"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"નીતિ દ્વારા બૅકગ્રાઉન્ડ ઍક્સેસને ચાલુ કરવામાં આવ્યો છે"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"નીતિ દ્વારા ફૉરગ્રાઉન્ડ ઍક્સેસને ચાલુ કરવામાં આવ્યો છે"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"વ્યવસ્થાપક દ્વારા નિયંત્રિત"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"હંમેશા"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"માત્ર ઍપનો ઉપયોગ કરતી વખતે જ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ક્યારેય નહીં"</string>
-    <string name="loading" msgid="7811651799620593731">"લોડ કરી રહ્યું છે..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"બધી પરવાનગીઓ"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"અન્ય ઍપ્લિકેશન ક્ષમતાઓ"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"પરવાનગીની વિનંતી"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"સ્ક્રીન ઓવરલે મળ્યું"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"આ પરવાનગી સેટિંગ બદલવા માટે, તમારે પહેલા સેટિંગ્સ &gt; Apps માંથી સ્ક્રીન ઓવરલે બંધ કરવું પડશે"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"સેટિંગ્સ ખોલો"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear પર ઇન્સ્ટૉલ/અનઇન્સ્ટૉલ ક્રિયાઓ સમર્થિત નથી."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ને શેના ઍક્સેસ માટેની મંજૂરી આપવી તે પસંદ કરો"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; અપડેટ કરવામાં આવી છે. આ ઍપ્લિકેશનને શેના ઍક્સેસ માટેની મંજૂરી આપવી તે પસંદ કરો."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"રદ કરો"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"ચાલુ રાખો"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"નવી પરવાનગીઓ"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"વર્તમાન પરવાનગીઓ"</string>
-    <string name="message_staging" msgid="6151794817691100003">"ઍપ્લિકેશન અમલમં છે..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"અજાણી"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"તમારી સુરક્ષા માટે, તમારા ટૅબ્લેટને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"તમારી સુરક્ષા માટે, તમારા ટીવીને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"તમારી સુરક્ષા માટે, તમારા ફોનને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"તમારો ફોન અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ફોનને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"તમારું ટૅબ્લેટ અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ટૅબ્લેટને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"તમારું ટીવી અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ  ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ટીવીને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ચાલુ રાખો"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"સેટિંગ્સ"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"એમ્બેડ ઍપ્લિકેશનો ઇન્સ્ટૉલ/અનઇન્સ્ટૉલ"</string>
+    <string name="app_name" msgid="7488448184431507488">"પૅકેજ ઇન્સ્ટૉલર"</string>
+    <string name="install" msgid="711829760615509273">"ઇન્સ્ટૉલ કરો"</string>
+    <string name="done" msgid="6632441120016885253">"થઈ ગયું"</string>
+    <string name="cancel" msgid="1018267193425558088">"રદ કરો"</string>
+    <string name="installing" msgid="4921993079741206516">"ઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ને ઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string>
+    <string name="install_done" msgid="5987363587661783896">"ઍપ્લિકેશન ઇન્સ્ટૉલ કરી."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"શું તમે આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરવા માંગો છો?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"શું તમે આ અસ્તિત્વમાંની ઍપ્લિકેશનના અપડેટને ઇન્સ્ટૉલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"શું તમે આ બિલ્ટ-ઇન ઍપ્લિકેશનના અપડેટને ઇન્સ્ટૉલ કરવા માગો છો? તમારો અસ્તિત્વમાંનો ડેટા ગુમ થશે નહીં."</string>
+    <string name="install_failed" msgid="5777824004474125469">"ઍપ્લિકેશન ઇન્સ્ટૉલ કરી નથી."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"પૅકેજને ઇન્સ્ટૉલ થવાથી બ્લૉક કરવામાં આવ્યું હતું."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"પૅકેજનો અસ્તિત્વમાંના પૅકેજ સાથે વિરોધાભાસ હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"તમારા ટેબ્લેટ સાથે ઍપ્લિકેશન સુસંગત ન હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"આ ઍપ્લિકેશન તમારા ટીવી સાથે સુસંગત નથી."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"તમારા ફોન સાથે ઍપ્લિકેશન સુસંગત ન હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"પૅકેજ અમાન્ય લાગી રહ્યું હોવાને કારણે ઍપ્લિકેશન ઇન્સ્ટૉલ થઈ નથી."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"તમારા ટૅબ્લેટ પર <xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટૉલ કરી શકાઈ નથી."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"આ વપરાશકર્તા અજાણી ઍપ્લિકેશનોને ઇન્સ્ટૉલ કરી શકતા નથી"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"આ વપરાશકર્તાને ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી"</string>
+    <string name="ok" msgid="7871959885003339302">"ઓકે"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"ઍપને મેનેજ કરો"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"સ્પેસ નથી"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ઇન્સ્ટૉલ કરી શકાઈ નથી. થોડું સ્પેસ ખાલી કરો અને ફરીથી પ્રયાસ કરો."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"ઍપ્લિકેશન મળી નથી"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ઇન્સ્ટૉલ કરેલી ઍપ્લિકેશનોની સૂચિમાં ઍપ્લિકેશન મળી નહોતી."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"મંજૂરી નથી"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"વર્તમાન વપરાશકર્તાને આ અનઇન્સ્ટૉલેશન કરવાની મંજૂરી નથી."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"ભૂલ"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"ઍપ્લિકેશન અનઇન્સ્ટૉલ કરી શકાઈ નહીં."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"ઍપ્લિકેશન અનઇન્સ્ટૉલ કરો"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"અપડેટ અનઇન્સ્ટૉલ કરો"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>, નીચેની ઍપ્લિકેશનનો ભાગ છે:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"શું તમે આ ઍપ્લિકેશનને અનઇન્સ્ટૉલ કરવા માંગો છો?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"શું તમે "<b>"બધા"</b>" વપરાશકર્તાઓ માટે આ ઍપ્લિકેશનને અનઇન્સ્ટૉલ કરવા માગો છો? ડિવાઇસ પરના "<b>"બધા"</b>" વપરાશકર્તાઓની ઍપ્લિકેશન અને તેનો ડેટા કાઢી નાખવામાં આવશે."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"શું તમે <xliff:g id="USERNAME">%1$s</xliff:g> વપરાશકર્તા માટે આ ઍપ્લિકેશનને અનઇન્સ્ટૉલ કરવા માગો છો?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"આ ઍપ્લિકેશનને ફેક્ટરી વર્ઝનથી બદલીએ? બધો ડેટા કાઢી નાખવામાં આવશે."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"આ ઍપ્લિકેશનને ફેક્ટરી વર્ઝનથી બદલીએ? બધો ડેટા કાઢી નાખવામાં આવશે. આનાથી કાર્યાલયની પ્રોફાઇલ ધરાવનારા વપરાશકર્તાઓ સહિત આ ડિવાઇસના બધા વપરાશકર્તાઓ પ્રભાવિત થશે."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"ચાલી રહેલા અનઇન્સ્ટૉલ"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"નિષ્ફળ થયેલા અનઇન્સ્ટૉલ"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"અનઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ને અનઇન્સ્ટૉલ કરી રહ્યાં છીએ…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"અનઇન્સ્ટૉલ કરવાનું સમાપ્ત થયું."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear પર ઇન્સ્ટૉલ/અનઇન્સ્ટૉલ ક્રિયાઓ સમર્થિત નથી."</string>
+    <string name="message_staging" msgid="8032722385658438567">"ઍપ્લિકેશનની પ્રક્રિયા ચાલુ છે…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"અજાણ"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"તમારી સુરક્ષા માટે, તમારા ટૅબ્લેટને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"તમારી સુરક્ષા માટે, તમારા ટીવીને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"તમારી સુરક્ષા માટે, તમારા ફોનને આ સ્રોત પરથી અજાણી ઍપ્લિકેશનો ઇન્સ્ટૉલ કરવાની મંજૂરી નથી."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"તમારો ફોન અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ફોનને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"તમારું ટૅબ્લેટ અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ટૅબ્લેટને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"તમારું ટીવી અને વ્યક્તિગત ડેટા અજાણી ઍપ્લિકેશનો દ્વારા હુમલા માટે વધુ સંવેદનશીલ છે. આ ઍપ્લિકેશન ઇન્સ્ટૉલ કરીને તમે સંમત થાઓ છો કે આનો ઉપયોગ કરવાથી તમારા ટીવીને થતી કોઈપણ હાનિ અથવા ડેટાના નુકસાન માટે તમે જવાબદાર છો."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"આગળ વધો"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"સેટિંગ"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"એમ્બેડ ઍપ્લિકેશનો ઇન્સ્ટૉલ/અનઇન્સ્ટૉલ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-hi/strings.xml b/packages/PackageInstaller/res/values-hi/strings.xml
index 5ddddbe..0a51a00 100644
--- a/packages/PackageInstaller/res/values-hi/strings.xml
+++ b/packages/PackageInstaller/res/values-hi/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"पैकेज इंस्‍टॉलर"</string>
-    <string name="next" msgid="3057143178373252333">"आगे"</string>
-    <string name="install" msgid="5896438203900042068">"इंस्‍टॉल करें"</string>
-    <string name="done" msgid="3889387558374211719">"हो गया"</string>
-    <string name="cancel" msgid="8360346460165114585">"रद्द करें"</string>
-    <string name="installing" msgid="8613631001631998372">"इंस्‍टॉल कर रहा है…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> इंस्टॉल हो रहा है…"</string>
-    <string name="install_done" msgid="3682715442154357097">"ऐप्स  इंस्‍टॉल हो गया."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"क्‍या आप इस ऐप्स को इंस्‍टॉल करना चाहते हैं? इससे यहां पर पहुंच प्राप्त होगी:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"क्‍या आप इस ऐप्स को इंस्‍टॉल करना चाहते हैं? इसके लिए किसी विशेष पहुंच की आवश्‍यकता नहीं है."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"क्‍या आप इस मौजूदा ऐप के बारे में नई जानकारी इंस्‍टॉल करना चाहते हैं? आपका मौजूदा डेटा गुम नहीं होगा. अपडेट किये गए ऐप से आपको इन पर पहुंच मिलेगी:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"क्‍या आप इस बिल्ट-इन ऐप के बारे में नई जानकारी इंस्‍टॉल करना चाहते हैं? आपका मौजूदा डेटा गुम नहीं होगा. नई जानकारी वाले ऐप से आपको इन पर मिलेगी:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"क्या आप इस मौजूदा ऐप में नई जानकारी इंस्टॉल करना चाहते हैं? आपका मौजूदा डेटा बना रहेगा. इसे किसी खास पहुंच की ज़रुरत नहीं होती."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"क्या आप इस मौजूदा ऐप में नई जानकारी इंस्टॉल करना चाहते हैं? आपका मौजूदा डेटा बना रहेगा. इसे किसी खास पहुंच की ज़रुरत नहीं होती."</string>
-    <string name="install_failed" msgid="6579998651498970899">"ऐप्स  इंस्‍टॉल नहीं हुआ."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"पैकेज को इंस्टॉल होने से अवरुद्ध किया हुआ है."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज का किसी मौजूदा पैकेज से विरोध है."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि ऐप्लिकेशन आपके टैबलेट से संगत नहीं है."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"यह ऐप आपके टीवी के संगत नहीं है."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि ऐप्लिकेशन आपके फ़ोन से संगत नहीं है."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज अमान्य लग रहा है."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> को आपके टैबलेट पर इंस्‍टॉल नहीं किया जा सका."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> को आपके टीवी पर इंस्‍टॉल नहीं किया जा सकता."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> को आपके फ़ोन पर इंस्‍टॉल नहीं किया जा सका."</string>
-    <string name="launch" msgid="4826921505917605463">"खोलें"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"आपका व्यवस्थापक अनजान स्रोतों से मिलने वाले ऐप्लिकेशन को इंस्टॉल करने की अनुमति नहीं देता है"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"यह उपयोगकर्ता अनजान ऐप्लिकेशन इंस्टॉल नहीं कर सकता"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"इस उपयोगकर्ता ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है"</string>
-    <string name="ok" msgid="3468756155452870475">"ठीक है"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"ऐप्स  प्रबंधित करें"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"जगह नहीं है"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> को इंस्‍टॉल नहीं किया जा सका. थोड़ी जगह खाली करें और फिर से कोशिश करें."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ऐप्स  नहीं मिला"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ऐप्स , इंस्‍टॉल किए गए ऐप्स  की सूची में नहीं मिला था."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"अनुमति नहीं है"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"मौजूदा उपयोगकर्ता को यह अनइंस्टॉल करने की अनुमति नहीं है"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"गड़बड़ी"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ऐप्लिकेशन अनइंस्टॉल नहीं किया जा सका."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ऐप्स अनइंस्‍टॉल करें"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"अपडेट अनइंस्‍टॉल करें"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> निम्‍न ऐप्स  का भाग है:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"क्‍या आप इस ऐप्स  को अनइंस्‍टॉल करना चाहते हैं?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"क्या आप इस ऐप्स  को "<b>"सभी"</b>" उपयोगकर्ताओं के लिए अनइंस्टॉल करना चाहते हैं? ऐप्स  और उसके डेटा को डिवाइस पर "<b>"सभी"</b>" उपयोगकर्ताओं से निकाल दिया जाएगा."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"क्या आप उपयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> के लिए इस ऐप को अनइंस्टॉल करना चाहते हैं?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"इस ऐप्लिकेशन को फ़ैक्टरी वर्शन से बदलें? सभी डेटा निकाल दिया जाएगा."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"इस ऐप्लिकेशन को फ़ैक्ट्री वर्शन से बदलें? पूरा डेटा निकाल दिया जाएगा. इसका इस डिवाइस के सभी उपयोगकर्ताओं पर असर पड़ेगा, जिनमें कार्य प्रोफ़ाइल वाले उपयोगकर्ता शामिल हैं."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"वे अनइंस्टॉल जो चल रहे हैं"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"वे अनइंस्टॉल जो सफल नहीं रहे"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"अनइंस्‍टॉल कर रहा है…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया जा रहा है…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"अनइंस्‍टॉल करना पूर्ण हो गया."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया गया"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"अनइंस्‍टॉल करना विफल."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को अनइंस्टॉल करना असफल."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"सक्रिय डिवाइस व्यवस्थापक ऐप्लिकेशन को अनइंस्टॉल नहीं किया जा सकता"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> के लिए सक्रिय डिवाइस व्यवस्थापक ऐप्लिकेशन को अनइंस्टॉल नहीं किया जा सकता"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"यह ऐप्लिकेशन कुछ उपयोगकर्ताओं या प्रोफ़ाइल हेतु आवश्यक है और अन्य हेतु अनइंस्टॉल हो गया है"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"आपकी कार्य प्रोफ़ाइल के लिए यह ऐप्लिकेशन आवश्यक है और उसे अनइंस्टॉल नहीं किया जा सकता."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"आपके डिवाइस व्यवस्थापक के लिए यह ऐप्स जरूरी है व इसे अनइंस्टॉल नहीं किया जा सकता."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"डिवाइस व्यवस्थापक ऐप्लिकेशन प्रबंधित करें"</string>
-    <string name="manage_users" msgid="3125018886835668847">"उपयोगकर्ताओं को प्रबंधित करें"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> को अनइंस्‍टॉल नहीं किया जा सका."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"पैकेज को पार्स करने में कोई समस्‍या थी."</string>
-    <string name="newPerms" msgid="6039428254474104210">"नया"</string>
-    <string name="allPerms" msgid="1024385515840703981">"सभी"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"निजता"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"डिवाइस पहुंच"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"इस अपडेट लिए अनुमति की ज़रुरत नहीं है."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"अस्वीकार करें"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"अधिक जानकारी"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"फिर भी अस्वीकार करें"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> में से <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को <xliff:g id="ACTION">%2$s</xliff:g> की अनुमति दें?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को हमेशा <xliff:g id="ACTION">%2$s</xliff:g> की अनुमति दें?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"सिर्फ़ ऐप्लिकेशन इस्तेमाल करते समय"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"हमेशा"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"अनुमति न दें और दोबारा न पूछें"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> अक्षम"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"सभी अक्षम हैं"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"कोई भी अक्षम नहीं है"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"अनुमति दें"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ऐप्लिकेशन"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ऐप्लिकेशन अनुमतियां"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"फिर से न पूछें"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"कोई अनुमति नहीं"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"और अनुमतियां"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ऐप्लिकेशन से जुड़ी जानकारी देखें"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> और</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> और</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"इस ऐप को Android के पुराने वर्शन के लिए डिज़ाइन किया गया था. अनुमति अस्वीकार करने पर हो सकता है कि फ़ंक्शन लक्षित रूप से काम नहीं करे."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"कोई अज्ञात कार्रवाई करें"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> में से <xliff:g id="COUNT_0">%1$d</xliff:g> ऐप्लिकेशन को अनुमति है"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"सिस्टम दिखाएं"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"सिस्टम छिपाएं"</string>
-    <string name="no_apps" msgid="1965493419005012569">"कोई ऐप्स नहीं"</string>
-    <string name="location_settings" msgid="1774875730854491297">"जगह की सेटिंग"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> इस डिवाइस के लिए जगह की जानकारी उपलब्‍ध कराता है. जगह की पहुंच (एक्सेस) को जगह की सेटिंग से बदला जा सकता है."</string>
-    <string name="system_warning" msgid="7103819124542305179">"यदि आप इस अनुमति को अस्वीकार करते हैं, तो हो सकता है कि आपके डिवाइस की मूलभूत सुविधाएं लक्षित कार्य ना कर पाएं."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"नीति द्वारा लागू"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"नीति के मुताबिक बैकग्राउंड एक्सेस बंद किया गया"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"नीति के मुताबिक बैकग्राउंड एक्सेस चालू किया गया"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"नीति के मुताबिक फ़ोरग्राउंड एक्सेस चालू किया गया"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"इसका नियंत्रण एडमिन के पास है"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"हमेशा"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"ऐप्लिकेशन इस्तेमाल करते समय"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"कभी नहीं"</string>
-    <string name="loading" msgid="7811651799620593731">"लोड हो रहा है…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"सभी अनुमतियां"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"अन्‍य ऐप कार्यक्षमताएं"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"अनुमति का अनुरोध"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"स्क्रीन ओवरले मिला"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"इस अनुमति सेटिंग को बदलने के लिए, आपको पहले सेटिंग &gt; ऐप, से स्क्रीन ओवरले को बंद करना होगा"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"सेटिंग खोलें"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"इंस्टॉल/अनइंस्टॉल किए जाने की कार्रवाइयां Wear पर समर्थित नहीं हैं."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"यह चुनें कि &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को किस-किस चीज पर पहुंचने देना चाहते हैं"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; को अपडेट कर दिया गया है. यह चुनें कि इस ऐप्लिकेशन को किस-किस चीज तक पहुंचने देना चाहते हैं."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"रद्द करें"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"जारी रखें"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"नई अनुमतियां"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"वर्तमान अनुमतियां"</string>
-    <string name="message_staging" msgid="6151794817691100003">"ऐप्लिकेशन चरणबद्ध किया जा रहा है…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"अज्ञात"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"आपकी सुरक्षा के लिए, आपके टैबलेट को इस स्रोत से आने वाले अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"आपकी सुरक्षा के लिए, आपके टीवी को इस स्रोत से आने वाले अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"आपकी सुरक्षा के लिए, आपके फ़ोन को इस स्रोत से आने वाले अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"आपका फ़ोन और व्यक्तिगत डेटा अज्ञात ऐप्लिकेशन के हमले के प्रति अधिक संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके आप सहमति देते हैं कि इसके उपयोग के चलते आपके फ़ोन को होने वाले किसी भी नुकसान या डेटा की हानि के लिए आप ज़िम्मेदार हैं."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"आपका टैबलेट और व्यक्तिगत डेटा अज्ञात ऐप्लिकेशन के हमले के प्रति अधिक संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके आप सहमति देते हैं कि इसके उपयोग के चलते आपके टैबलेट को होने वाले किसी भी नुकसान या डेटा की हानि के लिए आप ज़िम्मेदार हैं."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"आपका टीवी और व्यक्तिगत डेटा अज्ञात ऐप्लिकेशन के हमले के प्रति अधिक संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके आप सहमति देते हैं कि इसके उपयोग के चलते आपके टीवी को होने वाले किसी भी नुकसान या डेटा की हानि के लिए आप ज़िम्मेदार हैं."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"जारी रखें"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"सेटिंग"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"वियर ऐप इंस्टॉल/अनइंस्टॉल हो रहे हैं"</string>
+    <string name="app_name" msgid="7488448184431507488">"पैकेज इंस्‍टॉलर"</string>
+    <string name="install" msgid="711829760615509273">"इंस्टॉल करें"</string>
+    <string name="done" msgid="6632441120016885253">"हो गया"</string>
+    <string name="cancel" msgid="1018267193425558088">"रद्द करें"</string>
+    <string name="installing" msgid="4921993079741206516">"इंस्टॉल हो रहा है..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> इंस्टॉल हो रहा है…"</string>
+    <string name="install_done" msgid="5987363587661783896">"ऐप्लिकेशन इंस्‍टॉल हो गया."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"क्या आप इस ऐप्लिकेशन को इंस्‍टॉल करना चाहते हैं?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"क्या आप इस मौजूदा ऐप्लिकेशन को अपडेट करना चाहते हैं? आपका मौजूदा डेटा बचा रहेगा."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"क्या आप इस बिल्ट-इन ऐप्लिकेशन को अपडेट करना चाहते हैं? आपका मौजूदा डेटा बचा रहेगा."</string>
+    <string name="install_failed" msgid="5777824004474125469">"ऐप्लिकेशन इंस्‍टॉल नहीं हुआ."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"पैकेज को इंस्टॉल होने से ब्लॉक किया हुआ है."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज का किसी मौजूदा पैकेज से विरोध है."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि ऐप्लिकेशन आपके टैबलेट से संगत नहीं है."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"यह ऐप्लिकेशन आपके टीवी के संगत नहीं है."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि ऐप्लिकेशन आपके फ़ोन से संगत नहीं है."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"ऐप्लिकेशन इंस्टॉल नहीं हुआ क्योंकि पैकेज अमान्य लग रहा है."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> को आपके टैबलेट पर इंस्‍टॉल नहीं किया जा सका."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"यह उपयोगकर्ता अनजान ऐप्लिकेशन इंस्टॉल नहीं कर सकता"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"इस उपयोगकर्ता को ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है"</string>
+    <string name="ok" msgid="7871959885003339302">"ठीक है"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"ऐप्लिकेशन प्रबंधित करें"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"जगह नहीं है"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> को इंस्‍टॉल नहीं किया जा सका. थोड़ी जगह खाली करें और फिर से कोशिश करें."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"ऐप्लिकेशन नहीं मिला"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ऐप्लिकेशन, इंस्‍टॉल किए गए ऐप्लिकेशन की सूची में नहीं मिला था."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"अनुमति नहीं है"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"मौजूदा उपयोगकर्ता को यह अनइंस्टॉल करने की अनुमति नहीं है"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"गड़बड़ी"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"ऐप्लिकेशन अनइंस्टॉल नहीं किया जा सका."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"ऐप्लिकेशन अनइंस्‍टॉल करें"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"अपडेट अनइंस्‍टॉल करें"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> इस ऐप्लिकेशन का भाग है:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"क्‍या आप इस ऐप्लिकेशन को अनइंस्‍टॉल करना चाहते हैं?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"क्या आप इस ऐप्लिकेशन को "<b>"सभी"</b>" उपयोगकर्ताओं के लिए अनइंस्टॉल करना चाहते हैं? ऐप्लिकेशन और उसके डेटा को डिवाइस पर "<b>"सभी"</b>" उपयोगकर्ताओं से हटा दिया जाएगा."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"क्या आप उपयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> के लिए इस ऐप्लिकेशन को अनइंस्टॉल करना चाहते हैं?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"इस ऐप्लिकेशन को फ़ैक्ट्री वर्शन से बदलें? सभी डेटा हटा दिया जाएगा."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"इस ऐप्लिकेशन को फ़ैक्ट्री वर्शन से बदलें? पूरा डेटा हटा दिया जाएगा. इसका असर इस डिवाइस के सभी उपयोगकर्ताओं पर पड़ेगा, जिनमें काम की प्रोफ़ाइलों वाले उपयोगकर्ता शामिल हैं."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"वे अनइंस्टॉल जो चल रहे हैं"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"वे अनइंस्टॉल जो सफल नहीं रहे"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"अनइंस्‍टॉल हो रहा है…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल किया जा रहा है…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"अनइंस्टॉल हो गया."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear पर ऐप्लिकेशन इंस्टॉल या अनइंस्टॉल नहीं किए जा सकते."</string>
+    <string name="message_staging" msgid="8032722385658438567">"ऐप्लिकेशन तैयार किया जा रहा है…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"अनजान"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"आपकी सुरक्षा के लिए, आपके टैबलेट को इस स्रोत से अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"आपकी सुरक्षा के लिए, आपके टीवी को इस स्रोत से अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"आपकी सुरक्षा के लिए, आपके फ़ोन को इस स्रोत से अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति नहीं है."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"आपका फ़ोन और निजी डेटा अनजान ऐप्लिकेशन के हमले को लेकर ज़्यादा संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके, आप सहमति देते हैं कि इसके इस्तेमाल के चलते आपके फ़ोन को होने वाले किसी भी नुकसान या डेटा के मिट जाने पर, आप ज़िम्मेदार होंगे."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"आपका टैबलेट और निजी डेटा अनजान ऐप्लिकेशन के हमले को लेकर ज़्यादा संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके, आप सहमति देते हैं कि इसके इस्तेमाल के चलते आपके टैबलेट को होने वाले किसी भी नुकसान या डेटा के मिट जाने पर, आप ज़िम्मेदार होंगे."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"आपका टीवी और निजी डेटा अनजान ऐप्लिकेशन के हमले को लेकर ज़्यादा संवेदनशील हैं. इस ऐप्लिकेशन को इंस्टॉल करके, आप सहमति देते हैं कि इसके इस्तेमाल के चलते आपके टीवी को होने वाले किसी भी नुकसान या डेटा के मिट जाने पर, आप ज़िम्मेदार होंगे."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"जारी रखें"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"सेटिंग"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear ऐप्लिकेशन इंस्टॉल/अनइंस्टॉल हो रहे हैं"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
index 3884ae5..3169f3a 100644
--- a/packages/PackageInstaller/res/values-hr/strings.xml
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -16,142 +16,76 @@
 
 <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="2738748390251381682">"Alat za instaliranje paketa"</string>
-    <string name="next" msgid="3057143178373252333">"Sljedeća"</string>
-    <string name="install" msgid="5896438203900042068">"Instaliraj"</string>
-    <string name="done" msgid="3889387558374211719">"Gotovo"</string>
-    <string name="cancel" msgid="8360346460165114585">"Odustani"</string>
-    <string name="installing" msgid="8613631001631998372">"Instaliranje..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instaliranje paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikacija je instalirana."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Želite li instalirati ovu aplikaciju? Aplikacija će moći sljedeće:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Želite li instalirati ovu aplikaciju? Aplikacija ne zahtijeva nikakav poseban pristup."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Želite li instalirati ažuriranje postojeće aplikacije? Vaši postojeći podaci neće biti izgubljeni. Ažurirana aplikacija dobit će pristup sljedećem:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Želite li instalirati ažuriranje za ovu ugrađenu aplikaciju? Vaši postojeći podaci neće biti izgubljeni. Ažurirana aplikacija dobit će pristup sljedećem:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Želite li instalirati ažuriranje postojeće aplikacije? Vaši postojeći podaci neće se izgubiti. Nije potreban nikakav poseban pristup."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Želite li instalirati ažuriranje te ugrađene aplikacije? Vaši postojeći podaci neće se izgubiti. Nije potreban nikakav poseban pristup."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikacija nije instalirana."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Instaliranje paketa blokirano je."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacija koja nije instalirana kao paket u sukobu je s postojećim paketom."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacija koja nije instalirana kao aplikacija nije kompatibilna s vašim tabletom."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aplikacija nije kompatibilna s vašim televizorom."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacija koja nije instalirana kao aplikacija nije kompatibilna s vašim telefonom."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacija koja nije instalirana kao paket vjerojatno nije važeća."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati na ovo tabletno računalo."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nije bilo moguće instalirati aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> na vaš televizor."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati na vaš telefon."</string>
-    <string name="launch" msgid="4826921505917605463">"Otvori"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Vaš administrator ne dopušta instaliranje aplikacija iz nepoznatih izvora"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ovaj korisnik ne može instalirati nepoznate aplikacije"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ovaj korisnik nema dopuštenje za instaliranje aplikacija"</string>
-    <string name="ok" msgid="3468756155452870475">"U redu"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Upravljanje aplikacijama"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nema dovoljno mjesta"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati. Oslobodite dio prostora i pokušajte ponovo."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacija nije pronađena"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Na popisu instaliranih aplikacija ova aplikacija nije pronađena."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nije dopušteno"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Trenutačni korisnik nema dopuštenje za to deinstaliranje."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Pogreška"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Deinstaliranje aplikacije nije uspjelo."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Deinstaliraj aplikaciju"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Deinstalacija ažuriranja"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"Aktivnost <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> dio je sljedeće aplikacije:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Želite li deinstalirati ovu aplikaciju?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Želite li deinstalirati tu aplikaciju za "<b>"sve"</b>" korisnike? Aplikacija i njezini podaci bit će uklonjeni sa "<b>"svih"</b>" korisnika na uređaju."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Želite li deinstalirati tu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Želite li tu aplikaciju zamijeniti tvorničkom verzijom? Izgubit ćete sve podatke."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Želite li tu aplikaciju zamijeniti tvorničkom verzijom? Izgubit ćete sve podatke. To se odnosi na sve korisnike uređaja, uključujući one s radnim profilima."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Deinstaliranja u tijeku"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neuspjela deinstaliranja"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Deinstaliranje..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Deinstalacija je završena."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalirana"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Deinstalacija nije uspjela."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspjelo."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Deinstaliranje aktivne aplikacije administratora uređaja nije uspjelo"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nije uspjelo deinstaliranje aktivne aplikacije administratora uređaja za <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ta je aplikacija obavezna za neke korisnike ili profile, deinstalirana je za ostale"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ta je aplikacija potrebna za vaš profil i ne može se deinstalirati."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ta je aplikacija neophodna administratoru uređaja i nije ju moguće deinstalirati."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Upravljaj aplikacijama administratora uređaja"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Upravljaj korisnicima"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Došlo je do problema pri analiziranju paketa."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Sve"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privatnost"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Pristup uređaja"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Ovo ažuriranje ne zahtijeva nove dozvole."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odbij"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Više informacija"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Svejedno odbij"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> od <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Želite li aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; dopustiti da može <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Želite li uvijek dopustiti aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; sljedeće: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Samo dok se aplikacija koristi"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Uvijek"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odbij i više ne pitaj"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Onemogućeno: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"sve onemogućeno"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ništa nije onemogućeno"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Dopusti"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacije"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Dopuštenja aplikacije"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Više me ne pitaj"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Nema dopuštenja"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Dodatna dopuštenja"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otvori informacije o aplikaciji"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="few">Još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Još <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ova je aplikacija napravljena za stariju verziju Androida. Ako ne dobije dopuštenje, možda više neće funkcionirati kako treba."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"izvršiti nepoznatu radnju"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Aplikacije s dopuštenjem: <xliff:g id="COUNT_0">%1$d</xliff:g> od <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Prikaži sustav"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Sakrij sustav"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nema aplikacija"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Postavke lokacije"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> pruža usluge lokacije za ovaj uređaj. Pristup lokaciji može se izmijeniti u postavkama lokacije."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ako ne odobrite ovo dopuštenje, osnovne značajke vašeg uređaja možda više neće funkcionirati pravilno."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Provoditi se na temelju pravila"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Pristup u pozadini onemogućen je pravilima"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Pristup u pozadini omogućen je pravilima"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Pristup u prednjem planu omogućen je pravilima"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolira administrator"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Uvijek"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Samo dok se aplikacija koristi"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nikad"</string>
-    <string name="loading" msgid="7811651799620593731">"Učitavanje…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Sva dopuštenja"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Ostale mogućnosti aplikacije"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Zahtijevanje dopuštenja"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Otkriveno je preklapanje na zaslonu"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Da biste promijenili tu postavku dopuštenja, prvo morate isključiti preklapanje na zaslonu u Postavkama &gt; Aplikacije"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Otvori postavke"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Radnje instaliranja i deinstaliranja nisu podržane na Wearu."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Odaberite čemu će &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; moći pristupiti"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacija &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ažurirana je. Odaberite čemu će moći pristupiti."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Otkaži"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Nastavi"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nova dopuštenja"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Trenutačna dopuštenja"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Postavljanje aplikacije…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Nepoznato"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Iz sigurnosnih razloga tablet nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Iz sigurnosnih razloga televizor nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Iz sigurnosnih razloga telefon nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Vaš telefon i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje telefona ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Vaš tablet i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje tableta ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Vaš TV i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje televizora ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Nastavi"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Postavke"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instaliranje/deinstaliranje Wear apl."</string>
+    <string name="app_name" msgid="7488448184431507488">"Alat za inst. paketa"</string>
+    <string name="install" msgid="711829760615509273">"Instaliraj"</string>
+    <string name="done" msgid="6632441120016885253">"Gotovo"</string>
+    <string name="cancel" msgid="1018267193425558088">"Otkaži"</string>
+    <string name="installing" msgid="4921993079741206516">"Instaliranje…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instaliranje paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikacija je instalirana."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Želite li instalirati tu aplikaciju?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Želite li instalirati ažuriranje postojeće aplikacije? Vaši postojeći podaci neće se izgubiti."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Želite li instalirati ažuriranje za ovu ugrađenu aplikaciju? Vaši postojeći podaci neće se izgubiti."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikacija nije instalirana."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Instaliranje paketa blokirano je."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija koja nije instalirana kao paket u sukobu je s postojećim paketom."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikacija koja nije instalirana kao aplikacija nije kompatibilna s vašim tabletom."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Aplikacija nije kompatibilna s vašim televizorom."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikacija koja nije instalirana kao aplikacija nije kompatibilna s vašim telefonom."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikacija koja nije instalirana kao paket vjerojatno nije važeća."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati na ovo tabletno računalo."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati na vaš televizor."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati na vaš telefon."</string>
+    <string name="launch" msgid="3952550563999890101">"Otvori"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Vaš administrator ne dopušta instaliranje aplikacija iz nepoznatih izvora"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ovaj korisnik ne može instalirati nepoznate aplikacije"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ovaj korisnik nema dopuštenje za instaliranje aplikacija"</string>
+    <string name="ok" msgid="7871959885003339302">"U redu"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Upravljanje apl."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nema dovoljno mjesta"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati. Oslobodite dio prostora i pokušajte ponovo."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikacija nije pronađena"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikacija nije pronađena na popisu instaliranih aplikacija."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nije dopušteno"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Trenutačni korisnik nema dopuštenje za to deinstaliranje."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Pogreška"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Deinstaliranje aplikacije nije uspjelo."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Deinstaliraj aplikaciju"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Deinstalacija ažuriranja"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"Aktivnost <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> dio je sljedeće aplikacije:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Želite li deinstalirati ovu aplikaciju?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Želite li deinstalirati tu aplikaciju za "<b>"sve"</b>" korisnike? Aplikacija i njezini podaci bit će uklonjeni sa "<b>"svih"</b>" korisnika na uređaju."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Želite li deinstalirati tu aplikaciju za korisnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Želite li tu aplikaciju zamijeniti tvorničkom verzijom? Izgubit ćete sve podatke."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite li tu aplikaciju zamijeniti tvorničkom verzijom? Izgubit ćete sve podatke. To se odnosi na sve korisnike uređaja, uključujući one s radnim profilima."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Deinstaliranja u tijeku"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspjela deinstaliranja"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Deinstaliranje…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Deinstalacija je završena."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalirana"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Deinstalacija nije uspjela."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstaliranje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nije uspjelo."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Deinstaliranje aktivne aplikacije administratora uređaja nije uspjelo"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Nije uspjelo deinstaliranje aktivne aplikacije administratora uređaja za <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Aplikacija je obavezna za neke korisnike ili profile, deinstalirana je za ostale"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ta je aplikacija potrebna za vaš profil i ne može se deinstalirati."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ta je aplikacija neophodna administratoru uređaja i nije ju moguće deinstalirati."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Upravljaj aplikacijama administratora uređaja"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Upravljaj korisnicima"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g> nije moguće instalirati."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Došlo je do problema pri analiziranju paketa."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Radnje instaliranja i deinstaliranja nisu podržane na Wearu."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Postavljanje aplikacije…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Nepoznato"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Iz sigurnosnih razloga tablet nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Iz sigurnosnih razloga televizor nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Iz sigurnosnih razloga telefon nema dopuštenje za instaliranje nepoznatih aplikacija iz ovog izvora."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Vaš telefon i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje telefona ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Vaš tablet i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje tableta ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Vaš TV i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje televizora ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Nastavi"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Postavke"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instaliranje/deinstaliranje Wear apl."</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-hu/strings.xml b/packages/PackageInstaller/res/values-hu/strings.xml
index 5e96550..1971ea7 100644
--- a/packages/PackageInstaller/res/values-hu/strings.xml
+++ b/packages/PackageInstaller/res/values-hu/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Csomagtelepítő"</string>
-    <string name="next" msgid="3057143178373252333">"Tovább"</string>
-    <string name="install" msgid="5896438203900042068">"Telepítés"</string>
-    <string name="done" msgid="3889387558374211719">"Kész"</string>
-    <string name="cancel" msgid="8360346460165114585">"Mégse"</string>
-    <string name="installing" msgid="8613631001631998372">"Telepítés..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> telepítése…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Alkalmazás telepítve."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Telepíti ezt az alkalmazást? Az a következőkhöz fog hozzáférést kapni:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Telepíti ezt az alkalmazást? Az alkalmazás nem igényel különleges hozzáférést."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Telepít egy frissítést ehhez a meglévő alkalmazáshoz? A meglévő adatai nem vesznek el. A frissített alkalmazás a következőkhöz kap hozzáférést:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Telepít egy frissítést ehhez a beépített alkalmazáshoz? A meglévő adatai nem vesznek el. A frissített alkalmazás a következőkhöz kap hozzáférést:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Telepít egy frissítést ehhez a meglévő alkalmazáshoz? A meglévő adatai nem vesznek el. A frissítés nem igényel különleges hozzáférést."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Telepít egy frissítést ehhez a beépített alkalmazáshoz? A meglévő adatai nem vesznek el. A frissítés nem igényel különleges hozzáférést."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Az alkalmazás nincs telepítve."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"A csomag telepítését letiltotta a rendszer."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"A nem csomagként telepített alkalmazás ütközik egy már létező csomaggal."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"A nem alkalmazásként telepített alkalmazás nem kompatibilis az Ön táblagépével."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ez az alkalmazás nem kompatibilis tévéjével."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"A nem alkalmazásként telepített alkalmazás nem kompatibilis az Ön telefonjával."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"A nem csomagként telepített alkalmazás érvénytelen."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető táblagépére."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető a tévéjére."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető telefonjára."</string>
-    <string name="launch" msgid="4826921505917605463">"Megnyitás"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"A rendszergazda nem engedélyezi az ismeretlen forrásokból származó alkalmazások telepítését"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ez a felhasználó nem telepíthet ismeretlen alkalmazásokat"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ez a felhasználó nem telepíthet alkalmazásokat"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Alkalmazások kezelése"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nincs elég hely"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazást nem lehet telepíteni. Szabadítson fel egy kis helyet, és próbálja újra."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Az alkalmazás nem található"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Az alkalmazás nem található a telepített alkalmazások listájában."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nem engedélyezett"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"A jelenlegi felhasználó számára nem engedélyezett az eltávolítás végrehajtása."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Hiba"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Az alkalmazás nem távolítható el."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Alkalmazás eltávolítása"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Frissítés eltávolítása"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"A(z) <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> a következő alkalmazás része:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Eltávolítja ezt az alkalmazást?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Szeretné eltávolítani ezt az alkalmazást "<b>"minden"</b>" felhasználónál? Az alkalmazást és adatait az eszköz "<b>"minden"</b>" felhasználójánál töröljük."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Eltávolítja ezt az alkalmazást <xliff:g id="USERNAME">%1$s</xliff:g> felhasználó esetében?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Lecseréli az alkalmazást a gyári verzióra? Minden adat törlődik."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Lecseréli az alkalmazást a gyári verzióra? Minden adat törlődik. Ez az eszköz összes felhasználóját érinti, így a munkaprofilokkal rendelkezőket is."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Futó telepítések"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Sikertelen telepítések"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Eltávolítás..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása folyamatban van…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Az eltávolítás befejeződött."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása befejeződött"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Az eltávolítás sikertelen."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása nem sikerült."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nem lehet eltávolítani az aktív eszközrendszergazdai alkalmazást"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nem lehet eltávolítani az aktív eszközrendszergazdai alkalmazást <xliff:g id="USERNAME">%1$s</xliff:g> felhasználó esetében"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Egyes felhasználóknak/profiloknak szüksége van erre, másoknál pedig eltávolították"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ez az alkalmazás szükséges a profiljához, így nem távolítható el."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Az alkalmazásra szüksége van az eszköz adminisztrátorának, és nem távolítható el."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Eszközrendszergazdai alkalmazások kezelése"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Felhasználók kezelése"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Nem sikerült a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> eltávolítása"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Gond volt a csomag elemzésekor."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Új"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Mind"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Adatvédelem"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Eszközhozzáférés"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"A frissítés nem igényel új engedélyeket."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Elutasítás"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"További információ"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tiltás mindenképpen"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>/<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; számára a következőt: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Mindig engedélyezi a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&amp;gt számára a következőt: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Az alkalmazás használatakor"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Mindig"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Megtagadás, és ne jelenjen meg többé"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> van letiltva"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"az összes le van tiltva"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"egy sincs letiltva"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Engedélyezés"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Alkalmazások"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Alkalmazásengedélyek"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ne jelenjen meg többé"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Nincs engedély"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"További engedélyek"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Alkalmazásinformációk megnyitása"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> további</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> további</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ez az alkalmazás az Android egy korábbi verziójához készült. Az engedély megtagadása esetén előfordulhat, hogy a továbbiakban nem fog megfelelően működni."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"végrehajt egy ismeretlen műveletet"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>/<xliff:g id="COUNT_0">%1$d</xliff:g> alkalmazás engedélyezve"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Rendszerfolyamatok megjelenítése"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Rendszerfolyamatok elrejtése"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nincsenek alkalmazások"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Helybeállítások"</string>
-    <string name="location_warning" msgid="8778701356292735971">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> helyszolgáltatásokat biztosít ennek az eszköznek. A helyhozzáférést a helybeállításokban lehet módosítani."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ha ezt nem engedélyezi, akkor előfordulhat, hogy az eszköz egyes alapfunkciói nem megfelelően fognak működni."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Irányelv által kényszerítve"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Háttérhozzáférés házirend által letiltva"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Háttérhozzáférés házirend által engedélyezve"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Előtérbeli hozzáférés házirend által engedélyezve"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Rendszergazda által irányítva"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Mindig"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Az alkalmazás használatakor"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Soha"</string>
-    <string name="loading" msgid="7811651799620593731">"Betöltés…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Az összes engedély"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Egyéb alkalmazáslehetőségek"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Engedélykérés"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Képernyőfedvény észlelve"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Ennek az engedélynek a módosításához először ki kell kapcsolnia a képernyőfedvényt a Beállítások &gt; Alkalmazások menüben"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Beállítások megnyitása"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"A Wear nem támogatja a telepítés/eltávolítás műveletet."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Válassza ki, hogy a(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; mihez férjen hozzá"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"A(z) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; frissítése megtörtént. Válassza ki, hogy mihez férjen hozzá ez az alkalmazás."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Mégse"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Tovább"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Új engedélyek"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Jelenlegi engedélyek"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Alkalmazás fokozatos közzététele…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Ismeretlen"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Az Ön biztonsága érdekében táblagépe nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Az Ön biztonsága érdekében tévéje nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Az Ön biztonsága érdekében telefonja nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonja és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elismeri, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a telefont ért károkért."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Táblagépe és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elismeri, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a táblagépet ért károkért."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Tévéje és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elismeri, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a tévét ért károkért."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Tovább"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Beállítások"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear-alkalmazások telepítése/törlése"</string>
+    <string name="app_name" msgid="7488448184431507488">"Csomagtelepítő"</string>
+    <string name="install" msgid="711829760615509273">"Telepítés"</string>
+    <string name="done" msgid="6632441120016885253">"Kész"</string>
+    <string name="cancel" msgid="1018267193425558088">"Mégse"</string>
+    <string name="installing" msgid="4921993079741206516">"Telepítés…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> telepítése…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Alkalmazás telepítve."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Telepíti ezt az alkalmazást?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Telepíti a meglévő alkalmazás frissítését? Meglévő adatai nem vesznek el."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Telepíti a beépített alkalmazás frissítését? Meglévő adatai nem vesznek el."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Az alkalmazás nincs telepítve."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"A csomag telepítését letiltotta a rendszer."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"A nem csomagként telepített alkalmazás ütközik egy már létező csomaggal."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"A nem alkalmazásként telepített alkalmazás nem kompatibilis az Ön táblagépével."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ez az alkalmazás nem kompatibilis az Ön tévéjével."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"A nem alkalmazásként telepített alkalmazás nem kompatibilis az Ön telefonjával."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"A nem csomagként telepített alkalmazás érvénytelen."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető a táblagépére."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető a tévéjére."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazás nem telepíthető a telefonjára."</string>
+    <string name="launch" msgid="3952550563999890101">"Megnyitás"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"A rendszergazda nem engedélyezi az ismeretlen forrásokból származó alkalmazások telepítését"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ez a felhasználó nem telepíthet ismeretlen alkalmazásokat"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ez a felhasználó nem telepíthet alkalmazásokat"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Alkalmazáskezelés"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nincs elég hely"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> alkalmazást nem lehet telepíteni. Szabadítson fel egy kis helyet, és próbálkozzon újra."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Az alkalmazás nem található"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Az alkalmazás nem található a telepített alkalmazások listáján."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nem engedélyezett"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"A jelenlegi felhasználó számára nem engedélyezett az eltávolítás végrehajtása."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Hiba"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Az alkalmazás nem távolítható el."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Alkalmazás eltávolítása"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Frissítés eltávolítása"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"A(z) <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> a következő alkalmazás része:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Eltávolítja ezt az alkalmazást?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Szeretné eltávolítani ezt az alkalmazást "<b>"minden"</b>" felhasználónál? Az alkalmazást és adatait az eszköz "<b>"minden"</b>" felhasználójánál töröljük."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Eltávolítja ezt az alkalmazást <xliff:g id="USERNAME">%1$s</xliff:g> felhasználó esetében?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Lecseréli az alkalmazást a gyári verzióra? Minden adat törlődik."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Lecseréli az alkalmazást a gyári verzióra? Minden adat törlődik. Ez az eszköz összes felhasználóját érinti, így a munkaprofilokkal rendelkezőket is."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Futó eltávolítások"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Sikertelen telepítések"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Eltávolítás…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása folyamatban van…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Az eltávolítás befejeződött."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása befejeződött"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Az eltávolítás sikertelen."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"A(z) <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> eltávolítása nem sikerült."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Nem lehet eltávolítani az aktív eszközrendszergazdai alkalmazást"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Nem lehet eltávolítani az aktív eszközrendszergazdai alkalmazást <xliff:g id="USERNAME">%1$s</xliff:g> felhasználó esetében"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Egyes felhasználóknak/profiloknak szüksége van erre az alkalmazásra, másoknál pedig eltávolították"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ez az alkalmazás szükséges a profiljához, így nem távolítható el."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Az alkalmazásra szüksége van az eszköz adminisztrátorának, és nem távolítható el."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Eszközrendszergazdai alkalmazások kezelése"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Felhasználók kezelése"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Nem sikerült a(z) <xliff:g id="APP_NAME">%1$s</xliff:g> eltávolítása"</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Gond volt a csomag elemzésekor."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"A Wear nem támogatja a telepítés/eltávolítás műveletet."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Alkalmazás fokozatos közzététele…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Ismeretlen"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Az Ön biztonsága érdekében táblagépe nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Az Ön biztonsága érdekében tévéje nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Az Ön biztonsága érdekében telefonja nem telepíthet ebből a forrásból származó ismeretlen alkalmazásokat."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonja és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elfogadja, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a telefont ért károkért."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Táblagépe és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elfogadja, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a táblagépet ért károkért."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Tévéje és személyes adatai fokozott kockázatnak vannak kitéve az ismeretlen alkalmazások támadásaival szemben. Az alkalmazás telepítésével elfogadja, hogy Ön a felelős az alkalmazás használatából eredő esetleges adatvesztésért és a tévét ért károkért."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Tovább"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Beállítások"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear-alkalmazások telepítése/törlése"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml
index e89f1ec..4892ddd 100644
--- a/packages/PackageInstaller/res/values-hy/strings.xml
+++ b/packages/PackageInstaller/res/values-hy/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Փաթեթի տեղադրիչ"</string>
-    <string name="next" msgid="3057143178373252333">"Հաջորդը"</string>
-    <string name="install" msgid="5896438203900042068">"Տեղադրել"</string>
-    <string name="done" msgid="3889387558374211719">"Պատրաստ է"</string>
-    <string name="cancel" msgid="8360346460165114585">"Չեղարկել"</string>
-    <string name="installing" msgid="8613631001631998372">"Տեղադրվում է..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ի տեղադրում…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Հավելվածը տեղադրված է:"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Ցանկանու՞մ եք տեղադրել այս ծրագիրը: Այն մուտքի հնարավորություն կունենա`"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ցանկանու՞մ եք տեղադրել այս հավելվածը: Այն հատուկ մուտք չի պահանջում:"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Ցանկանու՞մ եք այս առկա հավելվածում թարմացում տեղադրել: Ձեր ընթացիկ տվյալները չեն կորի: Նորացված հավելվածը կստանա մատչում`"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ցանկանու՞մ եք այս ներկառուցված հավելվածում թարմացում տեղադրել: Ձեր առկա տվյալները չեն կորի: Նորացված հավելվածը կստանա մատչում `"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ցանկանու՞մ եք այս առկա հավելվածում թարմացում տեղադրել: Ձեր ընթացիկ տվյալները չեն կորի: Այն չի պահանջում որևէ հատուկ մուտք:"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ցանկանու՞մ եք այս ներկառուցված հավելվածում թարմացում տեղադրել: Ձեր ընթացիկ տվյալները չեն կորի: Այն չի պահանջում որևէ հատուկ մուտք:"</string>
-    <string name="install_failed" msgid="6579998651498970899">"Հավելվածը տեղադրված չէ:"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Փաթեթի տեղադրումն արգելափակվել է:"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթն ունի հակասություն առկա փաթեթի հետ:"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Հավելվածը չի տեղադրվել, քանի որ այն համատեղելի չէ ձեր պլանշետի հետ:"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Այս հավելվածը համատեղելի չէ ձեր հեռուստացույցի հետ:"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Հավելվածը չի տեղադրվել, քանի որ այն համատեղելի չէ ձեր հեռախոսի հետ:"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթը, կարծես թե, վնասված է:"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը չհաջողվեց տեղադրել ձեր պլանշետում:"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Չհաջողվեց տեղադրել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր հեռուստացույցի վրա:"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը չհաջողվեց տեղադրել ձեր հեռախոսում:"</string>
-    <string name="launch" msgid="4826921505917605463">"Բացել"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ձեր ադմինիստրատորը թույլ չի տալիս տեղադրել հավելվածներ անհայտ աղբյուրներից"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Այս օգտատերը չի կարող անհայտ հավելվածներ տեղադրել"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Այս օգտատիրոջը չի թույլատրվում տեղադրել հավելվածներ"</string>
-    <string name="ok" msgid="3468756155452870475">"Հաստատել"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Կառավարել հավելվածները"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Տարածքից դուրս"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը չհաջողվեց տեղադրել: Ազատեք որոշակի տարածք և կրկին փորձեք:"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Հավելվածը չի գտնվել"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Հավելվածը չի գտնվել տեղադրված հավելվածների ցանկում:"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Արգելված է"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Ընթացիկ օգտատերը հեռացնելու թույլտվություն չունի:"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Սխալ"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Հնարավոր չէ հեռացնել հավելվածը:"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Ապատեղադրել հավելվածը"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Ապատեղադրել թարմացումը"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>-ը հետևյալ հավելվածի մասն է`"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Ուզո՞ւմ եք ապատեղադրել այս հավելվածը։"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ցանկանու՞մ եք ապատեղադրել այս հավելվածը "<b>"բոլոր"</b>" օգտատերերի համար:  Հավելվածը և դրա տվյալները կհեռացվեն սարքի "<b>"բոլոր"</b>" օգտատերերից:"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ցանկանում եք ապատեղադրե՞լ այս ծրագիրը <xliff:g id="USERNAME">%1$s</xliff:g> օգտատիրոջ համար:"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն:"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն: Դա վերաբերում է այս սարքի բոլոր օգտատերերին, այդ թվում նաև աշխատանքային պրոֆիլներ ունեցողներին:"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Ընթացիկ հեռացումներ"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Ձախողված հեռացումներ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Ապատեղադրում է..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածը հեռացվում է…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Ապատեղադրումը ավարտված է:"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Հեռացված <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Ապատեղադրումն անհաջող է:"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Չհաջողվեց հեռացնել <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածը:"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Հնարավոր չէ հեռացնել ակտիվ սարքի ադմինիստրատորի հավելվածը"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Հնարավոր չէ հեռացնել ակտիվ սարքի ադմինիստրատորի հավելվածը <xliff:g id="USERNAME">%1$s</xliff:g> օգտատիրոջ համար"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Այս հավելվածն անհրաժեշտ է որոշ օգտատերերի կամ պրոֆիլների համար և մնացածի մոտ հեռացվել է"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Այս հավելվածն անհրաժեշտ է ձեր պրոֆիլի համար: Այն հնարավոր չէ հեռացնել:"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ծրագիրը ձեր սարքի ադմինիստրատորի կողմից նշվել է որպես պարտադիր և չի կարող հեռացվել:"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Կառավարել սարքի ադմինիստրատորի հավելվածները"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Կառավարել օգտատերերին"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ը չհաջողվեց ապատեղադրել:"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Փաթեթը վերլուծելիս խնդիր առաջացավ:"</string>
-    <string name="newPerms" msgid="6039428254474104210">"Նոր"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Բոլորը"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Գաղտնիություն"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Սարքի մատչում"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Այս թարմացումը պահանջում է, որ նոր թույլտվություններ չտրվեն:"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Մերժել"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Այլ տեղեկություններ"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Մերժել ամեն դեպքում"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>-ը <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>-ից"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Թույլատրե՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին <xliff:g id="ACTION">%2$s</xliff:g>:"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Միշտ թույլ տա՞լ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին <xliff:g id="ACTION">%2$s</xliff:g>:"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Միայն հավելվածն օգտագործելիս"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Միշտ"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Մերժել և այլևս չհարցնել"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"կասեցվել է <xliff:g id="COUNT">%1$d</xliff:g> թույլտվություն"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"բոլոր թույլտվությունները կասեցվել են"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ոչ մի թույլտվություն չի կասեցվել"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Թույլատրել"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Հավելվածներ"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Հավելվածների թույլտվություններ"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Այլևս չհարցնել"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Թույլտվություններ չկան"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Լրացուցիչ թույլտվություններ"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Հավելվածի մասին"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Եվս <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Եվս <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Այս հավելվածը նախատեսված է Android-ի ավելի հին տարբերակի համար: Եթե մերժեք թույլտվությունը, այն կարող է չաշխատել ինչպես հարկն է:"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"թույլատրել անհայտ գործողություն"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Թույլատրված է <xliff:g id="COUNT_0">%1$d</xliff:g> հավելվածի՝ <xliff:g id="COUNT_1">%2$d</xliff:g>-ից"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Ցուցադրել համակարգայինները"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Թաքցնել համակարգայինները"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Հավելվածներ չկան"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Տեղորոշման կարգավորումներ"</string>
-    <string name="location_warning" msgid="8778701356292735971">"Այս սարքի տեղորոշման ծառայությունները տրամադրում է <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը: Տեղադրության ցուցադրման կարգավորումները կարող եք փոխել տեղադրության կարգավորումներից:"</string>
-    <string name="system_warning" msgid="7103819124542305179">"Եթե չտրամադրեք այս թույլտվությունը, ձեր սարքի հիմնական գործառույթները հնարավոր է սխալ աշխատեն:"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Սահմանված է կանոններով"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Հասանելիությունը ֆոնային ռեժիմում անջատած է կանոնի համաձայն"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Հասանելիությունը ֆոնային ռեժիմում միացված է կանոնի համաձայն"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Հասանելիությունն ակտիվ ռեժիմում միացված է կանոնի համաձայն"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Վերահսկվում է ադմինիստրատորի կողմից"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Միշտ"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Միայն հավելվածն օգտագործելիս"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Երբեք"</string>
-    <string name="loading" msgid="7811651799620593731">"Բեռնում…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Բոլոր թույլտվությունները"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Այլ հավելվածների հնարավորությունները"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Թույլտվության հարցում"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Ցուցադրում այլ պատուհանների վրա"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Այս թույլտվության կարգավորումները փոխելու համար նախ անհրաժեշտ է անջատել էկրանի վերադրումը՝ անցնելով Կարգավորումներ &gt; Հավելվածներ"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Բացել կարգավորումները"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Տեղադրման/հեռացման գործողությունները Android Wear-ում չեն աջակցվում:"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Ընտրեք, ինչ թույլտվություններ եք ցանկանում տրամադրել &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածին"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; հավելվածը թարմացվել է: Ընտրեք, ինչ թույլտվություններ եք ցանկանում տրամադրել այդ հավելվածին:"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Չեղարկել"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Շարունակել"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Նոր թույլտվությունները"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Առկա թույլտվությունները"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Հավելվածի նախապատրաստում…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Անհայտ"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Անվտանգության նկատառումներից ելնելով՝ ձեր պլանշետին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Անվտանգության նկատառումներից ելնելով՝ ձեր հեռուստացույցին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Անվտանգության նկատառումներից ելնելով՝ ձեր հեռախոսին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Ձեր հեռախոսը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր հեռախոսին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ձեր պլանշետը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր պլանշետին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Ձեր TV-ն և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր TV-ին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Շարունակել"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Կարգավորումներ"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear հավելվածների տեղադրում/հեռացում"</string>
+    <string name="app_name" msgid="7488448184431507488">"Package Installer"</string>
+    <string name="install" msgid="711829760615509273">"Տեղադրել"</string>
+    <string name="done" msgid="6632441120016885253">"Պատրաստ է"</string>
+    <string name="cancel" msgid="1018267193425558088">"Չեղարկել"</string>
+    <string name="installing" msgid="4921993079741206516">"Տեղադրում…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածը տեղադրվում է…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Հավելվածը տեղադրված է:"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Տեղադրե՞լ այս հավելվածը:"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Տեղադրե՞լ այս հավելվածի թարմացումը: Ձեր տվյալները կպահպանվեն:"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Տեղադրե՞լ այս ներկառուցված հավելվածի թարմացումը: Ձեր տվյալները կպահպանվեն:"</string>
+    <string name="install_failed" msgid="5777824004474125469">"Հավելվածը տեղադրված չէ:"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Փաթեթի տեղադրումն արգելափակվել է:"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթն ունի հակասություն առկա փաթեթի հետ:"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Հավելվածը չի տեղադրվել, քանի որ այն համատեղելի չէ ձեր պլանշետի հետ:"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Այս հավելվածը համատեղելի չէ ձեր հեռուստացույցի հետ:"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Հավելվածը չի տեղադրվել, քանի որ այն համատեղելի չէ ձեր հեռախոսի հետ:"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Հավելվածը չի տեղադրվել, քանի որ տեղադրման փաթեթը, կարծես թե, վնասված է:"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Չհաջողվեց տեղադրել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր պլանշետում:"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Այս օգտատերը չի կարող անհայտ հավելվածներ տեղադրել"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Այս օգտատիրոջը չի թույլատրվում տեղադրել հավելվածներ"</string>
+    <string name="ok" msgid="7871959885003339302">"Եղավ"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Կառավարել հավելվածները"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Բավարար տարածք չկա"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Չհաջողվեց տեղադրել <xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը: Ազատեք տարածք և նորից փորձեք:"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Հավելվածը չի գտնվել"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Հավելվածը չի գտնվել տեղադրված հավելվածների ցանկում:"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Արգելված է"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Ընթացիկ օգտատերը ապատեղադրելու թույլտվություն չունի:"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Սխալ"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Չհաջողվեց ապատեղադրել հավելվածը:"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Հավելվածի ապատեղադրում"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Թարմացման ապատեղադրում"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> գործողությունը հետևյալ հավելվածի մասն է`"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Ուզո՞ւմ եք ապատեղադրել այս հավելվածը։"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Ապատեղադրե՞լ այս հավելվածը "<b>"բոլոր"</b>" օգտատերերի համար: Հավելվածը և դրա տվյալները կհեռացվեն սարքի "<b>"բոլոր"</b>" օգտատերերից:"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Ապատեղադրե՞լ այս հավելվածը <xliff:g id="USERNAME">%1$s</xliff:g> օգտատիրոջ համար:"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն:"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն: Դա վերաբերում է այս սարքի բոլոր օգտատերերին, այդ թվում նաև աշխատանքային պրոֆիլներ ունեցողներին:"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Ընթացիկ ապատեղադրումներ"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ձախողված ապատեղադրումներ"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Ապատեղադրվում է…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածն ապատեղադրվում է…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Ապատեղադրվեց:"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Տեղադրման/ապատեղադրման գործողությունները Android Wear-ում չեն աջակցվում:"</string>
+    <string name="message_staging" msgid="8032722385658438567">"Սպասեք…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Անհայտ"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Անվտանգության նկատառումներից ելնելով՝ ձեր պլանշետին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Անվտանգության նկատառումներից ելնելով՝ ձեր հեռուստացույցին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Անվտանգության նկատառումներից ելնելով՝ ձեր հեռախոսին չի թույլատրվում այս աղբյուրից տեղադրել անհայտ հավելվածներ:"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Ձեր հեռախոսը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր հեռախոսին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Ձեր պլանշետը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր պլանշետին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Ձեր հեռուստացույցը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր հեռուստացույցին պատճառած ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Շարունակել"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Կարգավորումներ"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear հավելվածների տեղադրում/ապատեղադրում"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-in/strings.xml b/packages/PackageInstaller/res/values-in/strings.xml
index afae29a..212eeb1 100644
--- a/packages/PackageInstaller/res/values-in/strings.xml
+++ b/packages/PackageInstaller/res/values-in/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Pemasang paket"</string>
-    <string name="next" msgid="3057143178373252333">"Berikutnya"</string>
-    <string name="install" msgid="5896438203900042068">"Instal"</string>
-    <string name="done" msgid="3889387558374211719">"Selesai"</string>
-    <string name="cancel" msgid="8360346460165114585">"Batal"</string>
-    <string name="installing" msgid="8613631001631998372">"Memasang..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Menginstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Apl terpasang."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Apakah Anda ingin memasang aplikasi ini? Aplikasi akan memiliki akses ke:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Apakah Anda ingin memasang aplikasi ini? Aplikasi tidak memerlukan akses khusus apa pun."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Apakah Anda ingin memasang pembaruan ke aplikasi yang ada? Data Anda yang ada tidak akan hilang. Aplikasi yang diperbarui akan mendapatkan akses ke:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Apakah Anda ingin memasang pembaruan ke aplikasi yang tertanam? Data Anda yang ada tidak akan hilang. Aplikasi yang diperbarui akan mendapatkan akses ke:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Anda ingin memasang pembaruan ke aplikasi yang ada ini? Data Anda yang ada akan hilang. Tindakan ini tidak memerlukan akses khusus apa pun."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Anda ingin memasang pembaruan ke aplikasi yang ada di dalamnya? Data Anda yang ada akan hilang. Tindakan ini tidak memerlukan akses khusus apa pun."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Apl tidak terpasang."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Paket diblokir sehingga tidak dapat dipasang."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikasi yang tidak dipasang sebagai paket akan bentrok dengan paket yang sudah ada."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikasi yang tidak dipasang sebagai aplikasi tidak kompatibel dengan tablet Anda."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aplikasi ini tidak kompatibel dengan TV Anda."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikasi yang tidak dipasang sebagai aplikasi tidak kompatibel dengan ponsel Anda."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikasi yang tidak dipasang sebagai paket tampaknya tidak valid."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang pada tablet Anda."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang di TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang pada ponsel Anda."</string>
-    <string name="launch" msgid="4826921505917605463">"Buka"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Admin tidak mengizinkan penginstalan aplikasi yang didapatkan dari sumber tidak dikenal"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Aplikasi yang tidak dikenal tidak dapat diinstal oleh pengguna ini"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Pengguna ini tidak diizinkan menginstal aplikasi"</string>
-    <string name="ok" msgid="3468756155452870475">"Oke"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Kelola apl"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Kehabisan ruang penyimpanan"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang. Kosongkan sebagian ruang dan coba lagi."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Apl tidak ditemukan"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Apl tersebut tidak ditemukan di dalam daftar apl yang terpasang."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Tidak diizinkan"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Pengguna saat ini tidak diizinkan meng-uninstal."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Kesalahan"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikasi tidak dapat dipasang."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Uninstal apl"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Uninstal pembaruan"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> adalah bagian dari apl berikut:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Apakah Anda ingin meng-uninstal apl ini?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Anda ingin mencopot aplikasi ini untuk "<b>"semua"</b>" pengguna? Aplikasi dan datanya akan dihapus dari "<b>"semua"</b>" pengguna pada perangkat."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ingin meng-uninstal aplikasi ini untuk pengguna <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Gantikan aplikasi ini dengan versi pabrik? Semua data akan dihapus."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Gantikan aplikasi ini dengan versi pabrik? Semua data akan dihapus. Tindakan ini memengaruhi semua pengguna perangkat ini, termasuk yang memiliki profil kerja."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Menjalankan uninstal"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Uninstal yang gagal"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Mencopot pemasangan..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Mencopot pemasangan <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Pencopotan pemasangan selesai."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> di-uninstal"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Pencopotan pemasangan tidak berhasil."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Gagal meng-uninstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Tidak dapat meng-uninstal aplikasi admin perangkat yang aktif"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Tidak dapat meng-uninstal aplikasi admin perangkat yang aktif untuk <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Aplikasi ini diperlukan untuk beberapa pengguna atau profil, dan telah dicopot pemasangannya untuk yang lainnya"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Aplikasi ini diperlukan untuk profil Anda dan tidak dapat dicopot pemasangannya."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Aplikasi diwajibkan administrator perangkat &amp; pemasangannya tidak bisa dicopot."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Kelola aplikasi admin perangkat"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Kelola pengguna"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dicopot pemasangannya."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Terjadi masalah saat mengurai paket."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Baru"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Semua"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privasi"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Akses Perangkat"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Pembaruan ini tidak memerlukan izin baru."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Tolak"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Info selengkapnya"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tetap tolak"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> dari <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; untuk <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Selalu izinkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; untuk <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Hanya saat menggunakan aplikasi"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Selalu"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Tolak dan jangan tanya lagi"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> dinonaktifkan"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"semua dinonaktifkan"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"tidak ada yang dinonaktifkan"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Izinkan"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikasi"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Izin aplikasi"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Jangan tanya lagi"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Tidak ada izin"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Izin tambahan"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Buka info aplikasi"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> lainnya</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> lainnya</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Aplikasi ini dirancang untuk versi lama Android. Menolak izin dapat menyebabkan aplikasi tidak berfungsi lagi sesuai harapan."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"melakukan tindakan yang tidak dikenal"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> dari <xliff:g id="COUNT_1">%2$d</xliff:g> aplikasi diizinkan"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Tampilkan sistem"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Sembunyikan sistem"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Tidak ada aplikasi"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Setelan Lokasi"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> adalah penyedia layanan lokasi untuk perangkat ini. Akses lokasi dapat diubah dari setelan lokasi."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Jika Anda menolak izin ini, fitur dasar perangkat mungkin tidak berfungsi lagi sesuai harapan."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Diterapkan menurut kebijakan"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Akses background dinonaktifkan oleh kebijakan"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Akses background diaktifkan oleh kebijakan"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Akses latar depan diaktifkan oleh kebijakan"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Dikontrol oleh admin"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Selalu"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Hanya saat menggunakan aplikasi"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Tidak pernah"</string>
-    <string name="loading" msgid="7811651799620593731">"Memuat…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Semua izin"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Kemampuan aplikasi lainnya"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Permintaan izin"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Hamparan layar terdeteksi"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Untuk mengubah setelan izin ini, terlebih dahulu Anda harus menonaktifkan hamparan layar dari Setelan &gt; Aplikasi"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Buka setelan"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Instal/Uninstal tidak didukung di Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Pilih item yang boleh diakses oleh &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; telah diperbarui. Pilih item yang boleh diakses oleh aplikasi ini."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Batal"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Lanjutkan"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Izin baru"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Izin saat ini"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Menyiapkan aplikasi..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Tidak dikenal"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Demi keamanan, TV tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Demi keamanan, TV tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Demi keamanan, ponsel tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Data pribadi dan ponsel lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan ponsel atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Data pribadi dan tablet lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan tablet atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Data pribadi dan TV lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan TV atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Lanjutkan"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Setelan"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Melakukan instal/uninstal aplikasi Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Installer paket"</string>
+    <string name="install" msgid="711829760615509273">"Instal"</string>
+    <string name="done" msgid="6632441120016885253">"Selesai"</string>
+    <string name="cancel" msgid="1018267193425558088">"Batal"</string>
+    <string name="installing" msgid="4921993079741206516">"Menginstal..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"Menginstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikasi terinstal."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Anda ingin menginstal aplikasi ini?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Apakah Anda ingin menginstal update ke aplikasi yang sudah ada? Data Anda yang ada saat ini tidak akan hilang."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Apakah Anda ingin menginstal update ke aplikasi bawaan? Data Anda yang ada saat ini tidak akan hilang."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikasi tidak terinstal."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paket diblokir sehingga tidak dapat diinstal."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikasi tidak diinstal karena paket ini bentrok dengan paket yang sudah ada."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikasi tidak diinstal karena aplikasi tidak kompatibel dengan tablet Anda."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Aplikasi ini tidak kompatibel dengan TV Anda."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikasi tidak diinstal karena aplikasi tidak kompatibel dengan ponsel Anda."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikasi tidak diinstal karena paket tampaknya tidak valid."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat diinstal pada tablet Anda."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat diinstal di TV Anda."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat diinstal pada ponsel Anda."</string>
+    <string name="launch" msgid="3952550563999890101">"Buka"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Admin Anda tidak mengizinkan penginstalan aplikasi yang didapatkan dari sumber tidak dikenal"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aplikasi yang tidak dikenal tidak dapat diinstal oleh pengguna ini"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Pengguna ini tidak diizinkan menginstal aplikasi"</string>
+    <string name="ok" msgid="7871959885003339302">"Oke"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Kelola aplikasi"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Kehabisan ruang penyimpanan"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat diinstal. Kosongkan sebagian ruang dan coba lagi."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikasi tidak ditemukan"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikasi tersebut tidak ditemukan di dalam daftar aplikasi yang terinstal."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Tidak diizinkan"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Pengguna saat ini tidak diizinkan meng-uninstal."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Aplikasi tidak dapat diinstal."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Uninstal aplikasi"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Uninstal update"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> adalah bagian dari aplikasi berikut:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Apakah Anda ingin meng-uninstal aplikasi ini?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Apakah Anda ingin meng-uninstal aplikasi ini untuk "<b>"semua"</b>" pengguna? Aplikasi dan datanya akan dihapus dari "<b>"semua"</b>" pengguna pada perangkat."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Apakah Anda ingin meng-uninstal aplikasi ini untuk pengguna <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Ganti aplikasi ini dengan versi setelan pabrik? Semua data akan dihapus."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Ganti aplikasi ini dengan versi setelan pabrik? Semua data akan dihapus. Tindakan ini memengaruhi semua pengguna perangkat ini, termasuk yang memiliki profil kerja."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Menjalankan proses uninstal"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Proses uninstal yang gagal"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Meng-uninstal..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Meng-uninstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Uninstal selesai."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> di-uninstal"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Uninstal gagal."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Gagal meng-uninstal <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Tidak dapat meng-uninstal aplikasi admin perangkat yang aktif"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Tidak dapat meng-uninstal aplikasi admin perangkat yang aktif untuk <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Aplikasi ini diperlukan oleh beberapa pengguna atau profil, dan telah di-uninstal untuk yang lainnya"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Aplikasi ini diperlukan untuk profil Anda dan tidak dapat di-uninstal."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Aplikasi ini diwajibkan oleh administrator perangkat &amp; tidak bisa di-uninstal."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Kelola aplikasi admin perangkat"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Kelola pengguna"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat di-uninstal."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Ada masalah saat mengurai paket."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Tindakan Instal/Uninstal tidak didukung di Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Menyiapkan aplikasi..."</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Tidak dikenal"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Demi keamanan, TV Anda tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Demi keamanan, TV Anda tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Demi keamanan, ponsel Anda tidak diizinkan menginstal aplikasi yang tidak dikenal dari sumber ini."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Ponsel dan data pribadi Anda lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan ponsel atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tablet dan data pribadi Anda lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan tablet atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV dan data pribadi Anda lebih rentan terhadap serangan oleh aplikasi yang tidak dikenal. Dengan menginstal aplikasi ini, Anda setuju bahwa Anda bertanggung jawab atas kerusakan TV atau kehilangan data yang mungkin diakibatkan oleh penggunaannya."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Lanjutkan"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Setelan"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Melakukan instal/uninstal aplikasi Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-is/strings.xml b/packages/PackageInstaller/res/values-is/strings.xml
index ea0bdcb..6921b7b 100644
--- a/packages/PackageInstaller/res/values-is/strings.xml
+++ b/packages/PackageInstaller/res/values-is/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Uppsetningarforrit pakka"</string>
-    <string name="next" msgid="3057143178373252333">"Áfram"</string>
-    <string name="install" msgid="5896438203900042068">"Setja upp"</string>
-    <string name="done" msgid="3889387558374211719">"Lokið"</string>
-    <string name="cancel" msgid="8360346460165114585">"Hætta við"</string>
-    <string name="installing" msgid="8613631001631998372">"Setur upp…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Setur upp <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Forritið er uppsett."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Viltu setja þetta forrit upp? Það mun fá aðgang að:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Viltu setja þetta forrit upp? Það krefst ekki neins sérstaks aðgangs."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Viltu setja upp uppfærslu á þessu uppsetta forriti? Eldri gögn glatast ekki. Uppfærða forritið mun fá aðgang að:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Viltu setja upp uppfærslu á þessu innbyggða forriti? Eldri gögn glatast ekki. Uppfærða forritið mun fá aðgang að:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Viltu setja upp uppfærslu á þessu uppsetta forriti? Eldri gögn glatast ekki. Forritið krefst ekki neins sérstaks aðgangs."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Viltu setja upp uppfærslu á þessu innbyggða forriti? Eldri gögn glatast ekki. Forritið krefst ekki neins sérstaks aðgangs."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Forritið er ekki uppsett."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Lokað var á uppsetningu pakkans."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Forritið var ekki sett upp vegna árekstra á milli pakkans og annars pakka."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Forritið var ekki sett upp því að forritið er ekki samhæft við spjaldtölvuna þína."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Þetta forrit er ekki samhæft við sjónvarpið."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Forritið var ekki sett upp því að forritið er ekki samhæft við símann þinn."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Forritið var ekki sett upp því að pakkinn virðist vera ógildur."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í spjaldtölvunni."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Ekki var hægt að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í sjónvarpinu."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í símanum."</string>
-    <string name="launch" msgid="4826921505917605463">"Opna"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Kerfisstjórinn leyfir ekki uppsetningu forrita af óþekktum uppruna"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Þessi notandi getur ekki sett upp óþekkt forrit"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Þessi notandi hefur ekki leyfi til að setja upp forrit"</string>
-    <string name="ok" msgid="3468756155452870475">"Í lagi"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Stjórna forritum"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Ekkert pláss eftir"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Ekki tókst að setja upp <xliff:g id="APP_NAME">%1$s</xliff:g>. Losaðu um pláss og reyndu aftur."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Forritið finnst ekki"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Forritið fannst ekki á listanum yfir uppsett forrit."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ekki heimilað"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Núverandi notandi hefur ekki heimild til að fjarlægja þetta."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Villa"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Ekki tókst að fjarlægja forritið."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Fjarlægja forrit"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Fjarlægja uppfærslu"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er hluti af þessu forriti:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Viltu fjarlægja þetta forrit?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Viltu fjarlægja þetta forrit hjá "<b>"öllum"</b>" notendum? Forritið og gögn þess verða fjarlægð hjá "<b>"öllum"</b>" notendum tækisins."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Viltu fjarlægja þetta forrit fyrir notandann <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Viltu skipta þessu forriti út fyrir verksmiðjuútgáfuna? Öll gögn verða fjarlægð."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Viltu skipta þessu forriti út fyrir verksmiðjuútgáfuna? Öll gögn verða fjarlægð. Þetta hefur áhrif á alla notendur tækisins, þar á meðal þá sem eru með vinnusnið."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Fjarlægingar í gangi"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Fjarlægingar sem mistókust"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Fjarlægir…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Fjarlægir <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Forritið hefur verið fjarlægt."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Fjarlægði <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Ekki tókst að fjarlægja forritið."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Ekki tókst að fjarlægja <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Ekki er hægt að fjarlægja virkt forrit tækjastjóra"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Ekki er hægt að fjarlægja virkt forrit tækjastjóra fyrir <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Þessa forrits er krafist hjá sumum notendum eða sniðum en var fjarlægt hjá öðrum"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Sniðið þitt krefst þessa forrits og ekki er hægt að fjarlægja það."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Stjórnandi tækisins krefst þessa forrits og ekki er hægt að fjarlægja það."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Stjórna forritum tækjastjóra"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Stjórna notendum"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Ekki tókst að fjarlægja <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Vandamál kom upp við að vinna úr pakkanum."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nýjar"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Allar"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Persónuvernd"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Tækisaðgangur"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Þessi uppfærsla krefst engra nýrra heimilda."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Hafna"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Frekari upplýsingar"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Hafna samt"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> af <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Leyfa forritinu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; að <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Viltu alltaf veita &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; leyfi til að <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Aðeins þegar forrit er í notkun"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Alltaf"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Hafna og ekki spyrja aftur"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> óvirkar"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"allar óvirkar"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"engin óvirk"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Leyfa"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Forrit"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Heimildir forrits"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ekki spyrja aftur"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Engar heimildir"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Viðbótarheimildir"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Opna upplýsingar um forrit"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> í viðbót</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> í viðbót</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Þetta forrit var hannað fyrir eldri útgáfu af Android. Ef því er ekki veitt heimild er hugsanlegt að það virki ekki rétt."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"framkvæma óþekkta aðgerð"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> forrit af <xliff:g id="COUNT_1">%2$d</xliff:g> leyfð"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Sýna kerfisforrit"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Fela kerfisforrit"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Engin forrit"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Staðsetningarstillingar"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> býður upp á staðsetningarþjónustu fyrir þetta tæki. Hægt er að breyta aðgangi að staðsetningu í stillingum staðsetningar."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ef þú veitir ekki þessa heimild getur verið að grunneiginleikar tækisins virki ekki lengur sem skyldi."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Stjórnað af reglu"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Bakgrunnsaðgangur óvirkur vegna reglu"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Bakgrunnsaðgangur virkur vegna reglu"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Forgrunnsaðgangur virkur vegna reglu"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Stjórnað af kerfisstjóra"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Alltaf"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Aðeins þegar forrit er í notkun"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Aldrei"</string>
-    <string name="loading" msgid="7811651799620593731">"Hleður…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Allar heimildir"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Aðrir forritseiginleikar"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Beiðni um heimild"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Skjáyfirlögn greindist"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Til að breyta þessari heimildarstillingu þarftu fyrst að slökkva á skjáyfirlögn undir Stillingar &gt; Forrit"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Opna stillingar"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Aðgerðir til að setja upp / fjarlægja eru ekki studdar í Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Veldu hverju &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; fær aðgang að"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; hefur verið uppfært. Veldu hverju forritið fær aðgang að."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Hætta við"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Halda áfram"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nýjar heimildir"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Núgildandi heimildir"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Setur upp forrit…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Óþekkt"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Til að tryggja öryggi þitt er ekki heimild í spjaldtölvunni þinni fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Til að tryggja öryggi þitt er ekki heimild í sjónvarpinu þínu fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Til að tryggja öryggi þitt er ekki heimild í símanum þínum fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Síminn þinn og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á símanum eða gagnatapi sem leiða kann af notkun þess."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Spjaldtölvan þín og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á spjaldtölvunni eða gagnatapi sem leiða kann af notkun þess."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Sjónvarpið þitt og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á sjónvarpinu eða gagnatapi sem leiða kann af notkun þess."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Áfram"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Stillingar"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Uppsetning/fjarlæging Wear forrita"</string>
+    <string name="app_name" msgid="7488448184431507488">"Uppsetningarforrit pakka"</string>
+    <string name="install" msgid="711829760615509273">"Setja upp"</string>
+    <string name="done" msgid="6632441120016885253">"Lokið"</string>
+    <string name="cancel" msgid="1018267193425558088">"Hætta við"</string>
+    <string name="installing" msgid="4921993079741206516">"Setur upp…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Setur <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> upp…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Forritið er uppsett."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Viltu setja þetta forrit upp?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Viltu setja upp uppfærslu á þessu uppsetta forriti? Eldri gögn glatast ekki."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Viltu setja upp uppfærslu á þessu innbyggða forriti? Eldri gögn glatast ekki."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Forritið er ekki uppsett."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Lokað var á uppsetningu pakkans."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Forritið var ekki sett upp vegna árekstra á milli pakkans og annars pakka."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Forritið var ekki sett upp því að forritið er ekki samhæft við spjaldtölvuna þína."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Þetta forrit er ekki samhæft við sjónvarpið."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Forritið var ekki sett upp því að forritið er ekki samhæft við símann þinn."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Forritið var ekki sett upp því að pakkinn virðist vera ógildur."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í spjaldtölvunni."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í sjónvarpinu."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp í símanum."</string>
+    <string name="launch" msgid="3952550563999890101">"Opna"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Kerfisstjórinn leyfir ekki uppsetningu forrita af óþekktum uppruna"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Þessi notandi getur ekki sett upp óþekkt forrit"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Þessi notandi hefur ekki leyfi til að setja upp forrit"</string>
+    <string name="ok" msgid="7871959885003339302">"Í lagi"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Stj. forritum"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Ekkert pláss eftir"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Ekki tókst að setja <xliff:g id="APP_NAME">%1$s</xliff:g> upp. Losaðu um pláss og reyndu aftur."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Forritið finnst ekki"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Forritið fannst ekki á listanum yfir uppsett forrit."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Ekki heimilað"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Núverandi notandi hefur ekki heimild til að fjarlægja þetta."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Villa"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Ekki tókst að fjarlægja forritið."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Fjarlægja forrit"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Fjarlægja uppfærslu"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er hluti af þessu forriti:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Viltu fjarlægja þetta forrit?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Viltu fjarlægja þetta forrit hjá "<b>"öllum"</b>" notendum? Forritið og gögn þess verða fjarlægð hjá "<b>"öllum"</b>" notendum tækisins."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Viltu fjarlægja þetta forrit fyrir notandann <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Viltu skipta þessu forriti út fyrir verksmiðjuútgáfuna? Öll gögn verða fjarlægð."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Viltu skipta þessu forriti út fyrir verksmiðjuútgáfuna? Öll gögn verða fjarlægð. Þetta hefur áhrif á alla notendur tækisins, þar á meðal þá sem eru með vinnusnið."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Fjarlægingar í gangi"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Fjarlægingar sem mistókust"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Fjarlægir…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Fjarlægir <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Forritið hefur verið fjarlægt."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Fjarlægði <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Ekki tókst að fjarlægja forritið."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Ekki tókst að fjarlægja <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Ekki er hægt að fjarlægja virkt forrit tækjastjóra"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Ekki er hægt að fjarlægja virkt forrit tækjastjóra fyrir <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Þessa forrits er krafist hjá sumum notendum eða sniðum en það var fjarlægt hjá öðrum"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Sniðið þitt krefst þessa forrits og ekki er hægt að fjarlægja það."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Stjórnandi tækisins krefst þessa forrits og ekki er hægt að fjarlægja það."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Stjórna forritum tækjastjóra"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Stjórna notendum"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Ekki tókst að fjarlægja <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Vandamál kom upp við að vinna úr pakkanum."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Aðgerðir til að setja upp / fjarlægja eru ekki studdar í Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Setur upp forrit…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Óþekkt"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Til að tryggja öryggi þitt er ekki heimild í spjaldtölvunni þinni fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Til að tryggja öryggi þitt er ekki heimild í sjónvarpinu þínu fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Til að tryggja öryggi þitt er ekki heimild í símanum þínum fyrir uppsetningu óþekktra forrita frá þessari veitu."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Síminn þinn og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á símanum eða gagnatapi sem leiða kann af notkun þess."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Spjaldtölvan þín og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á spjaldtölvunni eða gagnatapi sem leiða kann af notkun þess."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Sjónvarpið þitt og persónuleg gögn eru berskjaldaðri fyrir árásum forrita af óþekktum uppruna. Með uppsetningu þessa forrits samþykkirðu að bera fulla ábyrgð á hverju því tjóni sem verða kann á sjónvarpinu eða gagnatapi sem leiða kann af notkun þess."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Áfram"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Stillingar"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Uppsetning/fjarlæging Wear forrita"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-it/strings.xml b/packages/PackageInstaller/res/values-it/strings.xml
index 5870722..b44d6ea 100644
--- a/packages/PackageInstaller/res/values-it/strings.xml
+++ b/packages/PackageInstaller/res/values-it/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Installazione pacchetti"</string>
-    <string name="next" msgid="3057143178373252333">"Avanti"</string>
-    <string name="install" msgid="5896438203900042068">"Installa"</string>
-    <string name="done" msgid="3889387558374211719">"Fine"</string>
-    <string name="cancel" msgid="8360346460165114585">"Annulla"</string>
-    <string name="installing" msgid="8613631001631998372">"Installazione..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installazione di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App installata."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Vuoi installare questa applicazione? Avrà accesso a:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vuoi installare questa applicazione? Non richiede alcun accesso speciale."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Vuoi installare un aggiornamento per questa applicazione esistente? I tuoi dati esistenti non andranno persi. L\'applicazione aggiornata avrà accesso a:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vuoi installare un aggiornamento per questa applicazione integrata? I tuoi dati esistenti non andranno persi. L\'applicazione aggiornata avrà accesso a:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vuoi installare un aggiornamento di questa applicazione esistente? I dati correnti verranno conservati. Non occorrono accessi speciali."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vuoi installare un aggiornamento di questa applicazione integrata? I dati correnti verranno conservati. Non occorrono accessi speciali."</string>
-    <string name="install_failed" msgid="6579998651498970899">"App non installata."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"È stata bloccata l\'installazione del pacchetto."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"App non installata poiché il pacchetto è in conflitto con un pacchetto esistente."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App non installata poiché non compatibile con il tuo tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Questa app non è compatibile con la tua TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App non installata poiché non compatibile con il tuo telefono."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"App non installata poiché il pacchetto risulta non valido."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sul tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sulla tua TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sul telefono."</string>
-    <string name="launch" msgid="4826921505917605463">"Apri"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"L\'amministratore non consente l\'installazione di app ottenute da fonti sconosciute"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Questo utente non può installare app sconosciute"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"L\'utente non è autorizzato a installare app"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Gestisci applicazioni"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Spazio esaurito"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera dello spazio e riprova."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Applicazione non trovata"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Impossibile trovare l\'applicazione nell\'elenco di applicazioni installate."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Non autorizzato"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"L\'utente corrente non è autorizzato a eseguire questa disinstallazione."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Errore"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Impossibile disinstallare l\'app."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Disinstalla applicazione"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Disinstalla aggiornamento"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fa parte della seguente applicazione:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Vuoi disinstallare questa applicazione?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vuoi disinstallare questa applicazione per "<b>"tutti"</b>" gli utenti? L\'applicazione e i relativi dati verranno rimossi da "<b>"tutti"</b>" gli utenti configurati sul dispositivo."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Disinstallare l\'app per l\'utente <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Sostituire questa app con la versione di fabbrica? Tutti i dati verranno rimossi."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Sostituire questa app con la versione di fabbrica? Tutti i dati verranno rimossi. Saranno interessati tutti gli utenti del dispositivo, inclusi quelli che hanno profili di lavoro."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Disinstallazioni attuali"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Disinstallazioni non riuscite"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Disinstallazione..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Disinstallazione di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Disinstallazione completata."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"App <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> disinstallata"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Disinstallazione non riuscita."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Impossibile disinstallare <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Impossibile disinstallare l\'app di amministrazione del dispositivo attiva"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Impossibile disinstallare l\'app di amministrazione del dispositivo attiva per <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"L\'app è necessaria per alcuni utenti/profili ed è stata disinstallata per altri"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"L\'app è necessaria per il tuo profilo e non può essere disinstallata."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"App richiesta dall\'amministratore del dispositivo. Non può essere disinstallata."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gestisci app di amministrazione del dispositivo"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gestisci utenti"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Impossibile disinstallare <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Errore durante l\'analisi del pacchetto."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nuove"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Tutte"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Accesso dispositivo"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Questo aggiornamento non richiede nuove autorizzazioni."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Nega"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Altre informazioni"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Nega comunque"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> di <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Consentire a &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vuoi consentire sempre all\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; di <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Solo durante l\'uso dell\'app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Nega e non chiedermelo più"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> disattivate"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"tutte disattivate"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"nessuna disattivata"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Consenti"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"App"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Autorizzazioni app"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Non chiedermelo più"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Nessuna autorizzazione"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Altre autorizzazioni"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Visualizza informazioni sull\'app"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Altre <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> altra</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Questa app è stata sviluppata per una versione precedente di Android. Se l\'autorizzazione viene negata, l\'app potrebbe non funzionare più come previsto."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"esegue un\'azione sconosciuta"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Sono consentite <xliff:g id="COUNT_0">%1$d</xliff:g> app su <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Mostra app di sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Nascondi app di sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nessuna app"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Geolocalizzazione"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> è un fornitore di servizi di geolocalizzazione per questo dispositivo. È possibile modificare l\'accesso alla posizione dalle impostazioni sulla posizione."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Se neghi questa autorizzazione, le funzionalità di base del dispositivo potrebbero non funzionare più come previsto."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Applicata in base alle norme"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Accesso in background disattivato in base alla norma"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Accesso in background attivato in base alla norma"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Accesso in primo piano attivato in base alla norma"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Gestita dall\'amministratore"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Solo durante l\'uso dell\'app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Mai"</string>
-    <string name="loading" msgid="7811651799620593731">"Caricamento…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Tutte le autorizzazioni"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Altre funzionalità dell\'app"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Richiesta di autorizzazione"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Overlay schermo rilevato"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Per modificare questa impostazione di autorizzazione, devi innanzitutto disattivare l\'overlay schermo da Impostazioni &gt; App"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Apri impostazioni"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Le azioni di installazione/disinstallazione non sono supportate su Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Scegli i dati a cui l\'app <xliff:g id="APP_NAME">%1$s</xliff:g> può accedere"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"L\'app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; è stata aggiornata. Scegli i dati a cui può accedere."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Annulla"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continua"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nuove autorizzazioni"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Autorizzazioni correnti"</string>
-    <string name="message_staging" msgid="6151794817691100003">"App in preparazione…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Sconosciuto"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Per sicurezza, il tuo tablet non è autorizzato a installare app sconosciute da questa origine."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Per sicurezza, la tua TV non è autorizzata a installare app sconosciute da questa origine."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Per sicurezza, il tuo telefono non è autorizzato a installare app sconosciute da questa origine."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"I dati del telefono e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni al telefono o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"I dati del tablet e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni al tablet o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"I dati della TV e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni alla TV o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continua"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Impostazioni"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installazione/disinstallazione di app Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Installazione pacchetti"</string>
+    <string name="install" msgid="711829760615509273">"Installa"</string>
+    <string name="done" msgid="6632441120016885253">"Fine"</string>
+    <string name="cancel" msgid="1018267193425558088">"Annulla"</string>
+    <string name="installing" msgid="4921993079741206516">"Installazione…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installazione di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App installata."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Installare questa applicazione?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Vuoi installare un aggiornamento a questa applicazione esistente? I tuoi dati non andranno persi."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Vuoi installare un aggiornamento per questa applicazione integrata? I tuoi dati non andranno persi."</string>
+    <string name="install_failed" msgid="5777824004474125469">"App non installata."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"È stata bloccata l\'installazione del pacchetto."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"App non installata poiché il pacchetto è in conflitto con un pacchetto esistente."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"App non installata poiché non compatibile con il tuo tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Questa app non è compatibile con la tua TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"App non installata poiché non compatibile con il tuo telefono."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"App non installata poiché il pacchetto risulta non valido."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sul tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sulla TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g> sul telefono."</string>
+    <string name="launch" msgid="3952550563999890101">"Apri"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"L\'amministratore non consente l\'installazione di app ottenute da fonti sconosciute"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Questo utente non può installare app sconosciute"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"L\'utente non è autorizzato a installare app"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gestisci app"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Spazio esaurito"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Impossibile installare <xliff:g id="APP_NAME">%1$s</xliff:g>. Libera dello spazio e riprova."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App non trovata"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Impossibile trovare l\'applicazione nell\'elenco di applicazioni installate."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Non consentita"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"L\'utente corrente non è autorizzato a eseguire questa disinstallazione."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Errore"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Impossibile disinstallare l\'app."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Disinstalla app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Disinstalla aggiornamento"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> fa parte della seguente applicazione:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Vuoi disinstallare questa app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Vuoi disinstallare questa applicazione per "<b>"tutti"</b>" gli utenti? L\'applicazione e i relativi dati verranno rimossi da "<b>"tutti"</b>" gli utenti configurati sul dispositivo."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Disinstallare l\'app per l\'utente <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Sostituire questa app con la versione di fabbrica? Tutti i dati verranno rimossi."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Sostituire questa app con la versione di fabbrica? Tutti i dati verranno rimossi. Saranno interessati tutti gli utenti del dispositivo, inclusi quelli che hanno profili di lavoro."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Disinstallazioni in esecuzione"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Disinstallazioni non riuscite"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Disinstallazione…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Disinstallazione di <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Disinstallazione completata."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"App <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> disinstallata"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Disinstallazione non riuscita."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Impossibile disinstallare <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Impossibile disinstallare l\'app di amministrazione del dispositivo attiva"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Impossibile disinstallare l\'app di amministrazione del dispositivo attiva per <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"L\'app è necessaria per alcuni utenti/profili ed è stata disinstallata per altri"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"L\'app è necessaria per il tuo profilo e non può essere disinstallata."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"App richiesta dall\'amministratore del dispositivo. Non può essere disinstallata."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gestisci app di amministrazione del dispositivo"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gestisci utenti"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Impossibile disinstallare <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Errore durante l\'analisi del pacchetto."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Le azioni di installazione/disinstallazione non sono supportate su Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"App in preparazione…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Sconosciuto"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Per sicurezza, il tuo tablet non è autorizzato a installare app sconosciute da questa origine."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Per sicurezza, la tua TV non è autorizzata a installare app sconosciute da questa origine."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Per sicurezza, il tuo telefono non è autorizzato a installare app sconosciute da questa origine."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"I dati del telefono e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni al telefono o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"I dati del tablet e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni al tablet o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"I dati della TV e i dati personali sono più vulnerabili agli attacchi di app sconosciute. Se installi questa app, accetti di essere responsabile degli eventuali danni alla TV o dell\'eventuale perdita di dati derivanti dall\'uso dell\'app."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continua"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Impostazioni"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installazione/disinstallazione app Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-iw/strings.xml b/packages/PackageInstaller/res/values-iw/strings.xml
index 414fe4c..573f12a 100644
--- a/packages/PackageInstaller/res/values-iw/strings.xml
+++ b/packages/PackageInstaller/res/values-iw/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"מתקין החבילה"</string>
-    <string name="next" msgid="3057143178373252333">"הבא"</string>
-    <string name="install" msgid="5896438203900042068">"התקן"</string>
-    <string name="done" msgid="3889387558374211719">"סיום"</string>
-    <string name="cancel" msgid="8360346460165114585">"ביטול"</string>
-    <string name="installing" msgid="8613631001631998372">"מתקין..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"מתקין את <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"האפליקציה הותקנה."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"האם ברצונך להתקין את האפליקציה? היא תקבל גישה אל:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"האם ברצונך להתקין את האפליקציה? היא אינה דורשת גישה מיוחדת."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"האם ברצונך להתקין עדכון לאפליקציה קיימת זו? הנתונים הקיימים שלך לא יאבדו. האפליקציה המעודכנת תקבל גישה אל:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"האם ברצונך להתקין עדכון לאפליקציה מובנית זו? הנתונים הקיימים שלך לא יאבדו. האפליקציה המעודכנת תקבל גישה אל:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"האם ברצונך להתקין עדכון עבור אפליקציה קיימת זו? הנתונים הקיימים שלך לא יאבדו. אין צורך בגישה מיוחדת."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"האם ברצונך להתקין עדכון עבור אפליקציה מובנית זו? הנתונים הקיימים שלך לא יאבדו. אין צורך בגישה מיוחדת."</string>
-    <string name="install_failed" msgid="6579998651498970899">"האפליקציה לא הותקנה."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"החבילה נחסמה להתקנה."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"האפליקציה לא הותקנה כי החבילה מתנגשת עם חבילה קיימת."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטאבלט."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"האפליקציה הזו אינה תואמת לטלוויזיה שלך."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטלפון."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"האפליקציה לא הותקנה כי נראה שהחבילה לא תקפה."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטאבלט שלך."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטלוויזיה שלך."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטלפון שלך."</string>
-    <string name="launch" msgid="4826921505917605463">"פתח"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"מנהל המערכת שלך לא מתיר התקנה של אפליקציות ממקורות לא ידועים"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"למשתמש זה אין הרשאה להתקין אפליקציות שאינן מוכרות"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"למשתמש הזה אין הרשאה להתקין אפליקציות"</string>
-    <string name="ok" msgid="3468756155452870475">"אישור"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"נהל אפליקציות"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"אין מספיק שטח"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g>. פנה שטח ונסה שוב."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"האפליקציה לא נמצא"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"האפליקציה לא נמצאה ברשימת האפליקציות המותקנות."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"לא מורשה"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"המשתמש הנוכחי אינו מורשה להסיר את ההתקנה הזו."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"שגיאה"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"לא ניתן היה להסיר את התקנת האפליקציה."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"הסר את התקנת האפליקציה"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"הסר את התקנת העדכון"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> הוא חלק מהאפליקציה הבאה:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"האם ברצונך להסיר את ההתקנה של אפליקציה זו?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"האם אתה רוצה להסיר את האפליקציה הזו עבור "<b>"כל"</b>" המשתמשים? האפליקציה והנתונים שלה יוסרו מ"<b>"כל"</b>" המשתמשים במכשיר."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"האם ברצונך להסיר את התקנתה של אפליקציה זו עבור המשתמש <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"האם להחליף את האפליקציה הזאת בגירסת היצרן? כל הנתונים יוסרו."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"האם להחליף את האפליקציה הזאת בגירסת היצרן? כל הנתונים יוסרו. הפעולה תשפיע על כל משתמשי המכשיר, כולל משתמשים בעלי פרופיל עבודה."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"התקנות בתהליכי הסרה"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"הסרות התקנה שנכשלו"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"מסיר התקנה..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"מסיר את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"הסרת ההתקנה הסתיימה."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> הוסרה"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"הסרת התקנה נכשלה."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"נכשלה הסרת ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"לא ניתן להסיר את ההתקנה של אפליקציה פעילה של מנהל המכשיר"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"לא ניתן להסיר את ההתקנה של אפליקציה פעילה של מנהל המכשיר של <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"אפליקציה זו נדרשת לחלק מהמשתמשים או מהפרופילים והתקנתה הוסרה למשתמשים אחרים"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"האפליקציה הזו נחוצה לפרופיל שלך ולא ניתן להסיר את ההתקנה שלה."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"מנהל המכשיר שלך מחייב את קיומה של אפליקציה זו, ולא ניתן להסירה."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"אפליקציות למנהל המערכת של מכשיר מנוהל"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ניהול משתמשים"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"לא ניתן להסיר את ההתקנה של <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"אירעה בעיה בניתוח החבילה."</string>
-    <string name="newPerms" msgid="6039428254474104210">"חדש"</string>
-    <string name="allPerms" msgid="1024385515840703981">"הכל"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"פרטיות"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"גישה למכשיר"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"עדכון זה לא דורש הרשאות חדשות."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"לא, תודה"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"למידע נוסף"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"לדחות בכל מקרה"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> מתוך <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"‏האם לאשר ל&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"‏תמיד להרשות לאפליקציה &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"רק בזמן השימוש באפליקציה"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"תמיד"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"יש לדחות ואין לשאול שוב"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> הרשאות מושבתות"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"כל ההרשאות מושבתות"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"אין הרשאות מושבתות"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"כן, זה בסדר"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"אפליקציות"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"הרשאות לאפליקציות"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"ראיתי פעם אחת, זה מספיק"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"אין הרשאות"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"הרשאות נוספות"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"פתיחה של פרטי האפליקציה"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="two">עוד <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="many">עוד <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">עוד <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">עוד <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"‏האפליקציה הזו עוצבה בשביל גרסה ישנה יותר של Android. דחיית ההרשאה עשויה לגרום לה לתפקד בצורה לקויה."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ביצוע פעולה לא ידועה"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> מתוך <xliff:g id="COUNT_1">%2$d</xliff:g> אפליקציות קיבלו הרשאה"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"הרשאות המערכת"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"הסתר מערכת"</string>
-    <string name="no_apps" msgid="1965493419005012569">"אין אפליקציות"</string>
-    <string name="location_settings" msgid="1774875730854491297">"הגדרות מיקום"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> הוא ספק של שירותי מיקום בשביל המכשיר הזה. אפשר לשנות את גישת המיקום בהגדרות המיקום."</string>
-    <string name="system_warning" msgid="7103819124542305179">"אם תדחה את ההרשאה הזו, ייתכן שתכונות בסיסיות במכשיר לא יפעלו כצפוי."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"נאכף באמצעות מדיניות"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"הגישה ברקע מושבתת על ידי מדיניות"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"הגישה ברקע מופעלת על ידי מדיניות"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"הגישה בחזית מופעלת על ידי מדיניות"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"נמצא בשליטת מנהל מערכת"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"תמיד"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"רק בזמן השימוש באפליקציה"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"אף פעם"</string>
-    <string name="loading" msgid="7811651799620593731">"טוען..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"כל ההרשאות"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"הרשאות אחרות של האפליקציה"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"בקשת הרשאה"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"זוהתה שכבת על במסך"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"‏כדי לשנות את הגדרת ההרשאה הזו, ראשית עליך לכבות את שכבת העל במסך ב\'הגדרות\' &gt; \'אפליקציות\'"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"פתח הגדרות"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"‏פעולות התקנה/הסרת התקנה אינן נתמכות ב-Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"‏בחר אילו הרשאות גישה ברצונך לתת ל &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; עודכנה. בחר אילו הרשאות גישה יהיו לאפליקציה זו."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"ביטול"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"המשך"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"הרשאות חדשות"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"הרשאות קיימות"</string>
-    <string name="message_staging" msgid="6151794817691100003">"מכין אפליקציה להתקנה…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"לא ידוע"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"לצורכי אבטחה, הטאבלט שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"לצורכי אבטחה, מכשיר הטלוויזיה שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"לצורכי אבטחה, הטלפון שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"נתוני הטלפון והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטלפון שלך בעקבות השימוש באפליקציה."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"נתוני הטאבלט והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטאבלט שלך בעקבות השימוש באפליקציה."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"נתוני הטלוויזיה והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטלוויזיה שלך בעקבות השימוש באפליקציה."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"המשך"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"הגדרות"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"‏מתקין/מסיר התקנה של אפליקציות Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"מתקין החבילה"</string>
+    <string name="install" msgid="711829760615509273">"התקנה"</string>
+    <string name="done" msgid="6632441120016885253">"סיום"</string>
+    <string name="cancel" msgid="1018267193425558088">"ביטול"</string>
+    <string name="installing" msgid="4921993079741206516">"מתקין…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"מתקין את <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"האפליקציה הותקנה."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"האם ברצונך להתקין אפליקציה זו?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"האם ברצונך להתקין עדכון עבור אפליקציה קיימת זו? הנתונים הקיימים שלך לא יאבדו."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"האם ברצונך להתקין עדכון עבור אפליקציה מובנית זו? הנתונים הקיימים שלך לא יאבדו."</string>
+    <string name="install_failed" msgid="5777824004474125469">"האפליקציה לא הותקנה."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"החבילה נחסמה להתקנה."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"האפליקציה לא הותקנה כי החבילה מתנגשת עם חבילה קיימת."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטאבלט."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"האפליקציה הזו אינה תואמת לטלוויזיה שלך."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"האפליקציה לא הותקנה כי האפליקציה אינה תואמת לטלפון."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"האפליקציה לא הותקנה כי נראה שהחבילה לא תקפה."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g> בטאבלט שלך."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"למשתמש זה אין הרשאה להתקין אפליקציות שאינן מוכרות"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"למשתמש הזה אין הרשאה להתקין אפליקציות"</string>
+    <string name="ok" msgid="7871959885003339302">"אישור"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"ניהול אפליקציות"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"אין מספיק שטח"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"לא ניתן להתקין את <xliff:g id="APP_NAME">%1$s</xliff:g>. יש לפנות שטח ולנסות שוב."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"האפליקציה לא נמצאה"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"האפליקציה לא נמצאת ברשימת האפליקציות המותקנות."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"לא מורשה"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"המשתמש הנוכחי אינו מורשה להסיר את ההתקנה הזו."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"שגיאה"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"לא ניתן היה להסיר את התקנת האפליקציה."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"הסרת התקנה של האפליקציה"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"הסרת התקנה של עדכון"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> הוא חלק מהאפליקציה הבאה:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"האם ברצונך להסיר את ההתקנה של אפליקציה זו?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"האם אתה רוצה להסיר את האפליקציה הזו עבור "<b>"כל"</b>" המשתמשים? האפליקציה והנתונים שלה יוסרו מ"<b>"כל"</b>" המשתמשים במכשיר."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"האם ברצונך להסיר את התקנתה של אפליקציה זו עבור המשתמש <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"האם להחליף את האפליקציה הזאת בגרסת היצרן? כל הנתונים יוסרו."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"האם להחליף את האפליקציה הזאת בגרסת היצרן? כל הנתונים יוסרו. הפעולה תשפיע על כל משתמשי המכשיר, כולל משתמשים בעלי פרופיל עבודה."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"התקנות בתהליכי הסרה"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"הסרות התקנה שנכשלו"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"מסיר התקנה..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"מסיר את ההתקנה של <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"הסרת ההתקנה הסתיימה."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"‏פעולות התקנה/הסרת התקנה אינן נתמכות ב-Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"מכין אפליקציה להתקנה…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"לא ידוע"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"לצורכי אבטחה, הטאבלט שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"לצורכי אבטחה, מכשיר הטלוויזיה שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"לצורכי אבטחה, הטלפון שלך חסום להתקנת אפליקציות בלתי מוכרות המגיעות ממקור זה."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"נתוני הטלפון והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטלפון שלך בעקבות השימוש באפליקציה."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"נתוני הטאבלט והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטאבלט שלך בעקבות השימוש באפליקציה."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"נתוני הטלוויזיה והנתונים האישיים שלך חשופים יותר בפני התקפות על ידי אפליקציות ממקורות לא ידועים. אם תתקין אפליקציה זו, אתה מסכים לכך שאתה האחראי הבלעדי במקרה של אובדן נתונים או אם ייגרם נזק לטלוויזיה שלך בעקבות השימוש באפליקציה."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"המשך"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"הגדרות"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"‏מתקין/מסיר התקנה של אפליקציות Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml
index 5a7dc7d..42f1b3f 100644
--- a/packages/PackageInstaller/res/values-ja/strings.xml
+++ b/packages/PackageInstaller/res/values-ja/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"パッケージインストーラ"</string>
-    <string name="next" msgid="3057143178373252333">"次へ"</string>
-    <string name="install" msgid="5896438203900042068">"インストール"</string>
-    <string name="done" msgid="3889387558374211719">"完了"</string>
-    <string name="cancel" msgid="8360346460165114585">"キャンセル"</string>
-    <string name="installing" msgid="8613631001631998372">"インストール中..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をインストールしています…"</string>
-    <string name="install_done" msgid="3682715442154357097">"アプリをインストールしました。"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"このアプリケーションをインストールしてもよろしいですか?このアプリケーションは下記にアクセスする場合があります:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"このアプリケーションをインストールしてもよろしいですか?このアプリケーションは特別なアクセス許可を必要としません。"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"この既存のアプリケーションへのアップデートをインストールしてもよろしいですか?既存のデータは失われません。アップデート後のアプリケーションは下記にアクセスする場合があります:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"この内蔵アプリケーションへのアップデートをインストールしてもよろしいですか?既存のデータは失われません。アップデート後のアプリケーションは下記にアクセスする場合があります:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"この既存のアプリにアップデートをインストールしますか?既存のデータが失われることはありません。特別なアクセス権も必要ありません。"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"この内蔵アプリにアップデートをインストールしますか?既存のデータが失われることはありません。特別なアクセス権も必要ありません。"</string>
-    <string name="install_failed" msgid="6579998651498970899">"アプリはインストールされていません。"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"パッケージのインストールはブロックされています。"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"パッケージが既存のパッケージと競合するため、アプリをインストールできませんでした。"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"お使いのタブレットに対応していないため、アプリをインストールできませんでした。"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"このアプリはお使いのテレビに対応していません。"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"お使いのスマートフォンに対応していないため、アプリをインストールできませんでした。"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"パッケージが無効の可能性があるため、アプリをインストールできませんでした。"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>をタブレットにインストールできませんでした。"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>をテレビにインストールできませんでした。"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>を端末にインストールできませんでした。"</string>
-    <string name="launch" msgid="4826921505917605463">"開く"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"提供元不明のアプリをインストールすることは、管理者により禁止されています"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"このユーザーは不明なアプリをインストールできません"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"このユーザーはアプリをインストールできません"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"アプリを管理"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"容量不足です"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>をインストールできませんでした。空き容量を増やしてもう一度お試しください。"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"アプリが見つかりません"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"インストール済みアプリのリストに、このアプリはありません。"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"許可されていません"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"このアンインストール操作は現在のユーザーには許可されていません。"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"エラー"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"アプリをアンインストールできませんでした。"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"アプリをアンインストール"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"アップデートをアンインストール"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>は次のアプリの一部です:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"このアプリをアンインストールしますか?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"このアプリを"<b>"すべての"</b>"ユーザーからアンインストールしますか?このアプリとそのデータは端末の"<b>"すべての"</b>"ユーザーから削除されます。"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g>さんのアプリをアンインストールしますか?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"このアプリを出荷時の状態に戻しますか?データがすべて削除されます。"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"このアプリを出荷時の状態に戻しますか?データがすべて削除されます。これは、仕事用プロファイルを設定しているユーザーも含めて、この端末を使用するすべてのユーザーが対象となります。"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"実行中のアンインストール"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"エラーになったアンインストール"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"アンインストール中..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしています…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"アンインストールが完了しました。"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしました"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"アンインストールできませんでした。"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールできませんでした。"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"有効な端末管理アプリをアンインストールできません"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> さんの有効な端末管理アプリをアンインストールできません"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"このアプリは一部のユーザーやプロファイルに必要なため、アンインストールできませんでした"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"このアプリはプロファイルに必要なため、アンインストールできません。"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"このアプリは端末管理者が必要としているため、アンインストールできません。"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"端末管理アプリを管理"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ユーザーを管理"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>をアンインストールできませんでした。"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"パッケージの解析中に問題が発生しました。"</string>
-    <string name="newPerms" msgid="6039428254474104210">"New"</string>
-    <string name="allPerms" msgid="1024385515840703981">"すべて"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"プライバシー"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"端末アクセス"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"このアップデートでは新たな許可は必要ありません。"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"許可しない"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"詳細"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"許可しない"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に<xliff:g id="ACTION">%2$s</xliff:g>を許可しますか?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"「<xliff:g id="ACTION">%2$s</xliff:g>」を &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; に常に許可しますか?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"アプリの使用中のみ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"常時"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"許可しない(次回から表示しない)"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> 件無効"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"すべて無効"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"無効な権限なし"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"許可"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"アプリ"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"アプリの権限"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"今後表示しない"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"権限がありません"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"その他の権限"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"アプリ情報を開く"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">他<xliff:g id="COUNT_1">%1$d</xliff:g>件</item>
-      <item quantity="one">他<xliff:g id="COUNT_0">%1$d</xliff:g>件</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"このアプリはAndroidの以前のバージョンを対象としています。権限を許可しないと、意図されたとおりに動作しなくなる可能性があります。"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"不明な操作の実行"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>個のアプリを許可"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"システムを表示"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"システムを表示しない"</string>
-    <string name="no_apps" msgid="1965493419005012569">"アプリなし"</string>
-    <string name="location_settings" msgid="1774875730854491297">"位置情報の設定"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g>はこの端末の位置情報サービスのプロバイダです。位置情報アクセスは位置情報の設定から変更できます。"</string>
-    <string name="system_warning" msgid="7103819124542305179">"この権限を許可しないと、お使いの端末の基本的な機能が意図されたとおりに動作しなくなる可能性があります。"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ポリシーにより適用"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"バックグラウンドでのアクセスはポリシーによって無効です"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"バックグラウンドでのアクセスはポリシーによって有効です"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"フォアグラウンドでのアクセスはポリシーによって有効です"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"管理者により管理されています"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"常時"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"アプリの使用中のみ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"なし"</string>
-    <string name="loading" msgid="7811651799620593731">"読み込んでいます…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"すべての権限"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"その他のアプリ機能"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"権限のリクエスト"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"画面オーバーレイを検出"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"この権限設定を変更するには、まず[設定]&gt;[アプリ]から画面オーバーレイをOFFにします"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"設定を開く"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ではインストールやアンインストールができません"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」に許可する権限の選択"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"「&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;」が更新されました。このアプリに許可する権限を選択してください。"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"キャンセル"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"続行"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"新しい権限"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"現在の権限"</string>
-    <string name="message_staging" msgid="6151794817691100003">"アプリを準備しています…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"不明"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"セキュリティ上の理由から、お使いのタブレットではこの提供元からの不明なアプリをインストールすることはできません。"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"セキュリティ上の理由から、お使いのテレビではこの提供元からの不明なアプリをインストールすることはできません。"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"セキュリティ上の理由から、お使いのスマートフォンではこの提供元からの不明なアプリをインストールすることはできません。"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"不明なアプリをインストールするとスマートフォンや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるスマートフォンへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"不明なアプリをインストールするとタブレットや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるタブレットへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"不明なアプリをインストールすると TV や個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性がある TV への損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"続行"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"設定"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear アプリのインストールとアンインストール"</string>
+    <string name="app_name" msgid="7488448184431507488">"パッケージ インストーラ"</string>
+    <string name="install" msgid="711829760615509273">"インストール"</string>
+    <string name="done" msgid="6632441120016885253">"完了"</string>
+    <string name="cancel" msgid="1018267193425558088">"キャンセル"</string>
+    <string name="installing" msgid="4921993079741206516">"インストールしています…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をインストールしています…"</string>
+    <string name="install_done" msgid="5987363587661783896">"アプリをインストールしました。"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"このアプリをインストールしますか?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"この既存のアプリへのアップデートをインストールしてもよろしいですか?既存のデータは失われません。"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"この内蔵アプリへのアップデートをインストールしてもよろしいですか?既存のデータは失われません。"</string>
+    <string name="install_failed" msgid="5777824004474125469">"アプリはインストールされていません。"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"パッケージのインストールはブロックされています。"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"パッケージが既存のパッケージと競合するため、アプリをインストールできませんでした。"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"お使いのタブレットに対応していないため、アプリをインストールできませんでした。"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"このアプリはお使いのテレビに対応していません。"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"お使いのスマートフォンに対応していないため、アプリをインストールできませんでした。"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"パッケージが無効の可能性があるため、アプリをインストールできませんでした。"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> をタブレットにインストールできませんでした。"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"このユーザーは不明なアプリをインストールできません"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"このユーザーはアプリをインストールできません"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"アプリの管理"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"容量不足"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> をインストールできませんでした。空き容量を増やしてもう一度お試しください。"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"アプリが見つかりません"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"インストール済みアプリのリストに、このアプリはありません。"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"許可しない"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"このアンインストール操作は現在のユーザーには許可されていません。"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"エラー"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"アプリをアンインストールできませんでした。"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"アプリをアンインストール"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"アップデートのアンインストール"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> は次のアプリの一部です。"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"このアプリをアンインストールしますか?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"このアプリを"<b>"すべての"</b>"ユーザーからアンインストールしますか?このアプリとそのデータは端末の"<b>"すべての"</b>"ユーザーから削除されます。"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> さんのアプリをアンインストールしますか?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"このアプリを出荷時の状態に戻しますか?データがすべて削除されます。"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"このアプリを出荷時の状態に戻しますか?データがすべて削除されます。これは、仕事用プロファイルを設定しているユーザーも含めて、この端末を使用するすべてのユーザーが対象となります。"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"アンインストールを実行しています"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"エラーになったアンインストール"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"アンインストールしています…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしています…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"アンインストールが完了しました。"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear ではインストールやアンインストールはできません。"</string>
+    <string name="message_staging" msgid="8032722385658438567">"アプリを準備しています…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"不明"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"セキュリティ上の理由から、お使いのタブレットではこの提供元からの不明なアプリをインストールすることはできません。"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"セキュリティ上の理由から、お使いのテレビではこの提供元からの不明なアプリをインストールすることはできません。"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"セキュリティ上の理由から、お使いのスマートフォンではこの提供元からの不明なアプリをインストールすることはできません。"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"不明なアプリをインストールするとスマートフォンや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるスマートフォンへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"不明なアプリをインストールするとタブレットや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるタブレットへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"不明なアプリをインストールするとテレビや個人データが攻撃を受ける可能性が高くなります。このアプリをインストールすることにより、アプリの使用により生じる可能性があるテレビへの損害やデータの損失について、ユーザーご自身が単独で責任を負うことに同意するものとします。"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"次へ"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"設定"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wearアプリ インストール/アンインストール"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ka/strings.xml b/packages/PackageInstaller/res/values-ka/strings.xml
index 997f95c..4b2ae75 100644
--- a/packages/PackageInstaller/res/values-ka/strings.xml
+++ b/packages/PackageInstaller/res/values-ka/strings.xml
@@ -16,142 +16,76 @@
 
 <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="2738748390251381682">"პაკეტის ინსტალერი"</string>
-    <string name="next" msgid="3057143178373252333">"შემდეგი"</string>
-    <string name="install" msgid="5896438203900042068">"დაყენება"</string>
-    <string name="done" msgid="3889387558374211719">"დასრულდა"</string>
-    <string name="cancel" msgid="8360346460165114585">"გაუქმება"</string>
-    <string name="installing" msgid="8613631001631998372">"მიმდინარეობს ინსტალაცია…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის ინსტალაცია…"</string>
-    <string name="install_done" msgid="3682715442154357097">"აპი დაყენებულია."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"გსურთ, ამ აპლიკაციის დაყენება? მას ექნება წვდომა:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"გსურთ ამ აპლიკაციის დაყენება? ის არ მოითხოვს რაიმე განსაკუთრებულ ნებართვას."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"გსურთ განახლების დაყენება ამ არსებული აპლიკაციისთვის? არსებული მონაცემები არ დაიკარგება. განახლებულ აპლიკაციას წვდომა ექნება:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"გსურთ განახლების დაყენება ამ ჩაშენებული აპლიკაციისთვის? არსებული მონაცემები არ დაიკარგება. განახლენულ აპლიკაციას წვდომა ექნება:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"გსურთ განახლების დაყენება ამ არსებული აპლიკაციისთვის? არსებული მონაცემები არ დაიკარგება. ის არ საჭიროებს რაიმე განსაკუთრებულ წვდომას:"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"გსურთ განახლების დაყენება ამ ჩაშენებული აპლიკაციისთვის? არსებული მონაცემები არ დაიკარგება. ის არ საჭიროებს რაიმე განსაკუთრებულ წვდომას:"</string>
-    <string name="install_failed" msgid="6579998651498970899">"აპი არ არის დაყენებული."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ამ პაკეტის ინსტალაცია დაბლოკილია."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"აპი ვერ დაინსტალირდა, რადგან პაკეტი კონფლიქტშია არსებულ პაკეტთან."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"აპი ვერ დაინსტალირდა, რადგან ის არ არის თავსებადი თქვენს ტაბლეტთან."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ეს აპი არ არის თავსებადი თქვენს ტელევიზორთან."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"აპი ვერ დაინსტალირდა, რადგან ის არ არის თავსებადი თქვენს ტელეფონთან."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"აპი ვერ დაინსტალირდა, რადგან პაკეტი, სავარაუდოდ, არასწორია."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის დაყენება თქვენს ტაბლეტზე ვერ მოხერხდა."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ვერ დაინსტალირდება თქვენს ტელევიზორში."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის დაყენება თქვენს ტელეფონზე ვერ მოხერხდა."</string>
-    <string name="launch" msgid="4826921505917605463">"გახსნა"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"უცნობი წყაროებიდან ჩამოტვირთული აპების ინსტალაცია თქვენი ადმინისტრატორის მიერ ნებადართული არ არის"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ამ მომხმარებელს უცნობი აპების ინსტალაცია არ შეუძლია"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ამ მომხმარებელს აპების დაინსტალირების უფლება არ აქვს"</string>
-    <string name="ok" msgid="3468756155452870475">"კარგი"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"აპების მართვა"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"სივრცე შეივსო"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ის დაყენება შეუძლებელია. გაათავისუფლეთ მეხსიერება და სცადეთ ხელახლა."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"აპი ვერ მოიძებნა."</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"დაყენებული აპების სიაში ეს აპი ვერ მოიძებნა."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"დაუშვებელია"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"მიმდინარე მომხმარებელს არ აქვს დეინსტალაციის განხორციელების უფლება."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"შეცდომა"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"აპის დეინსტალაცია ვერ მოხერხდა."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"აპის დეინსტალაცია"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"განახლების დეინსტალაცია"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> არის შემდეგი აპის ნაწილი:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"გსურთ, ამ აპის დეინსტალაცია?"</string>
-    <!-- syntax error in translation for uninstall_application_text_all_users (5574704453233525222) org.xmlpull.v1.XmlPullParserException: expected: /string read: b (position:END_TAG </b>@1:122 in     <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"გსურთ ამ აპის დეინსტალაცია ყველა"</b>" მომხმარებილის "<b>"-თვის? აპლიკაცია და მისი მონაცემენბი წაიშლება ყველა"</b>" მომხმარებლის "<b>"-თვის მოწყობილობაზე."</string>
-)  -->
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"გსურთ <xliff:g id="USERNAME">%1$s</xliff:g> მომხმარებლისათვის ამ აპის დეინსტალაცია?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"გსურთ ამ აპის ქარხნული ვერსიით ჩანაცვლება? მონაცემები მთლიანად ამოიშლება."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"გსურთ ამ აპის ქარხნული ვერსიით ჩანაცვლება? მონაცემები მთლიანად ამოიშლება. ეს მოქმედება გავლენას იქონიებს ამ მოწყობილობის ყველა მომხმარებელზე, მათ შორის, სამსახურის პროფილებით მოსარგებლეებზეც."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"გაშვებული დეინსტალაციები"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"შეუსრულებელი დეინსტალაციები"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"დეინსტალაცია…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"დეინსტალაცია დასრულდა."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> დეინსტალირებულია"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"დეინსტალაცია წარუმატებელია."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია ვერ მოხერხდა."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"მოწყობილობის ადმინისტრატორის აქტიური აპის დეინსტალაცია ვერ მოხერხდება"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>-სთვის მოწყობილობის ადმინისტრატორის აქტიური აპის დეინსტალაცია ვერ მოხერხდება"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ამ აპს მომხმარებლების/პროფილების ნაწილი იყენებს. სხვებისთვის ის დეინსტალირებულია."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ეს აპი საჭიროა თქვენი პროფილისთვის. მისი დეინსტალაცია ვერ მოხერხდება."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ეს აპი საჭიროა თქვენი მოწყ. ადმინისტრატორისათვის და დეინსტალაცია ვერ გამოვა."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"მოწყობილობის ადმინისტრატორების აპების მართვა"</string>
-    <string name="manage_users" msgid="3125018886835668847">"მომხმარებლების მართვა"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> -ის დეინსტალაცია ვერ მოხერხდა."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"პაკეტის ანალიზისას წარმოიშვა პრობლემა."</string>
-    <string name="newPerms" msgid="6039428254474104210">"ახალი"</string>
-    <string name="allPerms" msgid="1024385515840703981">"ყველა"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"კონფიდენციალურობა"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"მოწყობილობის წვდომა"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ეს განახლება არ საჭიროებს ახალ ნებართვებს."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"უარყოფა"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"დამატებითი ინფორმაცია"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"მაინც უარყოფა"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>-დან"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"გსურთ, დაუშვათ, რომ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-მ შეასრულოს <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"გსურთ, ყოველთვის შესრულდეს <xliff:g id="ACTION">%2$s</xliff:g> &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>-ის&lt;/b&gt; მიერ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"მხოლოდ აპის გამოყენებისას"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ყოველთვის"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"უარყავი და აღარ მკითხო"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"გათიშულია <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"გათიშულია ყველა"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"არაფერია გათიშული"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"დაშვება"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"აპები"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"აპის უფლებები"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"აღარ მკითხოთ"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"ნებართვები არ არის"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"დამატებითი ნებართვები"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"აპის ინფორმაციის გახსნა"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> კიდევ</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> კიდევ</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ეს აპი Android-ის ძველი ვერსიისთვის შეიქმნა. ნებართვის უარყოფამ შესაძლოა მისი არასათანადო ფუნქციონირება გამოიწვიოს."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"უცნობი ქმედების შესრულება"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"დაშვებულია <xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> აპიდან"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"სისტემის ჩვენება"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"სისტემური პროცესების დამალვა"</string>
-    <string name="no_apps" msgid="1965493419005012569">"აპები არ არის"</string>
-    <string name="location_settings" msgid="1774875730854491297">"მდებარეობის პარამეტრები"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> არის მდებარეობის სერვისების მომწოდებელი ამ მოწყობილობისთვის. მდებარეობაზე წვდომის შეცვლა შესაძლებელია მდებარეობის პარამეტრებიდან."</string>
-    <string name="system_warning" msgid="7103819124542305179">"ამ ნებართვის უარყოფის შემთხვევაში, თქვენი მოწყობილობის ძირითადმა ფუნქციებმა შესაძლოა სათანადოდ აღარ იმუშაოს."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"შეესაბამება წესს"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ფონზე წვდომა დებულებით გათიშულია"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ფონზე წვდომა დებულებით დაშვებულია"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"წინა პლანზე წვდომა დებულებით დაშვებულია"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"იმართება ადმინისტრატორის მიერ"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ყოველთვის"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"მხოლოდ აპის გამოყენებისას"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"არასოდეს"</string>
-    <string name="loading" msgid="7811651799620593731">"იტვირთება..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"ყველა ნებართვა"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"აპის სხვა შესაძლებლობები"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"ნებართვის მოთხოვნა"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"ეკრანის გადაფარვა გამოვლინდა"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ამ ნებართვის პარამეტრის შესაცვლელად, ჯერ უნდა გამორთოთ ეკრანის გადაფარვა პარამეტრებიდან &gt; აპებიდან"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"პარამეტრების გახსნა"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ინსტალაციის/დეინსტალაციის მოქმედებები არ არის მხარდაჭერილი Wear-ზე."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"აირჩიეთ, რაზე ჰქონდეს წვდომა &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-ს"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; განახლდა. აირჩიეთ, რაზე ჰქონდეს წვდომა ამ აპს."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"გაუქმება"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"გაგრძელება"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"ახალი ნებართვები"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"ამჟამინდელი ნებართვები"</string>
-    <string name="message_staging" msgid="6151794817691100003">"მიმდინარეობს აპის შუალედური შენახვა…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"უცნობი"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"თქვენივე უსაფრთხოებისთვის, ტაბლეტს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება არ აქვს."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"თქვენივე უსაფრთხოებისთვის, ტელევიზორს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება არ აქვს."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"თქვენივე უსაფრთხოებისთვის, ტელეფონს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება არ აქვს."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"თქვენი ტელეფონი და პირადი მონაცემები უცნობი აპების შემოტევების წინაშე მეტად დაუცველია. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტელეფონისთვის მიყენებულ ზიანსა და მონაცემების დაკარგვაზე."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"თქვენი ტელეფონი და პირადი მონაცემები უცნობი აპების შემოტევების წინაშე მეტად დაუცველია. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტაბლეტისთვის მიყენებულ ზიანსა და მონაცემების დაკარგვაზე."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"თქვენი ტელევიზორი და პირადი მონაცემები უცნობი აპების შემოტევების წინაშე მეტად დაუცველია. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტელევიზორისთვის მიყენებულ ზიანსა და მონაცემების დაკარგვაზე."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"გაგრძელება"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"პარამეტრები"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear აპების ინსტალაცია/დეინსტალაცია"</string>
+    <string name="app_name" msgid="7488448184431507488">"პაკეტის ინსტალატორი"</string>
+    <string name="install" msgid="711829760615509273">"ინსტალაცია"</string>
+    <string name="done" msgid="6632441120016885253">"მზადაა"</string>
+    <string name="cancel" msgid="1018267193425558088">"გაუქმება"</string>
+    <string name="installing" msgid="4921993079741206516">"მიმდინარეობს ინსტალაცია…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის ინსტალაცია…"</string>
+    <string name="install_done" msgid="5987363587661783896">"აპი დაინსტალირებულია."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"გსურთ ამ აპლიკაციის ინსტალაცია?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"გსურთ ამ არსებული აპლიკაციის განახლების ინსტალაცია? არსებული მონაცემები არ დაიკარგება."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"გსურთ ამ ჩაშენებული აპლიკაციის განახლების ინსტალაცია? არსებული მონაცემები არ დაიკარგება."</string>
+    <string name="install_failed" msgid="5777824004474125469">"აპი დაუინსტალირებელია."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"ამ პაკეტის ინსტალაცია დაბლოკილია."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"აპი ვერ დაინსტალირდა, რადგან პაკეტი კონფლიქტშია არსებულ პაკეტთან."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"აპი ვერ დაინსტალირდა, რადგან ის არ არის თავსებადი თქვენს ტაბლეტთან."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"ეს აპი არ არის თავსებადი თქვენს ტელევიზორთან."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"აპი ვერ დაინსტალირდა, რადგან ის არ არის თავსებადი თქვენს ტელეფონთან."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"აპი ვერ დაინსტალირდა, რადგან პაკეტი, სავარაუდოდ, არასწორია."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> ვერ დაინსტალირდა თქვენს ტაბლეტზე."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"ამ მომხმარებელს არ შეუძლია უცნობი აპების ინსტალაცია"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ამ მომხმარებელს არ აქვს აპების ინსტალაციის უფლება"</string>
+    <string name="ok" msgid="7871959885003339302">"კარგი"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"აპების მართვა"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"მეხსიერება არასაკმარისია"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ვერ დაინსტალირდა. გაათავისუფლეთ მეხსიერება და ცადეთ ხელახლა."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"აპი ვერ მოიძებნა"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ეს აპი ვერ მოიძებნა დაინსტალირებული აპების სიაში."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"დაუშვებელია"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"ამჟამინდელ მომხმარებელს არ აქვს დეინსტალაციის უფლება."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"შეცდომა"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"აპის დეინსტალაცია ვერ მოხერხდა."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"აპის დეინსტალაცია"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"განახლების დეინსტალაცია"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> არის შემდეგი აპის ნაწილი:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"გსურთ ამ აპის დეინსტალაცია?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"გსურთ ამ აპის დეინსტალაცია "<b>"ყველა"</b>" მომხმარებლისთვის? აპლიკაცია და მისი მონაცემები ამოიშლება "<b>"ყველა"</b>" მომხმარებლის პროფილიდან მოწყობილობაზე."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"გსურთ ამ აპის დეინსტალაცია <xliff:g id="USERNAME">%1$s</xliff:g>-ისთვის?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"გსურთ ამ აპის ჩანაცვლება ქარხნული ვერსიით? მონაცემები მთლიანად ამოიშლება."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"გსურთ ამ აპის ჩანაცვლება ქარხნული ვერსიით? მონაცემები მთლიანად ამოიშლება. ეს ქმედება აისახება ამ მოწყობილობის ყველა მომხმარებელზე, მათ შორის, სამსახურის პროფილებით მოსარგებლეებზეც."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"გაშვებული დეინსტალაციები"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"შეუსრულებელი დეინსტალაციები"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"მიმდინარეობს დეინსტალაცია…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"მიმდინარეობს <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ის დეინსტალაცია…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"დეინსტალაცია დასრულდა."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"ინსტალაცია/დეინსტალაცია მხარდაუჭერელია Wear-ზე."</string>
+    <string name="message_staging" msgid="8032722385658438567">"მიმდინარეობს აპის შუალედური შენახვა…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"უცნობი"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"თქვენივე უსაფრთხოებისთვის, ტაბლეტს არ აქვს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"თქვენივე უსაფრთხოებისთვის, ტელევიზორს არ აქვს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"თქვენივე უსაფრთხოებისთვის, ტელეფონს არ აქვს ამ წყაროდან უცნობი აპების ინსტალაციის უფლება."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"თქვენი ტელეფონი და პერსონალური მონაცემები მეტად დაუცველია უცნობი აპების მხრიდან შეტევების წინაშე. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტელეფონისთვის მიყენებულ ზიანსა თუ მონაცემების დაკარგვაზე."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"თქვენი ტაბლეტი და პერსონალური მონაცემები მეტად დაუცველია უცნობი აპების მხრიდან შეტევების წინაშე. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტაბლეტისთვის მიყენებულ ზიანსა თუ მონაცემების დაკარგვაზე."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"თქვენი ტელევიზორი და პერსონალური მონაცემები მეტად დაუცველია უცნობი აპების მხრიდან შეტევების წინაშე. ამ აპის ინსტალაციის შემთხვევაში, თქვენ თანახმა ხართ, პასუხისმგებელი იყოთ მისი გამოყენების შედეგად ტელევიზორისთვის მიყენებულ ზიანსა თუ მონაცემების დაკარგვაზე."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"გაგრძელება"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"პარამეტრები"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear აპების ინსტალაცია/დეინსტალაცია"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-kk/strings.xml b/packages/PackageInstaller/res/values-kk/strings.xml
index 26892e1..708411c 100644
--- a/packages/PackageInstaller/res/values-kk/strings.xml
+++ b/packages/PackageInstaller/res/values-kk/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Бума орнатқыш"</string>
-    <string name="next" msgid="3057143178373252333">"Келесі"</string>
-    <string name="install" msgid="5896438203900042068">"Орнату"</string>
-    <string name="done" msgid="3889387558374211719">"Дайын"</string>
-    <string name="cancel" msgid="8360346460165114585">"Бас тарту"</string>
-    <string name="installing" msgid="8613631001631998372">"Орнатуда…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> орнатылуда…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Қолданба орнатылды."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Бұл қолданбаны орнатуды қалайсыз ба? Оның келесі нәрселерге қол жетімділігі болады:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Бұл қолданбаны орнатуды қалайсыз ба? Ол ерекше қол жетімділікті қажет етпейді."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Бұл қолданбаның жаңартылған нұсқасын орнатуды қалайсыз ба? Деректеріңіз жоғалмайды. Жаңартылған қолданбаның келесі нәрселерге қол жетімділігі болады:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Бұл орнатылған қолданбаның жаңартылған нұсқасын орнатуды қалайсыз ба? Деректеріңіз жоғалмайды. Жаңартылған қолданбаның келесі нәрселерге қол жетімділігі болады:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Бұл қолданбаның жаңартылған нұсқасын орнатуды қалайсыз ба? Деректеріңіз жоғалмайды. Ол ерекше қол жетімділікті қажет етпейді."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Бұл орнатылған қолданбаның жаңартылған нұсқасын орнатуды қалайсыз ба? Деректеріңіз жоғалмайды. Ол ерекше қол жетімділікті қажет етпейді."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Қолданба орнатылмады."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Буманы орнатуға тыйым салынды."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Пакет түрінде орнатылмаған қолданба мен бұрыннан бар пакеттің арасында қайшылық туындайды."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Қолданба түрінде орнатылмаған қолданба, планшетіңізбен үйлесімді емес."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Бұл қолданба теледидарыңызбен үйлесімді емес."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Қолданба түрінде орнатылмаған қолданба, телефоныңызбен үйлесімді емес."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Пакет түрінде орнатылмаған қолданба жарамсыз болып табылады."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын планшетіңізге орнату мүмкін емес"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> теледидарыңызда орнату мүмкін емес."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын телефоныңызға орнату мүмкін емес."</string>
-    <string name="launch" msgid="4826921505917605463">"Ашу"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Әкімші белгісіз көздерден алынған қолданбаларды орнатуға рұқсат етпейді"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Бұл пайдаланушы белгісіз қолданбаларды орната алмайды"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Бұл пайдаланушының қолданбаларды орнату рұқсаты жоқ"</string>
-    <string name="ok" msgid="3468756155452870475">"Жарайды"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Қолданбаларды басқару"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Орнында емес"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын орнату мүмкін болмады. Орын босатып, қайта әрекеттеніп көріңіз."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Қолданба табылмады"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Қолданба орнатылған қолданбалар тізімінен табылмады."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Рұқсат етілмеген"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Ағымдағы пайдаланушыға бұл жою әрекетіне рұқсат берілмеген."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Қате"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Қолданба жойылмады."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Қолданбаны алып тастау"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Жаңартуды алып тастау"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> келесі қолданбаның бөлігі:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Бұл қолданбаны алып тастауды қалайсыз ба?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Бұл қолданбаны "<b>"барлық"</b>" пайдаланушылар үшін алып тастауды қалайсыз ба? Қолданба және оның деректері құрылғыдағы "<b>"барлық"</b>" пайдаланушылардан алынады."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Пайдаланушы <xliff:g id="USERNAME">%1$s</xliff:g> үшін осы қолданбаны жою керек пе?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Осы қолданбаны зауыттық нұсқамен ауыстыру керек пе? Бүкіл деректер жойылады."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Осы қолданбаны зауыттық нұсқамен ауыстыру керек пе? Бүкіл деректер жойылады. Бұл осы құрылғының барлық пайдаланушыларына, соның ішінде жұмыс профильдері бар пайдаланушыларға әсер етеді."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Жұмыс істеп тұрған жою әрекеттері"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Сәтсіз жою әрекеттері"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Алып тастау орындалуда..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылуда…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Алып тастау аяқталды."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылды"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Алып тастау сәтсіздікке ұшырады."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жою сәтсіз аяқталды."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Белсенді құрылғының әкімші қолданбасын жою мүмкін емес"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> үшін белсенді құрылғының әкімші қолданбасын жою мүмкін емес"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Бұл қолданба кейбір пайдаланушылар немесе профильдер үшін қажет және басқалар үшін жойылды"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Бұл қолданба профиліңіз үшін қажет және оны жою мүмкін емес."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Әкімші осы қолданбаны талап етеді және оны жою мүмкін емес."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Құрылғы әкімшісі қолданбаларын басқару"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Пайдаланушыларды басқару"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын алып тастау мүмкін емес."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Жинақты сараптау кезінде мәселе орын алды."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Жаңа"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Барлық"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Құпиялылық"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Құралға кіру"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Бұл қолданба жаңа рұқсаттарды қажет етпейді."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Тыйым салу"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Қосымша ақпарат"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Бәрібір рұқсат бермеу"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>/<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасына <xliff:g id="ACTION">%2$s</xliff:g> рұқсатын беру керек пе?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; қолданбасы үшін <xliff:g id="ACTION">%2$s</xliff:g> әрекетіне әрқашан рұқсат етілсін бе?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Қолданба пайдаланылғанда ғана"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Әрқашан"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Тыйым салынсын және қайта сұралмасын"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> рұқсат өшірілді"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"барлық рұқсаттар өшірілді"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"рұқсаттардың ешқайсысы өшірілмеді"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Рұқсат беру"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Қолданбалар"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Қолданба рұқсаттары"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Қайта сұралмасын"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Рұқсат жоқ"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Қосымша рұқсаттар"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Қолданба ақпаратын ашу"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Тағы <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Тағы <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Бұл қолданба Android жүйесінің ескі нұсқасына арналған. Рұқсаттан бас тартсаңыз, бұдан былай тиісінше жұмыс істемеуі мүмкін."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"белгісіз әрекетті орындау"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g> қолданбаға рұқсат етілген"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Жүйені көрсету"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Жүйені жасыру"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Қолданбалар жоқ"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Орынды анықтау параметрлері"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> — осы құрылғыға орынды анықтау қызметтерін көрсететін қолданба. Орынды пайдалану мүмкіндігін орынды анықтау параметрлерінде өзгертуге болады."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Бұл рұқсатты бермесеңіз, құрылғының негізгі функциялары енді көзделгендей жұмыс істемеуі мүмкін."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Саясат арқылы қолданылған"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Саясат бойынша фондық режимде кіруге рұқсат етілмеген"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Саясат бойынша фондық режимде кіруге рұқсат етілген"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Саясат бойынша экрандық режимде кіруге рұқсат етілген"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Әкімші басқарады"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Әрқашан"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Қолданба пайдаланылғанда ғана"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Ешқашан"</string>
-    <string name="loading" msgid="7811651799620593731">"Жүктелуде…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Барлық рұқсаттар"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Басқа қолданба мүмкіндіктері"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Рұқсат сұрау"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Экранды қабаттастыру анықталды"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Бұл рұқсат параметрін өзгерту үшін алдымен «Параметрлер» &gt; «Қолданбалар» тармағында экранды қабаттастыруды өшіру керек"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Параметрлерді ашу"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear құрылғысында \"Орнату\"/\"Жою\" әрекеттері қолданылмайды."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы қайда кіре алатынын таңдаңыз"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы жаңартылды. Бұл қолданбаның қайда кіре алатынын таңдаңыз."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Бас тарту"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Жалғастыру"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Жаңа рұқсаттар"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Ағымдағы рұқсаттар"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Қолданба реттелуде…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Белгісіз"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Қауіпсіздікті сақтау үшін планшетке бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Қауіпсіздікті сақтау үшін теледидарға бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Қауіпсіздікті сақтау үшін телефонға бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефон және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі телефонға келетін залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Планшет және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі планшетке келетін залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Теледидар және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі теледидарға келетін қандай да бір залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Жалғастыру"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Параметрлер"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear қолданбасын орнату/жою"</string>
+    <string name="app_name" msgid="7488448184431507488">"Пакет орнатқыш"</string>
+    <string name="install" msgid="711829760615509273">"Орнату"</string>
+    <string name="done" msgid="6632441120016885253">"Дайын"</string>
+    <string name="cancel" msgid="1018267193425558088">"Бас тарту"</string>
+    <string name="installing" msgid="4921993079741206516">"Орнатылуда…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> орнатылуда…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Қолданба орнатылды."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Осы қолданба орнатылсын ба?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Қолданбаның жаңартылған нұсқасы орнатылсын ба? Бұрыннан бар деректер сақталады."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Орнатылған қолданбаның жаңартылған нұсқасы орнатылсын ба? Бұрыннан бар деректер сақталады."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Қолданба орнатылмады."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Пакетті орнатуға тыйым салынды."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Жаңа пакет пен бұрыннан бар пакеттің арасында қайшылық туындағандықтан, қолданба орнатылмады."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Планшетпен үйлесімді болмағандықтан, қолданба орнатылмады."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Бұл қолданба теледидарыңызбен үйлесімді емес."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Телефонмен үйлесімді болмағандықтан, қолданба орнатылмады."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Пакет жарамсыз болғандықтан, қолданба орнатылмады."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасын планшетке орнату мүмкін емес."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Бұл пайдаланушы белгісіз қолданбаларды орната алмайды"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Бұл пайдаланушының қолданбаларды орнату рұқсаты жоқ"</string>
+    <string name="ok" msgid="7871959885003339302">"Жарайды"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Қолданбаларды басқару"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Орын жоқ"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы орнатылмады. Орын босатып, қайталап көріңіз."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Қолданба табылмады"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Қолданба орнатылған қолданбалар тізімінен табылмады."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Рұқсат етілмеген"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Ағымдағы пайдаланушыға бұл жою әрекетіне рұқсат берілмеген."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Қате"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Қолданба жойылмады."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Қолданбаны жою"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Жаңа нұсқаны жою"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> келесі қолданбаның бөлігі:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Осы қолданба жойылсын ба?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Бұл қолданба "<b>"барлық"</b>" пайдаланушылар үшін жойылсын ба? Қолданба және оның деректері құрылғыдағы "<b>"барлық"</b>" пайдаланушылардан өшіріледі."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> үшін осы қолданба жойылсын ба?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Осы қолданбаны зауыттық нұсқамен ауыстыру керек пе? Барлық деректер жойылады."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Осы қолданбаны зауыттық нұсқамен ауыстыру керек пе? Барлық деректер жойылады. Бұл осы құрылғының барлық пайдаланушыларына, соның ішінде жұмыс профильдері бар пайдаланушыларға әсер етеді."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Орындалып жатқан жою процестері"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Сәтсіз жою әрекеттері"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Жойылуда…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> жойылуда…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Жою аяқталды."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear жүйесінде \"Орнату/Жою\" әрекеттері қолданылмайды."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Қолданба дайындалуда…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Белгісіз"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Қауіпсіздік үшін планшетке бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Қауіпсіздік үшін теледидарға бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Қауіпсіздік үшін телефонға бұл дереккөзден белгісіз қолданбаларды орнатуға рұқсат берілмейді."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефон және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі телефонға келетін залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Планшет және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі планшетке келетін залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Теледидар және жеке деректер белгісіз қолданбалардың шабуылына ұшырауы мүмкін. Бұл қолданбаны орнату арқылы оны пайдалану нәтижесіндегі теледидарға келетін қандай да бір залалға немесе деректердің жоғалуына өзіңіз ғана жауапты болатыныңызға келісесіз."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Жалғастыру"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Параметрлер"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear қолданбасын орнату/жою"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml
index 693ea32..78b04a0 100644
--- a/packages/PackageInstaller/res/values-km/strings.xml
+++ b/packages/PackageInstaller/res/values-km/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"កម្មវិធី​ដំឡើង​កញ្ចប់"</string>
-    <string name="next" msgid="3057143178373252333">"បន្ទាប់​"</string>
-    <string name="install" msgid="5896438203900042068">"ដំឡើង"</string>
-    <string name="done" msgid="3889387558374211719">"រួចរាល់"</string>
-    <string name="cancel" msgid="8360346460165114585">"បោះ​បង់​"</string>
-    <string name="installing" msgid="8613631001631998372">"កំពុង​ដំឡើង..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"កំពុង​ដំឡើង <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"បាន​ដំឡើង​កម្មវិធី។"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"តើ​អ្នក​ចង់​ដំឡើង​កម្មវិធី​នេះ? វា​នឹង​មាន​សិទ្ធិ​ចូល៖"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"តើ​អ្នក​ចង់​ដំឡើង​កម្មវិធី​នេះ? វា​មិន​ទាមទារ​សិទ្ធិ​ចូល​ពិសេស​ទេ។"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"តើ​អ្នក​ចង់​ដំឡើង​បច្ចុប្បន្នភាព​កម្មវិធី​ដែល​មាន​ស្រាប់​នេះ? ទិន្នន័យ​ដែល​មាន​ស្រាប់​របស់​អ្នក​នឹង​មិន​បាត់បង់​ទេ។ កម្មវិធី​បាន​ធ្វើ​បច្ចុប្បន្នភាព​នឹង​ចូល​ដំណើរការ​ទៅ៖"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"តើ​អ្នក​ចង់​ដំឡើង​បច្ចុប្បន្នភាព​កម្មវិធី​ដែល​ជាប់​ជា​មួយនេះ? ទិន្នន័យ​ដែល​មាន​ស្រាប់​របស់​អ្នក​នឹង​មិនបាត់បង់ទេ។ កម្មវិធី​បាន​ធ្វើ​បច្ចុប្បន្នភាពហើយ​នឹង​មានសិទ្ធិចូល​៖"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"តើ​អ្នក​ចង់​ដំឡើង​បច្ចុប្បន្នភាព​កម្មវិធី​ដែល​មាន​ស្រាប់​នេះ? ​ទិន្នន័យ​ដែល​មាន​ស្រាប់​របស់​អ្នក​នឹង​មិន​បាត់បង់​ទេ។ វា​មិន​ទាមទារ​ការ​ចូល​ដំណើរការ​ពិសេស​ណាមួយ​ទេ។"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"តើ​អ្នក​ចង់​ដំឡើង​បច្ចុប្បន្នភាព​កម្មវិធី​ដែល​ជាប់​ជា​មួយ? ​ទិន្នន័យ​ដែល​មាន​ស្រាប់​របស់​អ្នក​នឹង​មិន​បាត់បង់​ទេ។ វា​មិន​ទាមទារ​ការ​ចូល​ដំណើរការ​ពិសេស​ណាមួយ​ទេ។"</string>
-    <string name="install_failed" msgid="6579998651498970899">"មិន​បាន​ដំឡើង​កម្មវិធី។"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"កញ្ចប់នេះត្រូវបានរារាំងមិនឲ្យដំឡើង"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកញ្ចប់កម្មវិធីមិនត្រូវគ្នាជាមួយកញ្ចប់ដែលមានស្រាប់។"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកម្មវិធីមិនត្រូវគ្នាជាមួយថេប្លេតរបស់អ្នក។"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"កម្មវិធីនេះមិនត្រូវគ្នាជាមួយទូរទស្សន៍របស់អ្នកទេ"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកម្មវិធីមិនត្រូវគ្នាជាមួយទូរសព្ទរបស់អ្នក។"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកញ្ចប់គ្មានសុពលភាព។"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"មិន​អាច​ដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> ក្នុង​កុំព្យូទ័រ​បន្ទះ​របស់​អ្នក។"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនអាចដំឡើងនៅលើទូរទស្សន៍របស់អ្នកទេ។"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"មិន​អាច​ដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> ក្នុង​ទូរស័ព្ទ​របស់​អ្នក។"</string>
-    <string name="launch" msgid="4826921505917605463">"បើក"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"អ្នក​គ្រប់គ្រង​របស់​អ្នក​មិន​អនុញ្ញាត​ឲ្យ​ដំឡើង​កម្មវិធី​ដែល​បាន​មក​ពី​ប្រភព​ដែលមិន​ស្គាល់ទេ"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"កម្មវិធី​ដែល​មិនស្គាល់​មិនអាច​ដំឡើង​ដោយ​អ្នកប្រើប្រាស់​នេះ​បាន​ទេ"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"អ្នក​ប្រើ​ប្រាស់នេះ​មិនត្រូវបាន​អនុញ្ញាត​ឲ្យ​ដំឡើងកម្មវិធីទេ"</string>
-    <string name="ok" msgid="3468756155452870475">"យល់​ព្រម​"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"គ្រប់គ្រង​កម្មវិធី"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"អស់​ទំហំ"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"មិន​អាច​ដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> ។ លុប​ឯកសារ​ខ្លះ ហើយ​ព្យាយាម​ម្ដង​ទៀត។"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"រក​មិន​ឃើញ​កម្មវិធី"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"រក​មិន​ឃើញ​កម្មវិធី​ក្នុង​បញ្ជី​កម្មវិធី​បាន​ដំឡើង។"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"មិន​បាន​អនុញ្ញាត"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"អ្នកប្រើបច្ចុប្បន្នមិនមានការអនុញ្ញាតឱ្យ​ធ្វើការលុបនេះទេ។"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"បញ្ហា"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"មិនអាចលុបកម្មវិធីនេះបានទេ។"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"លុប​កម្មវិធី"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"លុប​បច្ចុប្បន្នភាព"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>​ ​ជា​ផ្នែក​មួយ​នៃ​កម្មវិធី​ដូច​ខាង​ក្រោម​នេះ​៖"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"តើ​អ្នក​ចង់​លុប​កម្មវិធី​នេះ​ឬ?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"តើ​អ្នក​ចង់​លុប​កម្មវិធី​នេះ​សម្រាប់​អ្នកប្រើ "<b>"ទាំងអស់"</b>"? កម្មវិធី និង​ទិន្នន័យ​របស់​វា​នឹង​ត្រូវ​បាន​លុប​ចេញ​ពី​អ្នកប្រើ "<b>"ទាំងអស់"</b>" ក្នុង​ឧបករណ៍​នេះ។"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"តើ​អ្នក​ចង់​លុប​កម្មវិធី​នេះ​សម្រាប់​អ្នកប្រើ <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ជំនួសកម្មវិធីនេះដោយកំណែរោងចក្រឬ? ទិន្នន័យទាំងអស់នឹងត្រូវបានលុបចេញ។"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ជំនួយកម្មវិធីនេះដោយកំណែរោងចក្រឬ? ទិន្នន័យទាំងអស់នឹងត្រូវបានលុបចេញ។ វាប៉ះពាល់ដល់អ្នកប្រើឧបករណ៍នេះទាំងអស់ ដោយរាប់បញ្ចូលទាំងអ្នកប្រើដែលមានប្រវត្តិរូបការងារផងដែរ។"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"កំពុង​ដំណើរការ​ការលុប"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"មិន​អាច​ធ្វើការលុប​បានទេ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"កំពុង​លុប..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"កំពុងលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"បាន​បញ្ចប់​ការ​លុប។"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"បានលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"ការ​លុប​បរាជ័យ។"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"មិនអាចលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> បាន។"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"មិនអាច​លុប​កម្មវិធី​អ្នកគ្រប់គ្រង​ឧបករណ៍​ដែល​បាន​ដំណើរការ​បានទេ"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"មិនអាច​លុប​កម្មវិធី​អ្នកគ្រប់គ្រង​ឧបករណ៍​សម្រាប់ <xliff:g id="USERNAME">%1$s</xliff:g> ដែល​បាន​ដំណើរការ​បាន​ទេ"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"កម្មវិធីនេះតម្រូវឲ្យមានសម្រាប់អ្នកប្រើ ឬប្រវត្តិរូបមួយចំនួន និងត្រូវបានលុបសម្រាប់អ្នកប្រើផ្សេងទៀត"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"កម្មវិធីនេះចាំបាច់សម្រាប់ប្រវតិ្តការងាររបស់អ្នក ហើយវាមិនអាចលុបបានទេ។"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"កម្មវិធីនេះត្រូវបានទាមទារដោយអ្នកគ្រប់គ្រងឧបករណ៍របស់អ្នក ហើយមិនអាចលុប​ចេញបាន​ទេ។"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"គ្រប់គ្រង​កម្មវិធី​អ្នកគ្រប់គ្រង​ឧបករណ៍"</string>
-    <string name="manage_users" msgid="3125018886835668847">"គ្រប់គ្រងអ្នកប្រើ"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"មិន​អាច​លុប <xliff:g id="APP_NAME">%1$s</xliff:g> ។"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"មាន​បញ្ហា​ក្នុង​ការ​ញែក​​កញ្ចប់។"</string>
-    <string name="newPerms" msgid="6039428254474104210">"ថ្មី"</string>
-    <string name="allPerms" msgid="1024385515840703981">"ទាំងអស់"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"ភាព​​ឯកជន"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ការ​ចូល​ដំណើរការ​ឧបករណ៍"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"បច្ចុប្បន្នភាព​នេះ​មិន​ទាមទារ​សិទ្ធិ​ថ្មី​ទេ។"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"បដិសេធ"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ព័ត៌មានបន្ថែម"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"បដិសេធទោះយ៉ាងណាក៏ដោយ"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> នៃ <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"អនុញ្ញាតឲ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"អនុញ្ញាតឱ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g> ជានិច្ចមែនទេ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ខណៈពេលប្រើ​កម្មវិធីតែប៉ុណ្ណោះ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ជានិច្ច"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"បដិសេធ ហើយកុំ​សួរម្តងទៀត"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"បានបិទ <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"បានបិទទាំងអស់"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"មិនបានបិទអ្វីទាំងអស់"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"អនុញ្ញាត"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"កម្មវិធី"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ការអនុញ្ញាតកម្មវិធី"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"កុំសួរទៀត"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"គ្មានសិទ្ធិអនុញ្ញាត"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"ការអនុញ្ញាតបន្ថែម"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"បើក​ព័ត៌មាន​កម្មវិធី"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ទៀត</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ទៀត</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"កម្មវិធីនេះត្រូវបានរចនាឡើងសម្រាប់កំណែចាស់របស់ Android។ ការបដិសេធសិទ្ធិអនុញ្ញាតអាចបណ្តាលឲ្យវាបំពេញមុខងារមិនដូចអ្វីដែលគេរំពឹងទុកតទៅទៀតទេ។"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ប្រតិបត្តិការសកម្មភាពមិនស្គាល់"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"បានអនុញ្ញាតកម្មវិធី <xliff:g id="COUNT_0">%1$d</xliff:g> នៃ <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"បង្ហាញប្រព័ន្ធ"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"លាក់ប្រព័ន្ធ"</string>
-    <string name="no_apps" msgid="1965493419005012569">"គ្មានកម្មវិធី"</string>
-    <string name="location_settings" msgid="1774875730854491297">"ការកំណត់ទីតាំង"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> គឺជាអ្នកផ្តល់សេវាកម្មទីតាំងសម្រាប់ឧបករណ៍នេះ។ ការចូលដំណើរការទីតាំងអាចកែសម្រួលបានចេញពីការកំណត់ទីតាំង។"</string>
-    <string name="system_warning" msgid="7103819124542305179">"ប្រសិនបើអ្នកបដិសេធសិទ្ធិអនុញ្ញាតនេះ លក្ខណៈពិសេសគោលនៃឧបករណ៍របស់អ្នកអាចមិនដំណើរការដូចដែលអ្នកចង់បានតទៅទៀតទេ។"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"អនុវត្តតាមគោលការណ៍"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ការចូលប្រើផ្ទៃខាងក្រោយ​ត្រូវបានបិទដោយគោលការណ៍"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ការចូលប្រើផ្ទៃខាងក្រោយ​ត្រូវបានបើកដោយគោលការណ៍"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ការចូលប្រើផ្ទៃខាងមុខ​ត្រូវបានបើកដោយគោលការណ៍"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"គ្រប់គ្រងដោយអ្នកគ្រប់គ្រង"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ជានិច្ច"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"ខណៈពេលប្រើ​កម្មវិធីតែប៉ុណ្ណោះ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"កុំឱ្យសោះ"</string>
-    <string name="loading" msgid="7811651799620593731">"កំពុងដំណើរការ..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"សិទ្ធិអនុញ្ញាតទាំងអស់"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"សមត្ថភាពកម្មវិធីផ្សេងទៀត"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"សំណើសុំសិទ្ធិអនុញ្ញាត"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"បានរកឃើញអេក្រង់ត្រួតគ្នា"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ដើម្បីប្តូរការកំណត់សិទ្ធិអនុញ្ញាតនេះ ជាដំបូងអ្នកត្រូវបិទអេក្រង់ត្រួតគ្នានៅក្នុង ការកំណត់ &gt; កម្មវិធី"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"បើកការកំណត់"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"សកម្មភាពដំឡើង/លុបការដំឡើងមិនគាំទ្រនៅលើ Wear ទេ"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"ជ្រើសរើសអ្វីដែលត្រូវអនុញ្ញាតឲ្យ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ចូលដំណើរការ"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ត្រូវបានអាប់ដេត។ ជ្រើសរើសអ្វីដែលត្រូវអនុញ្ញាតឲ្យកម្មវិធីនេះចូលដំណើរការ។"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"បោះបង់"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"បន្ត"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"សិទ្ធិអនុញ្ញាតថ្មី"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"សិទ្ធិអនុញ្ញាតបច្ចុប្បន្ន"</string>
-    <string name="message_staging" msgid="6151794817691100003">"កំពុងសាកល្បងកម្មវិធី…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"មិនស្គាល់"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ដើម្បីការពារសុវតិ្ថភាពរបស់អ្នក ថេប្លេតរបស់អ្នកមិនត្រូវបានអនុញ្ញាតឲ្យដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ដើម្បីការពារសុវតិ្ថភាពរបស់អ្នក ទូរទស្សន៍របស់អ្នកមិនត្រូវបានអនុញ្ញាតឲ្យដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ដើម្បីការពារសុវតិ្ថភាពរបស់អ្នក ទូរសព្ទរបស់អ្នកមិនត្រូវបានអនុញ្ញាតឲ្យដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ទូរសព្ទ និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតណាមួយចំពោះទូរសព្ទ ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្តាលមកពីការប្រើប្រាស់កម្មវិធីនោះ។"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ថេប្លេត និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតណាមួយចំពោះថេប្លេត ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្តាលមកពីការប្រើប្រាស់កម្មវិធីនោះ។"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ទូរទស្សន៍ និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតណាមួយចំពោះទូរទស្សន៍ ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្តាលមកពីការប្រើប្រាស់កម្មវិធីនោះ។"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"បន្ត"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ការ​កំណត់"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"ការដំឡើង/ការលុបកម្មវិធីឧបករណ៍​ពាក់​"</string>
+    <string name="app_name" msgid="7488448184431507488">"កម្មវិធី​ដំឡើង​កញ្ចប់"</string>
+    <string name="install" msgid="711829760615509273">"ដំឡើង"</string>
+    <string name="done" msgid="6632441120016885253">"រួចរាល់"</string>
+    <string name="cancel" msgid="1018267193425558088">"បោះបង់"</string>
+    <string name="installing" msgid="4921993079741206516">"កំពុងដំឡើង…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"កំពុង​ដំឡើង <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"បាន​ដំឡើង​កម្មវិធី។"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"តើ​អ្នក​ចង់​ដំឡើង​កម្មវិធី​នេះ​ដែរទេ?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"តើ​អ្នក​ចង់​ដំឡើងកំណែ​ថ្មី​សម្រាប់​កម្មវិធី​ដែលមាន​ស្រាប់​នេះ​ដែរទេ? ទិន្នន័យ​ដែល​មាន​ស្រាប់​របស់​អ្នក​នឹង​មិន​បាត់​បង់​ទេ។"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"តើ​អ្នក​ចង់​ដំឡើងកំណែ​ថ្មី​សម្រាប់​កម្មវិធី​ដែលភ្ជាប់​មក​ជាមួយនេះ​ដែរទេ? ទិន្នន័យ​ដែល​មាន​ស្រាប់​របស់​អ្នក​នឹង​មិន​បាត់​បង់​ទេ។"</string>
+    <string name="install_failed" msgid="5777824004474125469">"មិន​បាន​ដំឡើង​កម្មវិធីទេ។"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"កញ្ចប់ត្រូវបានទប់ស្កាត់​មិន​ឱ្យ​ដំឡើង។"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកញ្ចប់កម្មវិធីមិនត្រូវគ្នាជាមួយកញ្ចប់ដែលមានស្រាប់។"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកម្មវិធីមិនត្រូវគ្នាជាមួយថេប្លេតរបស់អ្នក។"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"កម្មវិធីនេះមិនត្រូវគ្នាជាមួយទូរទស្សន៍របស់អ្នកទេ។"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកម្មវិធីមិនត្រូវគ្នាជាមួយទូរសព្ទរបស់អ្នក។"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"កម្មវិធីមិនបានដំឡើងទេ ដោយសារកញ្ចប់គ្មានសុពលភាព។"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"មិន​អាច​ដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> នៅលើថេប្លេត​​របស់​អ្នកបានទេ។"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"អ្នកប្រើប្រាស់​នេះ​មិនអាច​ដំឡើងកម្មវិធីមិនស្គាល់​​បាន​ទេ"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"មិន​អនុញ្ញាត​ឱ្យអ្នក​ប្រើ​ប្រាស់នេះ​ដំឡើងកម្មវិធីទេ"</string>
+    <string name="ok" msgid="7871959885003339302">"យល់ព្រម"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"គ្រប់គ្រង​កម្មវិធី"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"អស់​ទំហំផ្ទុក"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"មិន​អាច​ដំឡើង <xliff:g id="APP_NAME">%1$s</xliff:g> បានទេ។ សូម​បង្កើន​ទំហំ​ផ្ទុក​ទំនេរ​មួយចំនួន​ រួច​ព្យាយាម​ម្ដង​ទៀត។"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"រក​មិន​ឃើញ​កម្មវិធីទេ"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"រក​មិន​ឃើញ​កម្មវិធី​នេះ​នៅ​ក្នុង​បញ្ជី​កម្មវិធី​ដែល​បាន​ដំឡើងទេ។"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"មិន​អនុញ្ញាត​ទេ"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"មិនអនុញ្ញាតឱ្យអ្នកប្រើប្រាស់បច្ចុប្បន្ន​ធ្វើការលុបនេះទេ។"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"បញ្ហា"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"មិនអាចលុបកម្មវិធីបានទេ។"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"លុប​កម្មវិធី"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"លុប​កំណែ​ថ្មី"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>​ ​ជា​ផ្នែក​មួយ​នៃ​កម្មវិធី​ដូច​ខាង​ក្រោម​នេះ​៖"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"តើ​អ្នក​ចង់​លុប​កម្មវិធី​នេះ​ដែរទេ?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"តើ​អ្នក​ចង់​លុប​កម្មវិធី​នេះ​សម្រាប់​អ្នកប្រើប្រាស់"<b>"ទាំងអស់"</b>"ដែរទេ? កម្មវិធីនេះ និង​ទិន្នន័យ​របស់​វា​នឹង​ត្រូវ​បាន​លុប​ចេញ​ពី​អ្នកប្រើប្រាស់"<b>"ទាំងអស់"</b>"នៅលើ​ឧបករណ៍​នេះ។"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"តើ​អ្នក​ចង់​លុប​កម្មវិធី​នេះ​សម្រាប់​អ្នកប្រើប្រាស់ <xliff:g id="USERNAME">%1$s</xliff:g> ដែរទេ?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ជំនួសកម្មវិធីនេះដោយប្រើកំណែរោងចក្រ? ទិន្នន័យទាំងអស់នឹងត្រូវបានលុប។"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ជំនួសកម្មវិធីនេះដោយប្រើកំណែរោងចក្រ? ទិន្នន័យទាំងអស់នឹងត្រូវបានលុប។ សកម្មភាព​នេះប៉ះពាល់ដល់អ្នកប្រើប្រាស់ទាំងអស់​របស់ឧបករណ៍នេះ រួម​ទាំងអ្នកប្រើប្រាស់ដែលមានកម្រង​ព័ត៌មាន​ការងារ​ផងដែរ។"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"កំពុង​ដំណើរការ​ការលុប"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"ការលុប​ដែល​បរាជ័យ"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"កំពុង​លុប…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"កំពុងលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"បាន​បញ្ចប់​ការ​លុប។"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"សកម្មភាព​ដំឡើង/លុបចេញមិនអាចប្រើ​នៅលើ Wear បានទេ។"</string>
+    <string name="message_staging" msgid="8032722385658438567">"កំពុងសាកល្បងកម្មវិធី…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"មិនស្គាល់"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"ដើម្បីសុវតិ្ថភាពរបស់អ្នក ថេប្លេតរបស់អ្នកមិនត្រូវបានអនុញ្ញាតឱ្យដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"ដើម្បីសុវតិ្ថភាពរបស់អ្នក ទូរទស្សន៍របស់អ្នកមិនត្រូវបានអនុញ្ញាតឱ្យ​ដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"ដើម្បីសុវតិ្ថភាពរបស់អ្នក ទូរសព្ទរបស់អ្នកមិនត្រូវបានអនុញ្ញាតឱ្យដំឡើងកម្មវិធីដែលមិនស្គាល់ពីប្រភពនេះទេ។"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"ទូរសព្ទ និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតទាំងឡាយចំពោះទូរសព្ទ ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្ដាលមកពីការប្រើប្រាស់កម្មវិធីនេះ។"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"ថេប្លេត និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតទាំងឡាយចំពោះថេប្លេត ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្ដាលមកពីការប្រើប្រាស់កម្មវិធីនេះ។"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ទូរទស្សន៍ និងទិន្នន័យផ្ទាល់ខ្លួនរបស់អ្នកងាយនឹងរងគ្រោះពីការវាយប្រហារពីកម្មវិធីដែលមិនស្គាល់។ ប្រសិនបើដំឡើងកម្មវិធីនេះ មានន័យថាអ្នកទទួលខុសត្រូវលើការខូចខាតទាំងឡាយចំពោះទូរទស្សន៍ ឬការបាត់បង់ទិន្នន័យរបស់អ្នក ដែលអាចបណ្ដាលមកពីការប្រើប្រាស់កម្មវិធីនេះ។"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"បន្ត"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"ការកំណត់"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"ការដំឡើង/ការលុបកម្មវិធីឧបករណ៍​ពាក់​"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-kn/strings.xml b/packages/PackageInstaller/res/values-kn/strings.xml
index f42035c..5b9698a 100644
--- a/packages/PackageInstaller/res/values-kn/strings.xml
+++ b/packages/PackageInstaller/res/values-kn/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"ಪ್ಯಾಕೇಜ್ ಸ್ಥಾಪಕ"</string>
-    <string name="next" msgid="3057143178373252333">"ಮುಂದೆ"</string>
-    <string name="install" msgid="5896438203900042068">"ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
-    <string name="done" msgid="3889387558374211719">"ಮುಗಿದಿದೆ"</string>
-    <string name="cancel" msgid="8360346460165114585">"ರದ್ದುಮಾಡಿ"</string>
-    <string name="installing" msgid="8613631001631998372">"ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="install_done" msgid="3682715442154357097">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲಾಗಿದೆ."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಇದು ಇಲ್ಲಿಗೆ ಪ್ರವೇಶ ಪಡೆದುಕೊಳ್ಳುತ್ತದೆ:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಇದಕ್ಕೆ ಯಾವುದೇ ವಿಶೇಷ ಪ್ರವೇಶದ ಅಗತ್ಯವಿಲ್ಲ."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"ನೀವು ಈ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅಪ್ಲಿಕೇಶನ್‍ನ ಅಪ್‌ಡೇಟ್‌‌ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಅಪ್‌ಡೇಟ್‌‌ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಇಲ್ಲಿಗೆ ಪ್ರವೇಶ ಪಡೆದುಕೊಳ್ಳುತ್ತದೆ:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ನೀವು ಈ ಬಿಲ್ಟ್-ಇನ್-ಅಪ್ಲಿಕೇಶನ್‌ನ ಅಪ್‌ಡೇಟ್‌‌ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಿಕೊಳ್ಳಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಅಪ್‌ಡೇಟ್‌‌ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಇಲ್ಲಿಗೆ ಪ್ರವೇಶ ಪಡೆದುಕೊಳ್ಳುತ್ತದೆ:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ನೀವು ಈ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಅಪ್ಲಿಕೇಶನ್‍ನ ಅಪ್‌ಡೇಟ್‌‌ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಇದಕ್ಕೆ ಯಾವುದೇ ವಿಶೇಷ ಪ್ರವೇಶದ ಅಗತ್ಯವಿಲ್ಲ."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ನೀವು ಈ ಬಿಲ್ಟ್-ಇನ್-ಅಪ್ಲಿಕೇಶನ್‌ನ ಅಪ್‌ಡೇಟ್‌‌ ಆದ ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಿಕೊಳ್ಳಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಇದಕ್ಕೆ ಯಾವುದೇ ವಿಶೇಷ ಪ್ರವೇಶದ ಅಗತ್ಯವಿಲ್ಲ."</string>
-    <string name="install_failed" msgid="6579998651498970899">"ಅಪ್ಲಿಕೇಶನ್ ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ಸ್ಥಾಪಿಸುವಿಕೆಯಿಂದ ಪ್ಯಾಕೇಜ್‌ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"ಪ್ಯಾಕೇಜ್‌ನಂತೆ ಸ್ಥಾಪಿತವಾಗದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಪ್ಯಾಕೇಜ್ ಜೊತೆಗೆ ಸಂಘರ್ಷವಾಗುತ್ತದೆ."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ಅಪ್ಲಿಕೇಶನ್‌ನಂತೆ ಸ್ಥಾಪಿತವಾಗದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಟಿವಿ ಜೊತೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ಅಪ್ಲಿಕೇಶನ್‌ನಂತೆ ಸ್ಥಾಪಿತವಾಗದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಫೋನ್ ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"ಪ್ಯಾಕೇಜ್‌ನಂತೆ ಸ್ಥಾಪಿತವಾಗದಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಅಮಾನ್ಯವಾಗಿರುವಂತೆ ತೋರುತ್ತದೆ."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ನಿಮ್ಮ ಟಿವಿಗೆ ಸ್ಥಾಪಿಸಲಾಗುವುದಿಲ್ಲ."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"ನಿಮ್ಮ ಫೋನ್‌ನಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಾಗುವುದಿಲ್ಲ."</string>
-    <string name="launch" msgid="4826921505917605463">"ತೆರೆ"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ಅಪರಿಚಿತ ಮೂಲಗಳ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಸ್ಥಾಪನೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ಈ ಬಳಕೆದಾರರು ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಈ ಬಳಕೆದಾರರನ್ನು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
-    <string name="ok" msgid="3468756155452870475">"ಸರಿ"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ಖಾಲಿ ಇಲ್ಲ"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ. ಕೊಂಚ ಸ್ಥಳವನ್ನು ಖಾಲಿ ಮಾಡಿ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿಲ್ಲ"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ಸ್ಥಾಪಿಸಲಾಗಿರುವ ಅಪ್ಲಿಕೇಶನ್‍ಗಳ ಪಟ್ಟಿಯಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿಲ್ಲ."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ಈ ಅಸ್ಥಾಪಿಸುವಿಕೆಯನ್ನು ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರಿಗೆ ನಿರ್ವಹಿಸಲು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"ದೋಷ"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ಅಪ್ಲಿಕೇಶನ್ ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"ನವೀಕರಣವನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ಎಂಬುದು ಕೆಳಗಿನ ಅಪ್ಲಿಕೇಶನ್‌ನ ಭಾಗವಾಗಿದೆ:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"ನೀವು ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ನೀವು "<b>"ಎಲ್ಲಾ"</b>" ಬಳಕೆದಾರರಿಗೂ ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅಸ್ಥಾಪಿಸಲು ಬಯಸುವಿರಾ? ಸಾಧನದಲ್ಲಿನ "<b>"ಎಲ್ಲಾ"</b>" ಬಳಕೆದಾರರಿಂದ ಅಪ್ಲಿಕೇಶನ್ ಮತ್ತು ಅದರ ಡೇಟಾವನ್ನು ತೆಗೆದುಹಾಕಲಾಗುವುದು."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> ಬಳಕೆದಾರರಿಗೆ ಈ ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಅಸ್ಥಾಪಿಸಲು ನೀವು ಬಯಸುವಿರಾ?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಬದಲಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುವುದೇ? ಎಲ್ಲಾ ಡೇಟಾ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ಈ ಅಪ್ಲಿಕೇಶನ್ ಬದಲಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುವುದೇ? ಎಲ್ಲಾ ಡೇಟಾ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ. ಕೆಲಸದ ಪ್ರೊಫೈಲ್‌ಗಳನ್ನು ಹೊಂದಿರುವವುಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ಈ ಸಾಧನದ ಎಲ್ಲಾ ಬಳಕೆದಾರರಿಗೆ ಇದು ಪರಿಣಾಮ ಬೀರುತ್ತದೆ."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ಚಾಲನೆಯಲ್ಲಿರುವ ಅಸ್ಥಾಪನೆಗಳು"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ವಿಫಲಗೊಂಡ ಅಸ್ಥಾಪನೆಗಳು"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"ಅಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಪೂರ್ಣಗೊಂಡಿದೆ."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅಸ್ಥಾಪಿಸಲಾಗಿದೆ"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ವಿಫಲವಾಗಿದೆ."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅಸ್ಥಾಪಿಸುವಿಕೆ ಯಶಸ್ವಿಯಾಗಲಿಲ್ಲ."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ಸಕ್ರಿಯ ಸಾಧನ ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> ಗಾಗಿ ಸಕ್ರಿಯ ಸಾಧನ ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್ ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ಕೆಲವು ಬಳಕೆದಾರರು ಅಥವಾ ಪ್ರೊಫೈಲ್‌ಗಳಿಗೆ ಈ ಅಪ್ಲಿಕೇಶನ್ ಅಗತ್ಯವಿರುತ್ತದೆ ಮತ್ತು ಇತರರಿಗೆ ಅಸ್ಥಾಪಿಸಲಾಗಿದೆ"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ಈ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ನಿಮ್ಮ ಪ್ರೊಫೈಲ್‌‌ನ ಅಗತ್ಯವಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ಈ ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮ ಸಾಧನ ನಿರ್ವಾಹಕರಿಗೆ ಅಗತ್ಯವಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"ಸಾಧನದ ನಿರ್ವಹಣೆ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ಬಳಕೆದಾರರನ್ನು ನಿರ್ವಹಿಸಿ"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ಪ್ಯಾಕೇಜ್ ಪಾರ್ಸ್ ಮಾಡುವಲ್ಲಿ ಸಮಸ್ಯೆ ಕಂಡುಬಂದಿದೆ."</string>
-    <string name="newPerms" msgid="6039428254474104210">"ಹೊಸತು"</string>
-    <string name="allPerms" msgid="1024385515840703981">"ಎಲ್ಲಾ"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"ಗೌಪ್ಯತೆ"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ಸಾಧನ ಪ್ರವೇಶ"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ಈ ನವೀಕರಣಕ್ಕೆ ಯಾವುದೇ ಹೊಸ ಅನುಮತಿಗಳ ಅಗತ್ಯವಿಲ್ಲ."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ನಿರಾಕರಿಸಿ"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿ"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ಹೇಗಾದರೂ ನಿರಾಕರಿಸಿ"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> ರಲ್ಲಿ <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"<xliff:g id="ACTION">%2$s</xliff:g> <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; to <xliff:g id="ACTION">%2$s</xliff:g> ಅನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸುವುದೇ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ಅಪ್ಲಿಕೇಶನ್ ಬಳಸುವಾಗ ಮಾತ್ರ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ಯಾವಾಗಲೂ"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ನಿರಾಕರಿಸಿ ಹಾಗೂ ಮತ್ತೊಮ್ಮೆ ಕೇಳಬೇಡ"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"ಎಲ್ಲಾ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ಯಾವುದನ್ನೂ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿಲ್ಲ"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ಅನುಮತಿಸಿ"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಗಳು"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"ಮತ್ತೆ ಕೇಳಬೇಡಿ"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"ಯಾವುದೇ ಅನುಮತಿಗಳಿಲ್ಲ"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"ಹೆಚ್ಚುವರಿ ಅನುಮತಿಗಳು"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿಯನ್ನು ತೆರೆಯಿರಿ"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಇನ್ನಷ್ಟು</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಇನ್ನಷ್ಟು</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ಈ ಅಪ್ಲಿಕೇಶನ್ Android ನ ಹಳೆಯ ಆವೃತ್ತಿಗೆ ವಿನ್ಯಾಸಗೊಳಿಸಲಾಗಿತ್ತು. ಅನುಮತಿ ನಿರಾಕರಿಸುವಿಕೆ ಇನ್ನು ಮುಂದೆ ಉದ್ದೇಶಿಸಲ್ಪಟ್ಟಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸದೆ ಇರುವುದಕ್ಕೆ ಇದು ಕಾರಣವಾಗಬಹುದು."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ಅಪರಿಚಿತ ಕ್ರಿಯೆಯನ್ನು ಮಾಡಿ"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="COUNT_0">%1$d</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಅನುಮತಿಸಲಾಗಿದೆ"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"ಸಿಸ್ಟಂ ತೋರಿಸು"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"ಸಿಸ್ಟಂ ಮರೆಮಾಡು"</string>
-    <string name="no_apps" msgid="1965493419005012569">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಇಲ್ಲ"</string>
-    <string name="location_settings" msgid="1774875730854491297">"ಸ್ಥಳ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್ ಈ ಸಾಧನಕ್ಕೆ ಸ್ಥಳ ಸೇವೆಗಳನ್ನು ಒದಗಿಸುತ್ತದೆ. ಸ್ಥಳ ಪ್ರವೇಶವನ್ನು ಸ್ಥಳ ಸೆಟ್ಟಿಂಗ್‌ಗಳಿಂದ ಮಾರ್ಪಡಿಸಬಹುದು."</string>
-    <string name="system_warning" msgid="7103819124542305179">"ನೀವು ಈ ಅನುಮತಿಯನ್ನು ನಿರಾಕರಿಸಿದರೆ, ಇನ್ನು ಮುಂದೆ ನಿಮ್ಮ ಸಾಧನದ ಮೂಲ ವೈಶಿಷ್ಟ್ಯಗಳು ಉದ್ದೇಶಿದಂತೆ ಕಾರ್ಯನಿರ್ವಹಿಸದಿರಬಹುದು."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ನೀತಿಯ ಮೂಲಕ ಜಾರಿಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ನೀತಿಯ ಮೂಲಕ ಹಿನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ನೀತಿ ಮೂಲಕ ಹಿನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾದ"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ನೀತಿ ಮೂಲಕ ಮುನ್ನೆಲೆ ಪ್ರವೇಶವನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾದ"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ನಿರ್ವಾಹಕರ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗಿದೆ"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ಯಾವಾಗಲೂ"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"ಅಪ್ಲಿಕೇಶನ್ ಬಳಸುವಾಗ ಮಾತ್ರ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ಎಂದೂ ಇಲ್ಲ"</string>
-    <string name="loading" msgid="7811651799620593731">"ಲೋಡ್ ಆಗುತ್ತಿದೆ..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"ಎಲ್ಲ ಅನುಮತಿಗಳು"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"ಇತರ ಅಪ್ಲಿಕೇಶನ್ ಸಾಮರ್ಥ್ಯಗಳು"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"ಅನುಮತಿ ವಿನಂತಿ"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"ಪರದೆ ಆವರಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಪತ್ತೆಹಚ್ಚಲಾಗಿದೆ"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ಈ ಅನುಮತಿ ಸೆಟ್ಟಿಂಗ್ ಬದಲಾಯಿಸಲು, ನೀವು ಮೊದಲು ಸೆಟ್ಟಿಂಗ್‌ಗಳು &gt; ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಂದ ಪರದೆ ಆವರಿಸಿಕೊಳ್ಳುವಿಕೆಯನ್ನು ಆಫ್ ಮಾಡಬೇಕು"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ಸೆಟ್ಟಿಂಗ್‍ಗಳನ್ನು ತೆರೆಯಿರಿ"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ನಲ್ಲಿ ಸ್ಥಾಪಿಸುವಿಕೆ/ಅಸ್ಥಾಪಿಸುವಿಕೆ ಕ್ರಿಯೆಗಳು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಗೆ ಪ್ರವೇಶಿಸಲು ಯಾವುದನ್ನು ಅನುಮತಿಸಬೇಕು ಎಂಬುದನ್ನು ಆರಿಸಿಕೊಳ್ಳಿ"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲಾಗಿದೆ. ಈ ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಪ್ರವೇಶಿಸಲು ಯಾವುದನ್ನು ಅನುಮತಿಸಬೇಕು ಎಂಬುದನ್ನು ಆರಿಸಿಕೊಳ್ಳಿ."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"ರದ್ದುಮಾಡಿ"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"ಮುಂದುವರಿಸು"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"ಹೊಸ ಅನುಮತಿಗಳು"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"ಪ್ರಸ್ತುತ ಅನುಮತಿಗಳು"</string>
-    <string name="message_staging" msgid="6151794817691100003">"ಸ್ಥಾಪಿಸಲು ಸಿದ್ಧವಿರುವ ಅಪ್ಲಿಕೇಶನ್…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"ಅಪರಿಚಿತ"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಈ ಮೂಲದಿಂದ ಬಂದಿರುವ ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಅಪರಿಚಿತ ಮೂಲಗಳಿಂದ ಪಡೆದುಕೊಳ್ಳುವ ಅಪ್ಲಿಕೇಶನ್‍‍ಗಳನ್ನು ನಿಮ್ಮ ಟಿವಿಯು ಸ್ಥಾಪಿಸದಂತೆ ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಈ ಮೂಲದಿಂದ ಬಂದಿರುವ ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ನಿಮ್ಮ ಫೋನ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ನಿಮ್ಮ ಫೋನ್ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸುವ ಮೂಲಕ, ನಿಮ್ಮ ಫೋನ್‌ಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸ್ಥಾಪಿಸುವ ಮೂಲಕ, ನಿಮ್ಮ ಫೋನ್‌ಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ನಿಮ್ಮ ಟಿವಿ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಸ್ಥಾಪಿಸುವ ಮೂಲಕ, ನಿಮ್ಮ ಟಿವಿಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ಮುಂದುವರಿಸಿ"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"wear ಅಪ್ಲಿಕೇಶನ್‌ ಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ/ಅಸ್ಥಾಪಿಸಲಾಗುತ್ತಿದೆ"</string>
+    <string name="app_name" msgid="7488448184431507488">"ಪ್ಯಾಕೇಜ್ ಇನ್‌ಸ್ಟಾಲರ್‌‌"</string>
+    <string name="install" msgid="711829760615509273">"ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+    <string name="done" msgid="6632441120016885253">"ಮುಗಿದಿದೆ"</string>
+    <string name="cancel" msgid="1018267193425558088">"ರದ್ದುಮಾಡಿ"</string>
+    <string name="installing" msgid="4921993079741206516">"ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="install_done" msgid="5987363587661783896">"ಆ್ಯಪ್‌ ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗಿದೆ."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"ನೀವು ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಬಯಸುವಿರಾ?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"ನೀವು ಈ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಆ್ಯಪ್‌ನ ಅಪ್‌ಡೇಟ್‌‌ ಆದ ಆ್ಯಪ್‌ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಿಕೊಳ್ಳಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"ನೀವು ಈ ಅಂತನಿರ್ಮಿತ ಆ್ಯಪ್‌ನ ಅಪ್‌ಡೇಟ್‌‌ ಆದ ಆ್ಯಪ್‌ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಿಕೊಳ್ಳಲು ಬಯಸುವಿರಾ? ಈಗಿರುವ ನಿಮ್ಮ ಡೇಟಾ ಕಳೆದು ಹೋಗುವುದಿಲ್ಲ. ಇದಕ್ಕೆ ಯಾವುದೇ ವಿಶೇಷ ಪ್ರವೇಶದ ಅಗತ್ಯವಿಲ್ಲ."</string>
+    <string name="install_failed" msgid="5777824004474125469">"ಆ್ಯಪ್‌ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗಿಲ್ಲ."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡುವ ಪ್ಯಾಕೇಜ್‌ ಅನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"ಪ್ಯಾಕೇಜ್‌ನಂತೆ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗಿರುವ ಆ್ಯಪ್‌ ಅಸ್ತಿತ್ವದಲ್ಲಿರುವ ಪ್ಯಾಕೇಜ್ ಜೊತೆಗೆ ಸಂಘರ್ಷವಾಗುತ್ತದೆ."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"ಆ್ಯಪ್‌ನಂತೆ ಇನ್‌ಸ್ಟಾಲ್‌ ಆಗದಿರುವ ಆ್ಯಪ್‌ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"ಈ ಆ್ಯಪ್‌ ನಿಮ್ಮ ಟಿವಿ ಜೊತೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"ಆ್ಯಪ್‌ನಂತೆ ಇನ್‌ಸ್ಟಾಲ್‌ ಆಗದಿರುವ ಆ್ಯಪ್‌ ನಿಮ್ಮ ಫೋನ್ ಜೊತೆಗೆ ಹೊಂದಾಣಿಕೆಯಾಗುವುದಿಲ್ಲ."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"ಪ್ಯಾಕೇಜ್‌ನಂತೆ ಇನ್‌ಸ್ಟಾಲ್‌ ಆಗದಿರುವ ಆ್ಯಪ್‌ ಅಮಾನ್ಯವಾಗಿರುವಂತೆ ತೋರುತ್ತದೆ."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ನಲ್ಲಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"ಈ ಬಳಕೆದಾರರು ಅಪರಿಚಿತ ಆ್ಯಪ್‌ಗಳನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ಆ್ಯಪ್‌ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಈ ಬಳಕೆದಾರರನ್ನು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
+    <string name="ok" msgid="7871959885003339302">"ಸರಿ"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"ಆ್ಯಪ್ ನಿರ್ವಹಿಸಿ"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"ಸಂಗ್ರಹಣೆ ಖಾಲಿ ಇಲ್ಲ"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ. ಕೊಂಚ ಸ್ಥಳವನ್ನು ಖಾಲಿ ಮಾಡಿ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"ಯಾವುದೇ ಆ್ಯಪ್ ಕಂಡುಬಂದಿಲ್ಲ"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಿರುವ ಆ್ಯಪ್‌ಗಳ ಪಟ್ಟಿಯಲ್ಲಿ ಯಾವುದೇ ಆ್ಯಪ್‌ ಕಂಡುಬಂದಿಲ್ಲ."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"ಈ ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡುವಿಕೆಯನ್ನು ಪ್ರಸ್ತುತ ಬಳಕೆದಾರರಿಗೆ ನಿರ್ವಹಿಸಲು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"ದೋಷ"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"ಆ್ಯಪ್‌ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"ಆ್ಯಪ್‌ ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"ಅಪ್‌ಡೇಟ್‌ ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ಎಂಬುದು ಕೆಳಗಿನ ಆ್ಯಪ್‌ನ ಭಾಗವಾಗಿದೆ:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"ನೀವು ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಬಯಸುವಿರಾ?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"ನೀವು "<b>"ಎಲ್ಲಾ"</b>" ಬಳಕೆದಾರರಿಗೂ ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಬಯಸುವಿರಾ? ಸಾಧನದಲ್ಲಿನ "<b>"ಎಲ್ಲಾ"</b>" ಬಳಕೆದಾರರಿಂದ ಆ್ಯಪ್‌ ಮತ್ತು ಅದರ ಡೇಟಾವನ್ನು ತೆಗೆದುಹಾಕಲಾಗುವುದು."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> ಬಳಕೆದಾರರಿಗೆ ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ನೀವು ಬಯಸುವಿರಾ?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ಈ ಆ್ಯಪ್‌ ಬದಲಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುವುದೇ? ಎಲ್ಲಾ ಡೇಟಾ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ಈ ಆ್ಯಪ್‌ ಬದಲಿಗೆ ಫ್ಯಾಕ್ಟರಿ ಆವೃತ್ತಿಯನ್ನು ಬದಲಾಯಿಸುವುದೇ? ಎಲ್ಲಾ ಡೇಟಾ ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ. ಕೆಲಸದ ಪ್ರೊಫೈಲ್‌ಗಳನ್ನು ಹೊಂದಿರುವವುಗಳನ್ನು ಒಳಗೊಂಡಂತೆ ಈ ಸಾಧನದ ಎಲ್ಲಾ ಬಳಕೆದಾರರಿಗೆ ಇದು ಪರಿಣಾಮ ಬೀರುತ್ತದೆ."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"ಚಾಲನೆಯಲ್ಲಿರುವ ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ಗಳು"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"ವಿಫಲಗೊಂಡ ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ಗಳು"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ಅನ್ನು ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="uninstall_done" msgid="439354138387969269">"ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್ ಪೂರ್ಣಗೊಂಡಿದೆ."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear ನಲ್ಲಿ ಇನ್‌ಸ್ಟಾಲ್/ಅನ್ಇನ್‌ಸ್ಟಾಲ್ ಕ್ರಿಯೆಗಳು ಬೆಂಬಲಿತವಾಗಿಲ್ಲ."</string>
+    <string name="message_staging" msgid="8032722385658438567">"ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಲು ಸಿದ್ಧವಿರುವ ಆ್ಯಪ್…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"ಅಪರಿಚಿತ"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಈ ಮೂಲದಿಂದ ಬಂದಿರುವ ಅಪರಿಚಿತ ಆ್ಯಪ್‌ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಅಪರಿಚಿತ ಮೂಲಗಳಿಂದ ಪಡೆದುಕೊಳ್ಳುವ ಆ್ಯಪ್‌‍‍ಗಳನ್ನು ನಿಮ್ಮ ಟಿವಿಯಲ್ಲಿ ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ಅನುಮತಿಯಿಲ್ಲ."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"ನಿಮ್ಮ ಸುರಕ್ಷತೆಯ ದೃಷ್ಟಿಯಿಂದ, ಈ ಮೂಲದಿಂದ ಬಂದಿರುವ ಅಪರಿಚಿತ ಆ್ಯಪ್‌ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲು ನಿಮ್ಮ ಫೋನ್‌ಗೆ ಅನುಮತಿಯಿಲ್ಲ."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"ನಿಮ್ಮ ಫೋನ್ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಆ್ಯಪ್‌ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡುವ ಮೂಲಕ, ನಿಮ್ಮ ಫೋನ್‌ಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಆ್ಯಪ್‌ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡುವ ಮೂಲಕ, ನಿಮ್ಮ ಫೋನ್‌ಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ನಿಮ್ಮ ಟಿವಿ ಹಾಗೂ ವೈಯಕ್ತಿಕ ಡೇಟಾ, ಅಪರಿಚಿತ ಆ್ಯಪ್‌ಗಳ ದಾಳಿಗೆ ತುತ್ತಾಗುವ ಸಾಧ್ಯತೆ ಹೆಚ್ಚಾಗಿದೆ. ಈ ಆ್ಯಪ್‌ ಅನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡುವ ಮೂಲಕ, ನಿಮ್ಮ ಟಿವಿಗೆ ಯಾವುದೇ ಹಾನಿ ಉಂಟಾದರೆ ಅಥವಾ ಅದರ ಬಳಕೆಯಿಂದ ಡೇಟಾ ನಷ್ಟವಾದರೆ, ಅದಕ್ಕೆ ನೀವೇ ಜವಾಬ್ದಾರರು ಎನ್ನುವುದನ್ನು ಒಪ್ಪಿಕೊಳ್ಳುತ್ತೀರಿ."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"ಮುಂದುವರಿಸಿ"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"wear ಆ್ಯಪ್‌ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್‌/ಅನ್‌ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ko/strings.xml b/packages/PackageInstaller/res/values-ko/strings.xml
index 235a1d4..50f8157 100644
--- a/packages/PackageInstaller/res/values-ko/strings.xml
+++ b/packages/PackageInstaller/res/values-ko/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"패키지 설치 프로그램"</string>
-    <string name="next" msgid="3057143178373252333">"다음"</string>
-    <string name="install" msgid="5896438203900042068">"설치"</string>
-    <string name="done" msgid="3889387558374211719">"완료"</string>
-    <string name="cancel" msgid="8360346460165114585">"취소"</string>
-    <string name="installing" msgid="8613631001631998372">"설치 중..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 설치 중…"</string>
-    <string name="install_done" msgid="3682715442154357097">"앱이 설치되었습니다."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"이 애플리케이션을 설치하시겠습니까? 애플리케이션이 다음에 액세스할 수 있습니다."</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"이 애플리케이션을 설치하시겠습니까? 특별한 액세스 권한이 필요하지 않습니다."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"기존 애플리케이션에 업데이트를 설치하시겠습니까? 기존 데이터는 손실되지 않습니다. 업데이트된 애플리케이션이 다음에 액세스할 수 있습니다."</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"내장 애플리케이션에 업데이트를 설치하시겠습니까? 기존 데이터는 손실되지 않습니다. 업데이트된 애플리케이션이 다음에 액세스할 수 있습니다."</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"기존의 애플리케이션 업데이트를 설치하시겠습니까? 기존의 데이터는 손실되지 않으며 특별한 액세스 권한이 필요하지 않습니다."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"내장 애플리케이션 업데이트를 설치하시겠습니까? 기존의 데이터는 손실되지 않으며 특별한 액세스 권한이 필요하지 않습니다."</string>
-    <string name="install_failed" msgid="6579998651498970899">"앱이 설치되지 않았습니다."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"패키지 설치가 차단되었습니다."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"패키지가 기존 패키지와 충돌하여 앱이 설치되지 않았습니다."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"앱이 태블릿과 호환되지 않아서 설치되지 않았습니다."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"앱이 사용 중인 TV와 호환되지 않습니다."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"앱이 휴대전화와 호환되지 않아서 설치되지 않았습니다."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"패키지가 잘못되어 앱이 설치되지 않았습니다."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"태블릿에 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>을(를) TV에 설치할 수 없습니다."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"휴대전화에 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다."</string>
-    <string name="launch" msgid="4826921505917605463">"열기"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"관리자가 알 수 없는 출처의 앱 설치를 허용하지 않습니다."</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"이 사용자는 알 수 없는 앱을 설치할 수 없습니다."</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"이 사용자는 앱을 설치할 권한이 없습니다."</string>
-    <string name="ok" msgid="3468756155452870475">"확인"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"앱 관리"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"여유 공간이 없음"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다. 여유 공간을 늘린 후에 다시 시도하세요."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"앱을 찾을 수 없음"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"설치된 앱 목록에 앱이 없습니다."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"허용되지 않음"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"현재 사용자는 이 제거를 수행할 수 없습니다."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"오류"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"앱을 제거할 수 없습니다."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"앱 제거"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"업데이트 제거"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>은(는) 다음 앱의 일부입니다."</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"이 앱을 제거하시겠습니까?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222"><b>"모든"</b>" 사용자에 대해 이 앱을 제거하시겠습니까? 기기를 사용하는 "<b>"모든"</b>" 사용자에 대해 애플리케이션 및 데이터가 삭제됩니다."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g>님의 기기에 설치된 앱을 제거하시겠습니까?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"이 앱을 초기 버전으로 바꾸시겠습니까? 모든 데이터가 삭제됩니다."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"이 앱을 초기 버전으로 바꾸시겠습니까? 모든 데이터가 삭제되며 직장 프로필 사용자를 포함해 이 기기의 모든 사용자에게 영향을 미칩니다."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"실행 중인 제거 작업"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"실패한 제거 작업"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"제거 중..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 제거 중…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"제거를 완료했습니다."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>을(를) 제거했습니다."</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"제거하지 못했습니다."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>을(를) 제거하지 못했습니다."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"활성 상태의 기기 관리자 앱을 제거할 수 없습니다."</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>의 활성 상태의 기기 관리자 앱을 제거할 수 없습니다."</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"이 앱은 일부 사용자 또는 프로필에 필요하며 다른 사용자에 대해서는 제거되었습니다."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"이 앱은 프로필에 필요하므로 삭제할 수 없습니다."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"이 앱은 기기 관리자에게 필요하므로 제거할 수 없습니다."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"기기 관리자 앱 관리"</string>
-    <string name="manage_users" msgid="3125018886835668847">"사용자 관리"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 제거할 수 없습니다."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"패키지를 파싱하는 중 문제가 발생했습니다."</string>
-    <string name="newPerms" msgid="6039428254474104210">"새 권한"</string>
-    <string name="allPerms" msgid="1024385515840703981">"전체"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"개인정보 보호"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"기기 액세스"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"이 업데이트에는 새로운 권한이 필요하지 않습니다."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"거부"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"추가 정보"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"거부"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;의 다음 작업을 허용하시겠습니까? <xliff:g id="ACTION">%2$s</xliff:g>"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 <xliff:g id="ACTION">%2$s</xliff:g>하도록 허용하시겠습니까??"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"앱 사용 중에만"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"항상"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"거부 및 다시 묻지 않음"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>개 중지됨"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"모두 중지됨"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"아무것도 중지되지 않음"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"허용"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"앱"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"앱 권한"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"다시 묻지 않음"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"권한이 없음"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"추가 권한"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"앱 정보 열기"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개 더보기</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개 더보기</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"이 앱은 Android 이전 버전에 맞게 설계되었습니다. 권한을 거부하면 정상적으로 작동하지 않을 수 있습니다."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"알 수 없는 작업 수행"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>개 앱 허용됨"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"시스템 표시"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"시스템 숨기기"</string>
-    <string name="no_apps" msgid="1965493419005012569">"앱 없음"</string>
-    <string name="location_settings" msgid="1774875730854491297">"위치 설정"</string>
-    <string name="location_warning" msgid="8778701356292735971">"이 기기의 위치 서비스 제공업체는 <xliff:g id="APP_NAME">%1$s</xliff:g>입니다. 위치 정보 액세스는 위치 설정에서 수정할 수 있습니다."</string>
-    <string name="system_warning" msgid="7103819124542305179">"이 권한을 거부하는 경우 기기의 기본 기능이 제대로 작동하지 않을 수 있습니다."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"정책에 의해 시행됨"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"정책에 따라 백그라운드 액세스 사용 중지됨"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"정책에 따라 백그라운드 액세스 사용 설정함"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"정책에 따라 포그라운드 액세스 사용 설정함"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"관리자가 제어"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"항상"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"앱 사용 중에만"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"사용 안함"</string>
-    <string name="loading" msgid="7811651799620593731">"로드 중..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"모든 권한"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"다른 앱 기능"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"권한 요청"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"화면 오버레이 감지됨"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"이 권한 설정을 변경하려면 먼저 설정 &gt; 앱에서 화면 오버레이를 사용하지 않도록 설정해야 합니다."</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"설정 열기"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear에서 지원하지 않는 설치/제거 작업입니다."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;에서 액세스하도록 허용할 항목을 선택하세요."</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;이(가) 업데이트되었습니다. 이 앱에서 액세스하도록 허용할 항목을 선택하세요."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"취소"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"계속"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"새로운 권한"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"기존 권한"</string>
-    <string name="message_staging" msgid="6151794817691100003">"앱 준비 중…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"알 수 없음"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"보안상의 이유로 이 경로를 통한 알 수 없는 앱을 태블릿에 설치할 수 없습니다."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"보안상의 이유로 이 경로를 통한 알 수 없는 앱을 TV에 설치할 수 없습니다."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"보안상의 이유로 이 경로를 통한 알 수 없는 앱을 휴대전화에 설치할 수 없습니다."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"휴대전화와 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 휴대전화 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"태블릿과 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 태블릿 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV와 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 TV 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"계속"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"설정"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear 앱 설치/제거"</string>
+    <string name="app_name" msgid="7488448184431507488">"패키지 설치 프로그램"</string>
+    <string name="install" msgid="711829760615509273">"설치"</string>
+    <string name="done" msgid="6632441120016885253">"완료"</string>
+    <string name="cancel" msgid="1018267193425558088">"취소"</string>
+    <string name="installing" msgid="4921993079741206516">"설치 중..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 설치 중…"</string>
+    <string name="install_done" msgid="5987363587661783896">"앱이 설치되었습니다."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"이 애플리케이션을 설치하시겠습니까?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"이 기존 애플리케이션에 대한 업데이트를 설치하시겠습니까? 기존 데이터는 유지됩니다."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"이 내장 애플리케이션에 대한 업데이트를 설치하시겠습니까? 기존 데이터는 유지됩니다."</string>
+    <string name="install_failed" msgid="5777824004474125469">"앱이 설치되지 않았습니다."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"패키지 설치가 차단되었습니다."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"패키지가 기존 패키지와 충돌하여 앱이 설치되지 않았습니다."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"앱이 태블릿과 호환되지 않아서 설치되지 않았습니다."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"앱이 사용 중인 TV와 호환되지 않습니다."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"앱이 휴대전화와 호환되지 않아서 설치되지 않았습니다."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"패키지가 잘못되어 앱이 설치되지 않았습니다."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"태블릿에 <xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"TV에 <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_user_restriction_dlg_text" msgid="151020786933988344">"이 사용자는 알 수 없는 앱을 설치할 수 없습니다."</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"이 사용자는 앱을 설치할 권한이 없습니다."</string>
+    <string name="ok" msgid="7871959885003339302">"확인"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"앱 관리"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"여유 공간이 없음"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> 앱을 설치할 수 없습니다. 여유 공간을 늘린 후에 다시 시도하세요."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"앱을 찾을 수 없음"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"설치된 앱 목록에 앱이 없습니다."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"허용되지 않음"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"현재 사용자는 이 제거를 처리할 수 없습니다."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"오류"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"앱을 제거할 수 없습니다."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"앱 제거"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"업데이트 제거"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>은(는) 다음 앱의 일부입니다."</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"이 앱을 제거하시겠습니까?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119"><b>"모든"</b>" 사용자에 대해 이 앱을 제거하시겠습니까? 기기를 사용하는 "<b>"모든"</b>" 사용자에 대해 애플리케이션 및 데이터가 삭제됩니다."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g>님의 기기에 설치된 앱을 제거하시겠습니까?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"이 앱을 초기 버전으로 바꾸시겠습니까? 모든 데이터가 삭제됩니다."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"이 앱을 초기 버전으로 바꾸시겠습니까? 모든 데이터가 삭제되며 직장 프로필 사용자를 포함해 이 기기의 모든 사용자에게 영향을 미칩니다."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"실행 중인 제거 작업"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"실패한 제거 작업"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"제거 중..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> 제거 중…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"제거를 완료했습니다."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear에서 지원되지 않는 설치/제거 작업"</string>
+    <string name="message_staging" msgid="8032722385658438567">"앱 준비 중…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"알 수 없음"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"보안상의 이유로 이 소스의 알 수 없는 앱을 태블릿에 설치할 수 없습니다."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"보안상의 이유로 이 소스의 알 수 없는 앱을 TV에 설치할 수 없습니다."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"보안상의 이유로 이 소스의 알 수 없는 앱을 휴대전화에 설치할 수 없습니다."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"휴대전화와 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 휴대전화 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"태블릿과 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 태블릿 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV와 개인 데이터는 알 수 없는 앱의 공격에 더욱 취약합니다. 이 앱을 설치하면 앱 사용으로 인해 발생할 수 있는 모든 TV 손상이나 데이터 손실에 사용자가 책임을 진다는 것에 동의하게 됩니다."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"계속"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"설정"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear 앱 설치/제거"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ky/strings.xml b/packages/PackageInstaller/res/values-ky/strings.xml
index 9a95c54..94da72f 100644
--- a/packages/PackageInstaller/res/values-ky/strings.xml
+++ b/packages/PackageInstaller/res/values-ky/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Топтом орноткуч"</string>
-    <string name="next" msgid="3057143178373252333">"Кийинки"</string>
-    <string name="install" msgid="5896438203900042068">"Орнотуу"</string>
-    <string name="done" msgid="3889387558374211719">"Даяр"</string>
-    <string name="cancel" msgid="8360346460165114585">"Жокко чыгаруу"</string>
-    <string name="installing" msgid="8613631001631998372">"Орнотулууда…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> орнотулууда…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Колдонмо орнотулду."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Бул колдонмону орнотоюн дегениңиз аныкпы? Ал кийинкилерге жетки алат:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Бул колдонмону орнотоюн дегениңиз аныкпы? Ал эч бир атайын жетки уруксаттарын талап кылбайт."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Учурда иштеп турган бул колдонмого жаңыртуу орнотоюн дегениңиз аныкпы? Сиздин сакталган берилиштериңиз өчүрүлбөйт. Жаңыртылган колдонмо кийинкилерге жетки алат:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Бул камтылган колдонмого жаңыртуу орнотоюн дегениңиз аныкпы? Сиздин сакталган берилиштериңиз өчүрүлбөйт. Жаңыртылган колдонмо кийинкилерге жетки алат:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Учурда иштпе турган бул колдонмого жаңыртуу орнотоюн дегениңиз аныкпы? Сиздин сакталган берилиштериңиз өчүрүлбөйт. Ал эч бир атайын жетки уруксаттарын талап кылбайт."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Бул камтылган колдонмого жаңыртуу орнотоюн дегениңиз аныкпы? Сиздин сакталган берилиштериңиз өчүрүлбөйт. Ал эч бир атайын жетки уруксаттарын  талап кылбайт."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Колдонмо орнотулган жок."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Топтом орнотуудан бөгөттөлгөн."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Башка топтом менен дал келбегендиктен колдонмо орнотулган жок."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Бул колдонмо планшетиңизге шайкеш эмес болгондуктан колдонмо орнотулган жок."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Бул колдонмо сыналгыңызга шайкеш келбейт."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Бул колдонмо телефонуңузга шайкеш эмес болгондуктан колдонмо орнотулган жок."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Топтом катары орнотулбай калган колдонмо жараксыз окшойт."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун планшетиңизге орнотуу мүмкүн эмес."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> сыналгыңызга орнотулбай койду."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун телефонуңузга орнотуу мүмкүн эмес."</string>
-    <string name="launch" msgid="4826921505917605463">"Ачуу"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Администраторуңуз белгисиз булактардан алынган колдонмолордун орнотулушуна жол бербейт"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Бул колдонуучу белгисиз колдонмолорду орното албайт"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Бул колдонуучу колдонмолорду орното албайт"</string>
-    <string name="ok" msgid="3468756155452870475">"Жарайт"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Колдонмолорду башкаруу"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Бош орун жок"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун телефонуңузга орнотуу мүмкүн эмес. Орун бошотуп, кайталап орнотуп көрүңүз."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Колдонмо табылган жок"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Колдонмо орнотулган колдонмолор тизмегинен табылган жок."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Тыюу салынган"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Учурдагы колдонуучу колдонмону чыгарып сала албайт."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Ката"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Колдонмону чыгарып салуу мүмкүн болбой жатат."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Колдонмону чечип салуу"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Жаңыртууну чечип салуу"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> кийинки колдонмонун бөлүгү:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Бул колдонмону чечип салгыңыз келеби?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Бул колдонмо "<b>"бардык"</b>" колдонуучулардан алынып салынсынбы? Бул колдонмо жана анын берилиштери бул түзмөктүн "<b>"бардык"</b>" колдонуучуларынан алынат."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Бул колдонмону <xliff:g id="USERNAME">%1$s</xliff:g> колдонуучусу үчүн орнотуудан чыгаргыңыз келеби?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Бул колдонмонун баштапкы версиясы орнотулсунбу? Бардык дайындар өчүп калат."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Бул колдонмонун баштапкы версиясы орнотулсунбу? Түзмөктөгү бардык профилдердин, ошондой эле жумушчу профилдин дайындары өчүп калат."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Чыгарылып салынууда"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Чыгарылып салынбай калгандар"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Чыгарылып салынууда…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> колдонмосу чыгарылууда…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Чечилип бүттү."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> колдонмосу чыгарылды"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Чечүү ийгиликсиз болду."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> колдонмосун чыгарып салуу ишке ашкан жок."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Түзмөктү башкарган колдонмо иштеп жатканда аны чыгарып салууга болбойт"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> колдонуучусунун түзмөктү башкарган колдонмосу иштеп жатканда, аны чыгарып салууга болбойт"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Колдонмо айрым колдонуучулар же профилдерге керек."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Бул колдонмо профилиңизге керек жана аны чыгарып салуу мүмкүн эмес."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Бул колдонмо түзмөк администраторуңузга керектелет жана орнотуудан чыгаруу мүмкүн эмес."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Түзмөктү башкарган колдонмолорду көзөмөлдөө"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Колдонуучуларды башкаруу"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун чечип салуу мүмкүн эмес."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Таңгакты окууда маселе пайда болду."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Жаңы"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Бардыгы"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Купуялуулук"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Жетүү уруксаттары"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Бул жаңыртуу жаңы уруксаттарды талап кылбайт."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Жок"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Көбүрөөк маалымат"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Баш тартуу"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> ичинен <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна <xliff:g id="ACTION">%2$s</xliff:g> уруксат берилсинби?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосуна <xliff:g id="ACTION">%2$s</xliff:g> аракетине ар дайым уруксат берилсинби?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Ушул колдонмодо иштегенде гана"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Ар дайым"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Баш тартам жана экинчи суралбасын"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> өчүрүлгөн"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"баары өчүрүлгөн"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"эч бири өчүрүлгөн жок"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Уруксат берүү"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Колдонмолор"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Колдонмо уруксаттары"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Экинчи суралбасын"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Уруксаттар жок"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Кошумча уруксаттар"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Колдонмо тууралуу маалыматты ачуу"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Дагы <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Дагы <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Бул колдонмо эски Android версиясы үчүн түзүлгөн. Уруксат берилбесе, ал туура эмес иштеп калышы мүмкүн."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"белгисиз аракеттерди жасайт"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> колдонмонун ичинен <xliff:g id="COUNT_0">%1$d</xliff:g> уруксат берилген"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Тутумду көрсөтүү"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Тутумдагы процесстерди жашыруу"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Бир дагы колдонмо жок"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Геолокация параметрлери"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> - бул түзмөктөгү жайгашкан жерди аныктоо кызматынын камсыздоочусу. Жайгашкан жерди көрүү мүмкүнчүлүгүн жайгашкан жерди аныктоо жөндөөлөрүнөн өзгөртсө болот."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Эгер бул уруксатты четке каксаңыз, түзмөгүңүздүн негизги функциялары талаптагыдай иштебей калышы мүмкүн."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Саясат тарабынан күчүнө киргизилген"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Фондук режимде колдонуу саясат тарабынан өчүрүлгөн"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Фондук режимде колдонуу саясат тарабынан иштетилген"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Активдүү режим саясат боюнча иштетилген"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Администратор тарабынан көзөмөлдөнөт"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Ар дайым"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Ушул колдонмодо иштегенде гана"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Эч качан"</string>
-    <string name="loading" msgid="7811651799620593731">"Жүктөлүүдө…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Бардык уруксаттар"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Колдонмонун башка жөндөмдөрү"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Уруксат суроо"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Экран кабатталышы аныкталды"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Бул уруксаттын жөндөөсүн өзгөртүү үчүн, адегенде Жөндөөлөр &gt; Колдонмолордон экрандын кабатталышын өчүрүңүз"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Жөндөөлөрдү ачуу"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Тагынма"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Орнотуу/чыгарып салуу аракеттери Android Wear\'де колдоого алынбайт."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; колдонмосу үчүн уруксаттарды тандаңыз"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; жаңыртылды. Ал үчүн уруксаттарды тандаңыз."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Жок"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Улантуу"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Жаңы уруксаттар"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Учурдагы уруксаттар"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Күтө туруңуз…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Белгисиз"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Коопсуздукту сактоо максатында, планшетиңизге бул булактан колдонмолорду орнотууга уруксат жок."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Коопсуздукту сактоо максатында, сыналгыңызга бул булактан колдонмолорду орнотууга уруксат жок."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Коопсуздукту сактоо максатында, телефонуңузга бул булактан колдонмолорду орнотууга уруксат жок."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефонуңуз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам телефонуңузга кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Планшетиңиз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам планшетиңизге кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам TV\'ңизге кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Улантуу"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Жөндөөлөр"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Тагынма колдонмолорду орнотуу/чыгаруу"</string>
+    <string name="app_name" msgid="7488448184431507488">"Топтомду орноткуч"</string>
+    <string name="install" msgid="711829760615509273">"Орнотуу"</string>
+    <string name="done" msgid="6632441120016885253">"Бүттү"</string>
+    <string name="cancel" msgid="1018267193425558088">"Жокко чыгаруу"</string>
+    <string name="installing" msgid="4921993079741206516">"Орнотулууда…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> орнотулууда…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Колдонмо орнотулду."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Бул колдонмону орнотоюн деп жатасызбы?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Учурдагы колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайындарыңыз өчүрүлбөйт."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Учурдагы алдын ала орнотулган колдонмону жаңыртканы жатасызбы? Буга чейин сакталган дайындарыңыз өчүрүлбөйт."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Колдонмо орнотулган жок."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Топтомду орнотууга болбойт."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Башка топтом менен дал келбегендиктен колдонмо орнотулган жок."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Бул колдонмо планшетиңизге шайкеш болбогондуктан колдонмо орнотулган жок."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Бул колдонмо сыналгыңызга шайкеш келбейт."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Бул колдонмо телефонуңузга шайкеш болбогондуктан колдонмо орнотулган жок."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Топтом катары орнотулбай калган колдонмо жараксыз окшойт."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу планшетиңизге орнотулбай койду."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Бул колдонуучу белгисиз колдонмолорду орното албайт"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Бул колдонуучу колдонмолорду орното албайт"</string>
+    <string name="ok" msgid="7871959885003339302">"ЖАРАЙТ"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Колд. башкаруу"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Бош орун жок"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосун телефонуңузга орнотуу мүмкүн эмес. Орун бошотуп, кайталап орнотуп көрүңүз."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Колдонмо табылган жок"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Колдонмо орнотулган колдонмолордун тизмесинде табылган жок."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Тыюу салынган"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Учурдагы колдонуучу колдонмону чыгарып сала албайт."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Ката"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Колдонмону чыгарып салуу мүмкүн болбой жатат."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Колдонмону чыгарып салуу"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Жаңыртууну чыгарып салуу"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> төмөнкү колдонмонун бөлүгү:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Бул колдонмону чыгарып саласызбы?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Бул колдонмо "<b>"бардык"</b>" колдонуучулардан алынып салынсынбы? Бул колдонмо жана анын дайындары бул түзмөктүн "<b>"бардык"</b>" колдонуучуларынан өчүрүлөт."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Бул колдонмону <xliff:g id="USERNAME">%1$s</xliff:g> үчүн чыгарып саласызбы?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Бул колдонмонун баштапкы версиясы орнотулсунбу? Бардык дайындар өчүп калат."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Бул колдонмонун баштапкы версиясы орнотулсунбу? Түзмөктөгү бардык профилдердин, ошондой эле жумушчу профилдердин дайындары өчүп калат."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Чыгарылып салынууда"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Чыгарылып салынбай калгандар"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Чыгарылып салынууда…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> чыгарылууда…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Чыгарылып салынды."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Орнотуу/чыгарып салуу аракеттери Android Wear\'де колдоого алынбайт."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Күтө туруңуз…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Белгисиз"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Коопсуздукту сактоо максатында, планшетиңизге бул булактан колдонмолорду орнотууга уруксат жок."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Коопсуздукту сактоо максатында, сыналгыңызга бул булактан колдонмолорду орнотууга уруксат жок."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Коопсуздукту сактоо максатында, телефонуңузга бул булактан колдонмолорду орнотууга уруксат жок."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефонуңуз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам телефонуңузга кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Планшетиңиз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам планшетиңизге кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Сыналгыңыз жана жеке дайындарыңыз белгисиз колдонмолордон зыян тартып калышы мүмкүн. Бул колдонмону орнотуп, аны пайдалануудан улам сыналгыңызга кандайдыр бир зыян келтирилсе же дайындарыңызды жоготуп алсаңыз, өзүңүз жооптуу болосуз."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Улантуу"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Жөндөөлөр"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Тагынма колдонмолорду орнотуу/чыгаруу"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-lo/strings.xml b/packages/PackageInstaller/res/values-lo/strings.xml
index f39f140..dba0dcc 100644
--- a/packages/PackageInstaller/res/values-lo/strings.xml
+++ b/packages/PackageInstaller/res/values-lo/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"ໂຕຕິດຕັ້ງແພັກເກດ"</string>
-    <string name="next" msgid="3057143178373252333">"ຕໍ່ໄປ"</string>
-    <string name="install" msgid="5896438203900042068">"ຕິດຕັ້ງ"</string>
-    <string name="done" msgid="3889387558374211719">"ແລ້ວໆ"</string>
-    <string name="cancel" msgid="8360346460165114585">"ຍົກເລີກ"</string>
-    <string name="installing" msgid="8613631001631998372">"ກຳລັງຕິດຕັ້ງ…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"ກຳລັງຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"ຕິດຕັ້ງແອັບຯແລ້ວ."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"ທ່ານຕ້ອງການຕິດຕັ້ງແອັບພລິເຄຊັນນີ້ບໍ່? ມັນຈະໄດ້ສິດການເຂົ້າເຖິງ:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ທ່ານ​ຕ້ອງ​ການ​ຕິດ​ຕັ້ງ​ແອັບພລິເຄຊັນນີ້ບໍ່​? ມັນ​ບໍ່​ຕ້ອງໃຊ້ສິດທິການ​ເຂົ້າ​ເຖິງ​​ພິ​ເສດໃດໆ."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"ທ່ານຕ້ອງການຕິດຕັ້ງອັບເດດໃສ່ແອັບພລິເຄຊັນນີ້ບໍ່? ຂໍ້ມູນຂອງທ່ານທີ່ມີຢູ່ກ່ອນແລ້ວຈະຍັງຄົງຢູ່ຄືເກົ່າ. ແອັບພລິເຄຊັນທີ່ຜ່ານການອັບເດດຈະສາມາດເຂົ້າເຖິງ:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ທ່ານຕ້ອງການທີ່ຈະຕິດຕັ້ງຊຸດອັບເດດສຳລັບແອັບຯນີ້ບໍ່? ຂໍ້ມູນທີ່ທ່ານມີຢູ່ຈະບໍ່ສູນຫາຍ. ການອັບເດດແອັບພລິເຄຊັນນີ້ຈະສາມາດເຂົ້າເຖິງ:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ທ່ານຕ້ອງການຕິດຕັ້ງອັບເດດໃສ່ແອັບພລິເຄຊັນນີ້ບໍ່? ຂໍ້ມູນຂອງທ່ານທີ່ມີຢູ່ກ່ອນແລ້ວຈະຍັງຄົງຢູ່ຄືເກົ່າ. ມັນບໍ່ຕ້ອງການສິດເຂົ້າເຖິງພິເສດໃດໆ."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ທ່ານຕ້ອງການຕິດຕັ້ງອັບເດດໃສ່ແອັບພລິເຄຊັນທີ່ມີມານຳນີ້ບໍ່? ຂໍ້ມູນຂອງທ່ານທີ່ມີຢູ່ກ່ອນແລ້ວຈະຍັງຄົງຢູ່ຄືເກົ່າ. ມັນບໍ່ຕ້ອງການສິດເຂົ້າເຖິງພິເສດໃດໆເລີຍ."</string>
-    <string name="install_failed" msgid="6579998651498970899">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບຯເທື່ອ."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ແພັກ​ເກດ​ຖືກບ​ລັອກ​ບໍ່​ໃຫ້​ໄດ້​ຮັບ​ການ​ຕິດ​ຕັ້ງ"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"App not installed as package conflicts with an existing package."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App not installed as app isn\'t compatible with your tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ແອັບ​ນີ້​ບໍ່​ເຂົ້າ​ກັນ​ໄດ້​ກັບໂທລະພາບຂອງ​ທ່ານ."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App not installed as app isn\'t compatible with your phone."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"App not installed as package appears to be invalid."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"ບໍ່ສາມາດຕິດຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ໃສ່ແທັບເລັດຂອງທ່ານໄດ້."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່​ສາ​ມາດ​ຕິດ​ຕັ້ງ​ໃສ່ໂທລະພາບຂອງ​ທ່ານ​ໄດ້."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"ບໍ່​ສາ​ມາດ​ຕິດ​ຕັ້ງ​ <xliff:g id="APP_NAME">%1$s</xliff:g> ໃນໂທລະສັບຂອງທ່ານໄດ້."</string>
-    <string name="launch" msgid="4826921505917605463">"ເປີດ"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ຕິດຕັ້ງແອັບທີ່ໄດ້ມາຈາກແຫຼ່ງທີ່ບໍ່ຮູ້ຈັກ"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ຜູ້ໃຊ້ນີ້ບໍ່ສາມາດຕິດຕັ້ງແອັບທີ່ບໍ່ຮູ້ຈັກໄດ້"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ຜູ້ໃຊ້ນີ້ບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ຕິດຕັ້ງແອັບໄດ້"</string>
-    <string name="ok" msgid="3468756155452870475">"ຕົກລົງ"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"ຈັດການແອັບຯ"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ພື້ນທີ່ຫວ່າງບໍ່ພຽງພໍ"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"ບໍ່ສາມາດຕິດຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ໄດ້. ກະລຸນາລຶບຂໍ້ມູນທີ່ບໍ່ຈຳເປັນອອກ ເພື່ອໃຫ້ມີບ່ອນຈັດເກັບຂໍ້ມູນຫວ່າງເພີ່ມຂຶ້ນ ແລ້ວລອງໃໝ່ອີກຄັ້ງ."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ບໍ່ພົບເຫັນແອັບຯ"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ບໍ່ພົບແອັບຯໃນລາຍການຂອງແອັບຯທີ່ຕິດຕັ້ງແລ້ວ."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ບໍ່ອະນຸຍາດແລ້ວ"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ຜູ້ໃຊ້ປັດຈຸບັນບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ຖອນການຕິດຕັ້ງນີ້ໄດ້."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"ຜິດພາດ"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ບໍ່ສາມາດຖອນການຕິດຕັ້ງແອັບໄດ້."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ຖອນ​ການ​ຕິດ​ຕັ້ງແອັບຯ"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"ຖອນ​ການ​ຕິດ​ຕັ້ງ​ອັບເດດ"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ແມ່ນ​ສ່ວນ​ນຶ່ງ​ຂອງແອັບຯຂ້າງລຸ່ມ:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"ທ່ານຕ້ອງການຖອນການຕິດຕັ້ງແອັບຯນີ້ບໍ່?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ທ່ານຕ້ອງການທີ່ຈະຖອນການຕິດຕັ້ງແອັບຯນີ້ ສຳລັງຜູ່ໃຊ້"<b>"ທຸກຄົນ"</b>"ບໍ່? ແອັບພລິເຄຊັນ ແລະຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກ ຈາກຜູ່ໃຊ້"<b>"ທັງໝົດ"</b>"ໃນອຸປະກອນນີ້."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"ທ່ານ​ຕ້ອງ​ການ​ຖອນ​ການ​ຕິດ​ຕັ້ງ​ແອັບຯ​ນີ້​ສຳ​ລັບ​ຜູ່​ໃຊ້ <xliff:g id="USERNAME">%1$s</xliff:g> ບໍ່?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ແທນທີ່ແອັບນີ້ດ້ວຍເວີຊັນທີ່ມາຈາກໂຮງງານບໍ? ຂໍ້ມູນທັງໝົດຈະຖືກລຶບອອກ."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ແທນທີ່ແອັບນີ້ດ້ວຍເວີຊັນທີ່ມາຈາກໂຮງງານບໍ? ຂໍ້ມູນທັງໝົດຈະຖືກລຶບອອກ ເຊິ່ງມີຜົນກັບຜູ້ໃຊ້ອຸປະກອນນີ້ທຸກຄົນ ຮວມທັງຄົນທີ່ມີໂປຣໄຟລ໌ບ່ອນເຮັດວຽກນຳ."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ກຳລັງຖອນການຕິດຕັ້ງ"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ຖອນການຕິດຕັ້ງບໍ່ສຳເລັດ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"ກຳລັງຖອນການຕິດຕັ້ງ..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"ກຳລັງຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"ຖອນການຕິດຕັ້ງສຳເລັດແລ້ວ."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"ຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ແລ້ວ"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"ການຖອນການຕິດຕັ້ງບໍ່ສຳເລັດ."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"ຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ບໍ່ສຳເລັດ."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ບໍ່ສາມາດຖອນການຕິດຕັ້ງແອັບອຸປະກອນທີ່ເຮັດວຽກຢູ່ໄດ້"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"ບໍ່ສາມາດຖອນການຕິດຕັ້ງແອັບຜູ້ເບິ່ງແຍງລະບົບທີ່ເຮັດວຽກຢູ່ສຳລັບ <xliff:g id="USERNAME">%1$s</xliff:g> ໄດ້"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ແອັບນີ້ຈຳເປັນສຳລັບບາງຜູ້ໃຊ້ ຫຼື ບາງໂປຣໄຟລ໌ ແລະ ຖືກຖອນການຕິດຕັ້ງສຳລັບຄົນອື່ນແລ້ວ"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ແອັບນີ້ຈຳເປັນຕ້ອງໃຊ້ກັບໂປຣໄຟລ໌ຂອງທ່ານ ແລະ ບໍ່ສາມາດຖອນການຕິດຕັ້ງໄດ້."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"​ແອັບຯ​ນີ້​ຕ້ອງ​ໃຊ້​ໂດຍ​ຜູ່​ເບິ່ງ​ແຍງ​ລະ​ບົບ​ຂອງ​ທ່ານ ແລະ​ບໍ່​ສາ​ມາດ​ຖອນ​ການ​ຕິດ​ຕັ້ງ​ໄດ້."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"ຈັດການແອັບຜູ້ເບິ່ງແຍງອຸປະກອນ"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ຈັດການຜູ້ໃຊ້"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່ສາມາດຖອນອອກໄດ້."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ເກີດບັນຫາໃນການວິເຄາະແພັກເກດ."</string>
-    <string name="newPerms" msgid="6039428254474104210">"ໃໝ່"</string>
-    <string name="allPerms" msgid="1024385515840703981">"ທັງໝົດ"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"ຄວາມ​ເປັນ​ສ່ວນ​ຕົວ"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ການເຂົ້າເຖິງອຸປະກອນ"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ອັບເດດນີ້ບໍ່ຕ້ອງການການອະນຸຍາດໃໝ່."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ປະຕິເສດ"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ຂໍ້ມູນເພີ່ມເຕີມ"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ຢືນຢັນປະຕິເສດ"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ໃນ <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"ອະນຸຍາດໃຫ້ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ສາມາດ <xliff:g id="ACTION">%2$s</xliff:g> ບໍ?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"ອະນຸຍາດ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ໃຫ້ໃຊ້ <xliff:g id="ACTION">%2$s</xliff:g> ໄດ້ທຸກເທື່ອບໍ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ໃນເວລາໃຊ້ແອັບເທົ່ານັ້ນ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ທຸກເທື່ອ"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ປະຕິເສດ ແລະ ຢ່າຖາມອີກ"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"ປິດໄວ້ <xliff:g id="COUNT">%1$d</xliff:g> ສິດອະນຸຍາດແລ້ວ"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"ປິດໄວ້ທັງໝົດແລ້ວ"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ບໍ່ມີອັນໃດປິດການນຳໃຊ້ໄວ້"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ອະນຸຍາດ"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ແອັບ"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ການ​ອະ​ນຸ​ຍາດ​ແອັບ"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"ບໍ່ຕ້ອງຖາມອີກ"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"​ບໍ່​ມີການ​ອະ​ນຸ​ຍາດ​"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"ການ​ອະ​ນຸ​ຍາດ​​ເພີ່ມ​ເຕີມ"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ເປີດຂໍ້ມູນແອັບ"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ເພີ່ມ​ເຕີມ</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ເພີ່ມ​ເຕີມ</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ແອັບ​ນີ້​ຖືກ​ອອກ​ແບບ​ມາ​ສຳ​ລັບ Android ເວີ​ຊັນ​ເກົ່າ. ການ​ປະ​ຕິ​ເສດ​ການ​ອະ​ນຸ​ຍາດ​ອາດ​ຈະ​ເຮັດ​ໃຫ້​ມັນ​ບໍ່​ເຮັດ​ວຽກ​ຕາມ​ຕ້ອງ​ການ​ໄດ້​ອີກ."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ເຮັດ​ການ​ດຳ​ເນີນ​ການ​ທີ່​ບໍ່​ຮູ້​ຈັກ"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> ໃນ <xliff:g id="COUNT_1">%2$d</xliff:g> ແອັບ​ໄດ້​ຮັບ​ອະ​ນຸ​ຍາດ​ແລ້ວ"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"ສະແດງລະບົບ"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"ເຊື່ອງ​ລະ​ບົບ"</string>
-    <string name="no_apps" msgid="1965493419005012569">"ບໍ່ມີແອັບ"</string>
-    <string name="location_settings" msgid="1774875730854491297">"ການຕັ້ງຄ່າ​ທີ່​ຕັ້ງ"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ແມ່ນ​ຜູ້​ໃຫ້​ບໍ​ລິ​ການ​ເລື່ອງ​ການ​ບໍ​ລິ​ການ​ທີ່​ຕັ້ງ​ສຳ​ລັບ​ອຸ​ປະ​ກອນ​ນີ້. ການ​ເຂົ້າ​ເຖິງ​ທີ່​ຕັ້ງ​ແມ່ນ​ສາ​ມາດ​ດັດ​ແປງ​ໄດ້​ຈາກ​ການ​ຕັ້ງ​ຄ່າ​ທີ່​ຕັ້ງ."</string>
-    <string name="system_warning" msgid="7103819124542305179">"ຖ້າ​ທ່ານ​ປະ​ຕິ​ເສດ​ການ​ອະ​ນຸ​ຍາດ​ນີ້, ຄຸນສົມບັດໃຊ້ງານ​ພື້ນ​ຖານ​ຂອງ​ອຸ​ປະ​ກອນ​ຂອງ​ທ່ານ​ອາດ​ຈະ​ບໍ່​ເຮັດ​ໜ້າ​ທີ່​ຕາມທີ່ກຳນົດໄວ້."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ບັງ​ຄັບ​ໃຊ້​ຕາມ​ນະ​ໂຍ​ບາຍ​ແລ້ວ"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ປິດນຳໃຊ້ການເຂົ້າເຖິງໃນພື້ນຫຼັງຕາມນະໂຍບາຍແລ້ວ"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ເປີດນຳໃຊ້ການເຂົ້າເຖິງໃນພື້ນຫຼັງຕາມນະໂຍບາຍແລ້ວ"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ເປີດນຳໃຊ້ການເຂົ້າເຖິງໃນພື້ນໜ້າຕາມນະໂຍບາຍແລ້ວ"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ຄວບຄຸມໂດຍຜູ້ເບິ່ງແຍງລະບົບ"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ທຸກເທື່ອ"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"ໃນເວລາໃຊ້ແອັບເທົ່ານັ້ນ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ບໍ່ເລີຍ"</string>
-    <string name="loading" msgid="7811651799620593731">"ກຳລັງ​ໂຫລດ..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"ທຸກ​ການ​ອະ​ນຸ​ຍາດ"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"ຄວາມ​​ສາ​ມາດ​​ອື່ນຂອງແອັບ"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"ການຮ້ອງຂໍການອະນຸຍາດ"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"ກວດ​ພົບ​ການ​ວາງ​ຊ້ອນ​ໜ້າ​ຈໍ​ແລ້ວ"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ເພື່ອ​ປ່ຽນ​ແປງ​ການ​ຕັ້ງ​ຄ່າ​ການ​ອະ​ນຸ​ຍາດ​ນີ້, ກ່ອນ​ອື່ນ​ໝົດ​ທ່ານ​ຕ້ອງ​ປິດ​ການ​ວາງ​ຊ້ອນ​ໜ້າ​ຈໍ​ຈາກ​ແອັບ​ການ​ຕັ້ງ​ຄ່າ"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ເປີດການຕັ້ງຄ່າ"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ຕິດຕັ້ງ/ຖອນຕິດຕັ້ງ ຄຳສັ່ງທີ່ບໍ່ຮອງຮັບຢູ່ໃນ Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"ເລືອກວ່າຈະອະນຸຍາດໃຫ້ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ເຂົ້າເຖິງຫຍັງໄດ້ແດ່"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"ອັບເດດ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ແລ້ວ. ກະລຸນາເລືອກວ່າຈະໃຫ້ແອັບນີ້ເຂົ້າເຖິງຫຍັງໄດ້ແດ່."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"​ຍົກ​ເລີກ"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"​ສືບ​ຕໍ່"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"ການ​ອະ​ນຸ​ຍາດ​ໃໝ່"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"ການ​ອະນຸຍາດ​ປັດຈຸ​ບັນ"</string>
-    <string name="message_staging" msgid="6151794817691100003">"ກຳລັງຮຽງແອັບ…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"ບໍ່ຮູ້ຈັກ"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ແທັບເລັດຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ໂທລະທັດຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ໂທລະສັບຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ໂທລະສັບ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ແທັບເລັດ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ໂທລະທັດ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ດຳເນີນການຕໍ່"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ການຕັ້ງຄ່າ"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"ກຳລັງຕິດຕັ້ງ/ຖອດຖອນແອັບ Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"ຕົວຕິດຕັ້ງແພັກເກດ"</string>
+    <string name="install" msgid="711829760615509273">"ຕິດຕັ້ງ"</string>
+    <string name="done" msgid="6632441120016885253">"ແລ້ວໆ"</string>
+    <string name="cancel" msgid="1018267193425558088">"ຍົກເລີກ"</string>
+    <string name="installing" msgid="4921993079741206516">"ກຳລັງຕິດຕັ້ງ…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"ກຳລັງຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"ຕິດຕັ້ງແອັບແລ້ວ."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"ທ່ານ​ຕ້ອງ​ການ​ຕິດ​ຕັ້ງ​ແອັບພລິເຄຊັນນີ້​ບໍ່?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"ທ່ານຕ້ອງການຕິດຕັ້ງອັບເດດຫາແອັບພລິເຄຊັນທີ່ມີຢູ່ກ່ອນແລ້ວນີ້ບໍ່? ຂໍ້ມູນເກົ່າຂອງທ່ານຈະບໍ່ເສຍໄປໃສ."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"ທ່ານຕ້ອງການຕິດຕັ້ງອັບເດດໃສ່ແອັບພລິເຄຊັນແບບມີມາໃນຕົວນີ້ບໍ່? ຂໍ້ມູນເກົ່າຂອງທ່ານຈະບໍ່ເສຍໄປໃສ."</string>
+    <string name="install_failed" msgid="5777824004474125469">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເທື່ອ."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"ແພັກ​ເກດ​ຖືກບ​ລັອກ​ບໍ່​ໃຫ້​ໄດ້​ຮັບ​ການ​ຕິດ​ຕັ້ງ."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເນື່ອງຈາກແພັກເກດຂັດແຍ່ງກັບແພັກເກດທີ່ມີຢູ່ກ່ອນແລ້ວ."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເນື່ອງຈາກແອັບບໍ່ສາມາດໃຊ້ຮ່ວມກັບແທັບເລັດຂອງທ່ານໄດ້."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"ແອັບນີ້ໃຊ້ຮ່ວມກັບໂທລະທັດຂອງທ່ານບໍ່ໄດ້."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເນື່ອງຈາກແອັບບໍ່ສາມາດໃຊ້ຮ່ວມກັບໂທລະສັບຂອງທ່ານໄດ້."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"ບໍ່ໄດ້ຕິດຕັ້ງແອັບເນື່ອງຈາກແພັກເກດບໍ່ຖືກຕ້ອງ."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"ບໍ່ສາມາດຕິດຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ຢູ່ແທັບເລັດຂອງທ່ານໄດ້."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"ຜູ້ໃຊ້ນີ້ບໍ່ສາມາດຕິດຕັ້ງແອັບທີ່ບໍ່ຮູ້ຈັກໄດ້"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ຜູ້ໃຊ້ນີ້ບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ຕິດຕັ້ງແອັບໄດ້"</string>
+    <string name="ok" msgid="7871959885003339302">"ຕົກລົງ"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"ຈັດການແອັບ"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"ພື້ນທີ່ຫວ່າງບໍ່ພຽງພໍ"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"ບໍ່ສາມາດຕິດຕັ້ງ <xliff:g id="APP_NAME">%1$s</xliff:g> ໄດ້. ກະລຸນາລຶບຂໍ້ມູນທີ່ບໍ່ຈຳເປັນອອກເພື່ອໃຫ້ມີບ່ອນຈັດເກັບຂໍ້ມູນຫວ່າງເພີ່ມຂຶ້ນ ແລ້ວລອງໃໝ່ອີກຄັ້ງ."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"ບໍ່ພົບແອັບ"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ບໍ່ພົບແອັບໃນລາຍການຂອງແອັບທີ່ຕິດຕັ້ງແລ້ວ."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"ບໍ່ອະນຸຍາດແລ້ວ"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"ຜູ້ໃຊ້ປັດຈຸບັນບໍ່ໄດ້ຮັບອະນຸຍາດໃຫ້ຖອນການຕິດຕັ້ງນີ້ໄດ້."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"ຜິດພາດ"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"ບໍ່ສາມາດຖອນການຕິດຕັ້ງແອັບໄດ້."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"ຖອນຕິດຕັ້ງແອັບ"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"ຖອນການຕິດຕັ້ງອັບເດດ"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ແມ່ນ​ສ່ວນ​ໜຶ່ງຂອງແອັບຕໍ່ໄປນີ້:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"ທ່ານຕ້ອງການຖອນການຕິດຕັ້ງແອັບນີ້ບໍ່?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"ທ່ານຕ້ອງການທີ່ຈະຖອນການຕິດຕັ້ງແອັບນີ້ສຳລັງຜູ້ໃຊ້"<b>"ທຸກຄົນ"</b>"ບໍ່? ແອັບພລິເຄຊັນ ແລະ ຂໍ້ມູນຂອງມັນຈະຖືກລຶບອອກຈາກຜູ້ໃຊ້"<b>"ທັງໝົດ"</b>"ໃນອຸປະກອນນີ້."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"ທ່ານ​ຕ້ອງ​ການ​ຖອນ​ການ​ຕິດ​ຕັ້ງ​ແອັບ​ນີ້​ສຳ​ລັບ​ຜູ້​ໃຊ້ <xliff:g id="USERNAME">%1$s</xliff:g> ບໍ່?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ແທນທີ່ແອັບນີ້ດ້ວຍເວີຊັນທີ່ມາຈາກໂຮງງານບໍ? ຂໍ້ມູນທັງໝົດຈະຖືກລຶບອອກ."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ແທນທີ່ແອັບນີ້ດ້ວຍເວີຊັນທີ່ມາຈາກໂຮງງານບໍ? ຂໍ້ມູນທັງໝົດຈະຖືກລຶບອອກ ເຊິ່ງມີຜົນກັບຜູ້ໃຊ້ອຸປະກອນນີ້ທຸກຄົນ ຮວມທັງຄົນທີ່ມີໂປຣໄຟລ໌ບ່ອນເຮັດວຽກນຳ."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"ກຳລັງຖອນການຕິດຕັ້ງ"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"ຖອນການຕິດຕັ້ງບໍ່ສຳເລັດ"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"ກຳລັງຖອນການຕິດຕັ້ງ..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"ກຳລັງຖອນການຕິດຕັ້ງ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"ຖອນການຕິດຕັ້ງສຳເລັດແລ້ວ."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"ຕິດຕັ້ງ/ຖອນການຕິດຕັ້ງ ຄຳສັ່ງທີ່ບໍ່ຮອງຮັບຢູ່ Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"ກຳລັງຮຽງແອັບ…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"ບໍ່ຮູ້ຈັກ"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ແທັບເລັດຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ໂທລະທັດຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"ເພື່ອຄວາມປອດໄພຂອງທ່ານ, ໂທລະສັບຂອງທ່ານບໍ່ສາມາດຕິດຕັ້ງແອັບຈາກແຫລ່ງຂໍ້ມູນນີ້ໄດ້."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"ໂທລະສັບ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"ແທັບເລັດ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ໂທລະທັດ ແລະ ຂໍ້ມູນສ່ວນຕົວຂອງທ່ານອາດຖືກໂຈມຕີໄດ້ໂດຍແອັບທີ່ບໍ່ຮູ້ຈັກ. ໂດຍການຕິດຕັ້ງແອັບນີ້, ແມ່ນທ່ານຍອມຮັບວ່າທ່ານຈະຮັບຜິດຊອບຕໍ່ຄວາມເສຍຫາຍໃດໆກໍຕາມທີ່ເກີດຂຶ້ນຕໍ່ໂທລະທັດຂອງທ່ານ ຫຼື ການສູນເສຍຂໍ້ມູນທີ່ອາດເກີດຈາກການນຳໃຊ້ມັນ."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"ສືບຕໍ່"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"ການຕັ້ງຄ່າ"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"ການຕິດຕັ້ງ/ຖອນການຕິດຕັ້ງແອັບ Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-lt/strings.xml b/packages/PackageInstaller/res/values-lt/strings.xml
index 79546a9..73b0bff 100644
--- a/packages/PackageInstaller/res/values-lt/strings.xml
+++ b/packages/PackageInstaller/res/values-lt/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"Paketo įdiegimo programa"</string>
-    <string name="next" msgid="3057143178373252333">"Kitas"</string>
-    <string name="install" msgid="5896438203900042068">"Įdiegti"</string>
-    <string name="done" msgid="3889387558374211719">"Atlikta"</string>
-    <string name="cancel" msgid="8360346460165114585">"Atšaukti"</string>
-    <string name="installing" msgid="8613631001631998372">"Diegiama..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Įdiegiama „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Programa įdiegta."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Ar norite įdiegti šią programą? Jai bus suteikta prieiga prie:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ar norite įdiegti šią programą? Jai nereikalinga jokia speciali prieiga."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Ar norite įdiegti šios esamos programos naujinį? Neprarasite esamų duomenų. Atnaujinus programą bus suteikta prieiga prie:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ar norite įdiegti šios integruotos programos naujinį? Neprarasite esamų duomenų. Atnaujinus programą bus suteikta prieiga prie:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ar norite įdiegti šios esamos programos naujinį? Neprarasite esamų duomenų. Nereikia jokios specialios prieigos."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ar norite įdiegti šios integruotos programos naujinį? Neprarasite esamų duomenų. Nereikia jokios specialios prieigos."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Programa neįdiegta."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Paketas užblokuotas ir negali būti įdiegtas."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Programa neįdiegta, nes paketas nesuderinamas su esamu paketu."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Programa neįdiegta, nes ji nesuderinama su planšetiniu kompiuteriu."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ši programa nesuderinama su jūsų TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Programa neįdiegta, nes ji nesuderinama su telefonu."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Programa neįdiegta, nes panašu, kad paketas netinkamas."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Jūsų planšetiniame kompiuteryje nepavyko įdiegti „<xliff:g id="APP_NAME">%1$s</xliff:g>“."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nepavyko programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ įdiegti jūsų TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Jūsų telefone nepavyko įdiegti „<xliff:g id="APP_NAME">%1$s</xliff:g>“."</string>
-    <string name="launch" msgid="4826921505917605463">"Atidaryti"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Jūsų administratorius neleidžia diegti programų, gautų iš nežinomų šaltinių"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Šis naudotojas negali diegti nežinomų programų"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Šiam naudotojui neleidžiama diegti programų"</string>
-    <string name="ok" msgid="3468756155452870475">"Gerai"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Tvarkyti programas"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nėra vietos"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Nepavyko įdiegti „<xliff:g id="APP_NAME">%1$s</xliff:g>“. Atlaisvinkite vietos ir bandykite dar kartą."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Programa nerasta"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Programa nerasta įdiegtų programų sąraše."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Neleidžiama"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Dabartiniam naudotojui neleidžiama atlikti šio pašalinimo veiksmo."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Klaida"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Nepavyko įdiegti programos."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Pašalinti programą"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Pašalinti naujinį"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"„<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>“ yra šios programos dalis:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Ar norite pašalinti šią programą?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ar norite pašalinti šią programą "<b>"visiems"</b>" naudotojams? Programa ir jos duomenys bus pašalinti iš "<b>"visų"</b>" naudotojų įrenginyje."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ar norite pašalinti šią naudotojo <xliff:g id="USERNAME">%1$s</xliff:g> programą?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Pakeisti šios programos versiją į gamyklinę? Visi duomenys bus pašalinti."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Pakeisti šios programos versiją į gamyklinę? Visi duomenys bus pašalinti. Tai paveiks visus šio įrenginio naudotojus, įskaitant turinčius darbo profilius."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Vykdomi įdiegimai"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Nepavykę įdiegimai"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Pašalinama..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Pašalinama „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Pašalinimas baigtas."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Paketas „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ pašalintas"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Nepavyko pašalinti."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"„<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ pašalinimo veiksmas nesėkmingas."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Negalima pašalinti aktyvios įrenginio administravimo programos"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Negalima pašalinti aktyvios naudotojo <xliff:g id="USERNAME">%1$s</xliff:g> įrenginio administravimo programos"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ši programa reikalinga kai kuriems naudotojams ar kai kuriuose profiliuose ir buvo pašalinta kitur"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ši programa reikalinga jūsų profilyje ir jos negalima pašalinti."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ši programa reikalinga jūsų įrenginio administratoriui ir jos negalima pašalinti."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Tvarkyti įrenginio administravimo programas"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Valdyti naudotojus"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Nepavyko pašalinti „<xliff:g id="APP_NAME">%1$s</xliff:g>“."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Analizuojant paketą iškilo problema."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Naujiena"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Visi"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privatumas"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Prieiga prie įreng."</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Šiam naujiniui nereikalingi nauji leidimai."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Atmesti"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Daugiau informacijos"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Vis tiek atmesti"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> iš <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Leisti programai &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Visada leisti programai &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Tik naudojant programą"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Visada"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Atmesti ir daugiau neklausti"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Išjungta leidimų: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"visi leidimai išjungti"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"nė vienas leidimas neišjungtas"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Leisti"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Programos"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Programos leidimai"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Daugiau neklausti"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Nėra jokių leidimų"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Papildomi leidimai"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Atidaryti programos informaciją"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Dar <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="few">Dar <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="many">Dar <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Dar <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ši programa skirta senesnės versijos „Android“. Uždraudus leidimą ji gali nebeveikti kaip numatyta."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"atlieka nežinomą veiksmą"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Leidžiama programų: <xliff:g id="COUNT_0">%1$d</xliff:g> iš <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Rodyti sistemą"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Slėpti sistemą"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nėra jokių programų"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Vietovės nustatymai"</string>
-    <string name="location_warning" msgid="8778701356292735971">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ yra šio įrenginio vietovės paslaugų teikėjas. Vietovės pasiekiamumą galima keisti vietovės nustatymuose."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Jei uždrausite šį leidimą, pagrindinės įrenginio funkcijos gali nebeveikti, kaip numatyta."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Reikalaujama pagal politikos nuostatas"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Prieiga fone išjungta pagal politiką"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Prieiga fone įgalinta pagal politiką"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Prieiga priekiniame plane įgalinta pagal politiką"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Valdo administratorius"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Visada"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Tik naudojant programą"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Niekada"</string>
-    <string name="loading" msgid="7811651799620593731">"Įkeliama..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Visi leidimai"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Kitos programos galimybės"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Leidimo užklausa"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Aptikta ekrano perdanga"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Jei norite pakeisti šį leidimo nustatymą, pirmiausia turite išjungti ekrano perdangą skiltyje „Nustatymai &gt; Programos“"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Atidaryti nustatymus"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Diegimo / pašalinimo veiksmai nepalaikomi sistemoje „Wear“."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Pasirinkite, ką norite leisti programai &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; pasiekti"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Programa &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; buvo atnaujinta. Pasirinkite, ką norite leisti šiai programai pasiekti."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Atšaukti"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Tęsti"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nauji leidimai"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Dabartiniai leidimai"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Programa pateikiama etapais…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Nežinoma"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Saugos sumetimais planšetiniame kompiuteryje neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Saugos sumetimais TV neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Saugos sumetimais telefone neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonas ir asmeniniai duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą telefonui arba prarastus duomenis dėl šios programos naudojimo."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Planšetinis kompiuteris ir asmeniniai duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą planšetiniam kompiuteriui arba prarastus duomenis dėl šios programos naudojimo."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV ir asmeniniai duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą TV arba prarastus duomenis dėl šios programos naudojimo."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Tęsti"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Nustatymai"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Įdiegiamos / pašalinamos „Wear“ program."</string>
+    <string name="app_name" msgid="7488448184431507488">"Paketo diegimo programa"</string>
+    <string name="install" msgid="711829760615509273">"Įdiegti"</string>
+    <string name="done" msgid="6632441120016885253">"Atlikta"</string>
+    <string name="cancel" msgid="1018267193425558088">"Atšaukti"</string>
+    <string name="installing" msgid="4921993079741206516">"Įdiegiama…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Įdiegiamas paketas „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Programa įdiegta."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Ar norite įdiegti šią programą?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Ar norite įdiegti šios esamos programos naujinį? Esamų duomenų neprarasite."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Ar norite įdiegti šios įtaisytos programos naujinį? Esamų duomenų neprarasite."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Programa neįdiegta."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paketas užblokuotas ir negali būti įdiegtas."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Programa neįdiegta, nes paketas nesuderinamas su esamu paketu."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Programa neįdiegta, nes ji nesuderinama su planšetiniu kompiuteriu."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ši programa nesuderinama su televizoriumi."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Programa neįdiegta, nes ji nesuderinama su telefonu."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Programa neįdiegta, nes panašu, kad paketas netinkamas."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Nepavyko įdiegti programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ planšetiniame kompiuteryje."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Nepavyko įdiegti programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ televizoriuje."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Nepavyko įdiegti programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ telefone."</string>
+    <string name="launch" msgid="3952550563999890101">"Atidaryti"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Jūsų administratorius neleidžia diegti programų, gautų iš nežinomų šaltinių"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Šis naudotojas negali diegti nežinomų programų"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Šiam naudotojui neleidžiama diegti programų"</string>
+    <string name="ok" msgid="7871959885003339302">"Gerai"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Tvark. progr."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nėra vietos"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Nepavyko įdiegti programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“. Atlaisvinkite vietos ir bandykite dar kartą."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Programa nerasta"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Programa nerasta įdiegtų programų sąraše."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Neleidžiama"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Dabartiniam naudotojui neleidžiama atlikti šio pašalinimo veiksmo."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Klaida"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Nepavyko įdiegti programos."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Pašalinti programą"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Pašalinti naujinį"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"Veikla „<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>“ yra toliau nurodytos programos dalis."</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Ar norite pašalinti šią programą?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Ar norite pašalinti šią programą "<b>"visiems"</b>" naudotojams? Programa ir jos duomenys bus pašalinti "<b>"visiems"</b>" įrenginio naudotojams."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Ar norite pašalinti šią naudotojo <xliff:g id="USERNAME">%1$s</xliff:g> programą?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Pakeisti šios programos versiją į gamyklinę? Visi duomenys bus pašalinti."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Pakeisti šios programos versiją į gamyklinę? Visi duomenys bus pašalinti. Tai paveiks visus šio įrenginio naudotojus, įskaitant turinčius darbo profilius."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Vykdomi pašalinimai"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Nepavykę pašalinimai"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Pašalinama…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Pašalinamas paketas „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Pašalinimas baigtas."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Paketas „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ pašalintas"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Nepavyko pašalinti."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Paketo „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ pašalinimo veiksmas nesėkmingas."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Negalima pašalinti aktyvios įrenginio administravimo programos"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Negalima pašalinti aktyvios naudotojo <xliff:g id="USERNAME">%1$s</xliff:g> įrenginio administravimo programos"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ši programa reikalinga kai kuriems naudotojams ar kai kuriuose profiliuose ir buvo pašalinta kitiems naudotojams"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ši programa reikalinga jūsų profilyje ir jos negalima pašalinti."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ši programa reikalinga jūsų įrenginio administratoriui ir jos negalima pašalinti."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Tvarkyti įrenginio administravimo programas"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Tvarkyti naudotojus"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Nepavyko pašalinti „<xliff:g id="APP_NAME">%1$s</xliff:g>“."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Analizuojant paketą kilo problema."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Diegimo / pašalinimo veiksmai nepalaikomi sistemoje „Wear“."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Programa pateikiama etapais…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Nežinoma"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Saugos sumetimais planšetiniame kompiuteryje neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Saugos sumetimais televizoriuje neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Saugos sumetimais telefone neleidžiama diegti nežinomų programų iš šio šaltinio."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonas ir asmens duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą telefonui arba prarastus duomenis dėl šios programos naudojimo."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Planšetinis kompiuteris ir asmens duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą planšetiniam kompiuteriui arba prarastus duomenis dėl šios programos naudojimo."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV ir asmens duomenys labiau pažeidžiami įdiegus nežinomų programų. Įdiegdami šią programą sutinkate, kad patys esate atsakingi už žalą TV arba prarastus duomenis dėl šios programos naudojimo."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Tęsti"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Nustatymai"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Įdiegiamos / pašalinamos „Wear“ program."</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-lv/strings.xml b/packages/PackageInstaller/res/values-lv/strings.xml
index 40ddf74..d51a0aa 100644
--- a/packages/PackageInstaller/res/values-lv/strings.xml
+++ b/packages/PackageInstaller/res/values-lv/strings.xml
@@ -16,142 +16,76 @@
 
 <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="2738748390251381682">"Pakotnes instalēšanas programma"</string>
-    <string name="next" msgid="3057143178373252333">"Tālāk"</string>
-    <string name="install" msgid="5896438203900042068">"Instalēt"</string>
-    <string name="done" msgid="3889387558374211719">"Gatavs"</string>
-    <string name="cancel" msgid="8360346460165114585">"Atcelt"</string>
-    <string name="installing" msgid="8613631001631998372">"Notiek instalēšana..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Notiek pakotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> instalēšana…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Lietotne ir instalēta."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Vai vēlaties instalēt šo lietojumprogrammu? Tā iegūs piekļuvi:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vai vēlaties instalēt šo lietojumprogrammu? Tai nav nepieciešamas īpašas piekļuves atļaujas."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Vai vēlaties instalēt šīs lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti. Atjauninātajai lietojumprogrammai būs piekļuve:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vai vēlaties instalēt šīs iebūvētās lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti. Atjauninātajai lietojumprogrammai būs piekļuve:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vai vēlaties instalēt šīs lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti. Tam nav nepieciešama īpaša piekļuves atļauja."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vai vēlaties instalēt šīs iebūvētās lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti. Tam nav nepieciešama īpaša piekļuves atļauja."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Lietotne nav instalēta."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Pakotnes instalēšana tika bloķēta."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Lietotne netika instalēta, jo rodas pakotnes konflikts ar esošo pakotni."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Lietotne netika instalēta, jo tā nav saderīga ar jūsu planšetdatoru."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Šī lietotne nav saderīga ar jūsu televizoru."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Lietotne netika instalēta, jo tā nav saderīga ar jūsu tālruni."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Lietotne netika instalēta, jo šķiet, ka pakotne nav derīga."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt planšetdatorā."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt jūsu televizorā."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt tālrunī."</string>
-    <string name="launch" msgid="4826921505917605463">"Atvērt"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Jūsu administrators neļauj instalēt lietotnes, kas iegūtas no nezināmiem avotiem."</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Šis lietotājs nevar instalēt lietotnes, kas iegūtas no nezināmiem avotiem."</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Šim lietotājam nav atļauts instalēt lietotnes"</string>
-    <string name="ok" msgid="3468756155452870475">"Labi"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Pārvaldīt lietotnes"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nav brīvas vietas"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt. Atbrīvojiet vietu un mēģiniet vēlreiz."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Lietotne nav atrasta"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Šī lietotne netika atrasta instalēto lietotņu sarakstā."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nav atļauts"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Pašreizējam lietotājam nav atļauts veikt atinstalēšanu."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Kļūda"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Nevarēja atinstalēt lietotni."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Atinstalēt lietotni"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Atinstalēt atjauninājumu"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ir daļa no šādas lietotnes:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Vai vēlaties atinstalēt šo lietotni?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vai vēlaties atinstalēt šo lietotni "<b>"visiem"</b>" lietotājiem? Šī lietojumprogramma un tās dati tiks noņemti no "<b>"visiem"</b>" ierīces lietotāju kontiem."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Vai vēlaties atinstalēt šo lietotni lietotājam <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Vai aizstāt šo lietotni ar rūpnīcas versiju? Visi dati tiks noņemti."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vai aizstāt šo lietotni ar rūpnīcas versiju? Visi dati tiks noņemti. Tas ietekmēs visu šīs ierīces lietotāju (arī to lietotāju, kuriem ir darba profili) datus."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Pašlaik veiktie atinstalēšanas gadījumi"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neizdevušies atinstalēšanas gadījumi"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Notiek atinstalēšana..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Notiek lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Atinstalēšana ir pabeigta."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Lietotne <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ir atinstalēta"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Atinstalēšana neizdevās."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana nebija sekmīga."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Neizdevās atinstalēt aktīvas ierīces administratora lietotnes."</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Neizdevās atinstalēt aktīvas ierīces administratora lietotni <xliff:g id="USERNAME">%1$s</xliff:g>."</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Šī lietotne ir nepieciešama dažiem lietotājiem vai profiliem un tika atinstalēta citiem"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Šī lietotne ir nepieciešama jūsu profilam, tāpēc to nevar atinstalēt."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ierīces administrators ir noteicis, ka lietotne ir obligāta un to nevar atinstalēt."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Pārvaldīt ierīces administratora lietotnes"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Pārvaldīt lietotājus"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja atinstalēt."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Parsējot pakotni, radās problēma."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Jauna!"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Visas"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Konfidencialitāte"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Piekļuve ierīcei"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Šim atjauninājumam nav nepieciešamas jaunas atļaujas."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Neatļaut"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Plašāka informācija"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tomēr noraidīt"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>. no <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Vai atļaut lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vai vienmēr atļaut lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Tikai izmantojot lietotni"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Vienmēr"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Noraidīt un vairs nejautāt"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> atspējotas"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"visas atspējotas"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"neviena nav atspējota"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Atļaut"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Lietotnes"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Lietotnes atļaujas"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Turpmāk vairs nejautāt"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Nav atļauju"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Papildu atļaujas"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Atvērt lietotnes informāciju"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="zero">Vēl <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Vēl <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Vēl <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Šī lietotne ir paredzēta vecākai Android versijai. Ja noraidīsiet atļauju, iespējams, netiks nodrošināta paredzētā lietotnes darbība."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"veikt nezināmu darbību"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Atļautas <xliff:g id="COUNT_0">%1$d</xliff:g> lietotnes no <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Rādīt sistēmas lietotnes"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Slēpt sistēmas lietotnes"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nav lietotņu"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Atrašanās vietas iestatījumi"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> nodrošina šai ierīcei atrašanās vietu pakalpojumus. Piekļuves iestatījumus atrašanās vietas datiem var mainīt atrašanās vietas iestatījumos."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ja nepiešķirsiet šo atļauju, ierīces pamatfunkcijas, iespējams, vairs nedarbosies, kā paredzēts."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Īstenota saskaņā ar politiku"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Piekļuve fonā atspējota saskaņā ar politiku"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Piekļuve fonā iespējota saskaņā ar politiku"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Piekļuve priekšplānā iespējota saskaņā ar politiku"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolē administrators"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Vienmēr"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Tikai izmantojot lietotni"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nekad"</string>
-    <string name="loading" msgid="7811651799620593731">"Notiek ielāde..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Visas atļaujas"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Citas lietotnes atļaujas"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Atļaujas pieprasījums"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Konstatēts ekrāna pārklājums"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Lai mainītu šo atļaujas iestatījumu, vispirms sadaļā “Iestatījumi un lietotnes” izslēdziet ekrāna pārklājumu."</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Atvērt iestatījumus"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ierīcē netiek atbalstīta instalēšana/atinstalēšana"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Izvēlieties, kādas piekļuves atļaujas piešķirt lietotnei &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Lietotne &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ir atjaunināta. Izvēlieties, kādas piekļuves atļaujas tai piešķirt."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Atcelt"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Turpināt"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Jaunas atļaujas"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Pašreizējās atļaujas"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Lietotne tiek izstādīta…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Nezināms"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Drošības nolūkos jūsu planšetdatorā nedrīkst instalēt no šī avota iegūtas nezināmas lietotnes."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Drošības nolūkos jūsu televizorā nedrīkst instalēt no šī avota iegūtas nezināmas lietotnes."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Drošības nolūkos jūsu tālrunī nedrīkst instalēt no šī avota iegūtas nezināmas lietotnes."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Jūsu tālruņa un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par tālruņa bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Jūsu planšetdatora un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par planšetdatora bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Jūsu televizora un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par televizora bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Turpināt"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Iestatījumi"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear lietotņu instalēšana/atinstalēšana"</string>
+    <string name="app_name" msgid="7488448184431507488">"Pakotnes instalēš. progr."</string>
+    <string name="install" msgid="711829760615509273">"Instalēt"</string>
+    <string name="done" msgid="6632441120016885253">"Gatavs"</string>
+    <string name="cancel" msgid="1018267193425558088">"Atcelt"</string>
+    <string name="installing" msgid="4921993079741206516">"Notiek instalēšana…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Notiek pakotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> instalēšana…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Lietotne ir instalēta."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Vai vēlaties instalēt šo lietojumprogrammu?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Vai vēlaties instalēt šīs lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Vai vēlaties instalēt šīs iebūvētās lietojumprogrammas atjauninājumu? Esošie dati netiks zaudēti."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Lietotne nav instalēta."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Pakotnes instalēšana tika bloķēta."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Lietotne netika instalēta, jo pastāv pakotnes konflikts ar esošu pakotni."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Lietotne netika instalēta, jo tā nav saderīga ar jūsu planšetdatoru."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Šī lietotne nav saderīga ar jūsu televizoru."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Lietotne netika instalēta, jo tā nav saderīga ar jūsu tālruni."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Lietotne netika instalēta, jo šķiet, ka pakotne nav derīga."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt jūsu planšetdatorā."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt jūsu televizorā."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt jūsu tālrunī."</string>
+    <string name="launch" msgid="3952550563999890101">"Atvērt"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Jūsu administrators neļauj instalēt lietotnes, kas iegūtas no nezināmiem avotiem."</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Šis lietotājs nevar instalēt nezināmas lietotnes"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Šim lietotājam nav atļauts instalēt lietotnes"</string>
+    <string name="ok" msgid="7871959885003339302">"Labi"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Pārv. lietotnes"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nav brīvas vietas"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja instalēt. Atbrīvojiet vietu un mēģiniet vēlreiz."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Lietotne netika atrasta"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Šī lietotne netika atrasta instalēto lietotņu sarakstā."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nav atļauts"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Pašreizējam lietotājam nav atļauts veikt šādu atinstalēšanu."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Kļūda"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Nevarēja atinstalēt lietotni."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Atinstalēt lietotni"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Atinstalēt atjauninājumu"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ir daļa no šādas lietotnes:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Vai vēlaties atinstalēt šo lietotni?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Vai vēlaties atinstalēt šo lietotni "<b>"visiem"</b>" lietotājiem? Šī lietojumprogramma un tās dati tiks noņemti no "<b>"visiem"</b>" ierīces lietotāju kontiem."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Vai vēlaties atinstalēt šo lietotni lietotājam <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Vai aizstāt šo lietotni ar rūpnīcas versiju? Visi dati tiks noņemti."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vai aizstāt šo lietotni ar rūpnīcas versiju? Visi dati tiks noņemti. Tas ietekmēs visu šīs ierīces lietotāju datus, pat ja viņiem ir darba profili."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Pašreizējās atinstalēšanas operācijas"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Nesekmīgi atinstalēšanas mēģinājumi"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Notiek atinstalēšana…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Notiek lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Atinstalēšana ir pabeigta."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Lietotne <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ir atinstalēta"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Atinstalēšana neizdevās."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Lietotnes <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> atinstalēšana nebija sekmīga."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Nevar atinstalēt aktīvas ierīces administratora lietotnes."</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Neizdevās atinstalēt aktīvo ierīces administratora lietotni lietotājam <xliff:g id="USERNAME">%1$s</xliff:g>."</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Šī lietotne ir nepieciešama dažiem lietotājiem vai profiliem, un pārējiem tā tika atinstalēta"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Šī lietotne ir nepieciešama jūsu profilam, tāpēc to nevar atinstalēt."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ierīces administrators ir noteicis, ka lietotne ir obligāta un to nevar atinstalēt."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Pārvaldīt ierīces administratora lietotnes"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Pārvaldīt lietotājus"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Lietotni <xliff:g id="APP_NAME">%1$s</xliff:g> nevarēja atinstalēt."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Parsējot pakotni, radās problēma."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Operētājsistēmā Wear netiek atbalstīta instalēšana/atinstalēšana."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Lietotne tiek izstādīta…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Nezināma"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Drošības nolūkos jūsu planšetdatorā ir aizliegts instalēt no šī avota iegūtas nezināmas lietotnes."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Drošības nolūkos jūsu televizorā ir aizliegts instalēt no šī avota iegūtas nezināmas lietotnes."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Drošības nolūkos jūsu tālrunī ir aizliegts instalēt no šī avota iegūtas nezināmas lietotnes."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Jūsu tālrunis un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par tālruņa bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Jūsu planšetdators un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par planšetdatora bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Jūsu televizors un personas dati ir neaizsargātāki pret uzbrukumiem no nezināmām lietotnēm. Instalējot šo lietotni, jūs piekrītat, ka esat atbildīgs par televizora bojājumiem vai datu zudumu, kas var rasties lietotnes dēļ."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Tālāk"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Iestatījumi"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear lietotņu instalēšana/atinstalēšana"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
index 8cf208e..4dd948b 100644
--- a/packages/PackageInstaller/res/values-mk/strings.xml
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Инсталатор на пакет"</string>
-    <string name="next" msgid="3057143178373252333">"Следно"</string>
-    <string name="install" msgid="5896438203900042068">"Инсталирај"</string>
-    <string name="done" msgid="3889387558374211719">"Готово"</string>
-    <string name="cancel" msgid="8360346460165114585">"Откажи"</string>
-    <string name="installing" msgid="8613631001631998372">"Се инсталира..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Се инсталира <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Апликацијата е инсталирана."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Дали сакате да ја инсталирате оваа апликација? Ќе добие пристап до:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Дали сакате да ја инсталирате оваа апликација? Не бара никаков посебен пристап."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Дали сакате да инсталирате надградба на оваа постоечка апликација? Вашите постоечки податоци нема да се изгубат. Ажурираната апликација ќе добие пристап до:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Дали сакате да инсталирате надградба на оваа вградена апликација? Вашите постоечки податоци нема да се изгубат. Ажурираната апликација ќе добие пристап до:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Дали сакате да инсталирате надградба на оваа постоечка апликација? Вашите постоечки податоци нема да се изгубат. Таа не бара никаков посебен пристап."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Дали сакате да инсталирате надградба на оваа вградена апликација? Вашите постоечки податоци нема да се изгубат. Таа не бара никаков посебен пристап."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Апликацијата не е инсталирана."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Инсталирањето на пакетот е блокирано."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Апликација што не е инсталирана како пакет е во конфликт со постоен пакет."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Апликација што не е инсталирана како апликација не е компатибилна со вашиот таблет."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Оваа апликација не е компатибилна со вашиот телевизор."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Апликација што не е инсталирана како апликација не е компатибилна со вашиот телефон."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Апликација што не е инсталирана како пакет се чини дека е неважечка."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можеше да се инсталира на вашиот таблет."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> не може да се инсталира на вашиот телевизор."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можеше да се инсталира на вашиот телефон."</string>
-    <string name="launch" msgid="4826921505917605463">"Отвори"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Вашиот администратор не дозволува инсталација на апликации добиени од непознати извори"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Корисников не може да инсталира непознати апликации"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"На корисников не му е дозволено да инсталира апликации"</string>
-    <string name="ok" msgid="3468756155452870475">"Во ред"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Управувај со апликации"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Нема простор"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можеше да се инсталира. Ослободете простор и обидете се повторно."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Апликацијата не е пронајдена"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Апликацијата не е пронајдена во списокот инсталирани апликации."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Не е дозволено"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Тековниот корисник нема дозвола да ја изведе деинсталацијава."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Грешка"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Не можеше да се деинсталира апликацијата."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Деинсталирај апликација"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Деинсталирај ажурирање"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> е дел од следната апликација:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Дали сакате да ја деинсталирате оваа апликација?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Дали сакате да ја деинсталирате оваа апликација за "<b>"сите"</b>" корисници? Апликацијата и нејзините податоци ќе се отстранат од "<b>"сите"</b>" корисници на уредот."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Дали сакате да ја деинсталирате апликацијава за корисникот <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Сакате да ја замените оваа апликација со фабричката верзија? Сите податоци ќе се отстранат."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Сакате да ја замените оваа апликација со фабричката верзија? Сите податоци ќе се отстранат. Тоа важи за сите корисници на овој уред, вклучувајќи ги и тие со работни профили."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Деинсталации во тек"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Неуспешни деинсталации"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Се деинсталира..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Се деинсталира <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Деинсталирањето заврши."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> е деинсталиран"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Деинсталирањето е неуспешно."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Деинсталирањето на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> е неуспешно."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Не може да се деинсталира активна апликација на администраторот на уредот"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Не може да се деинсталира активна апликација на администраторот на уредот за <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Апликацијата е неопходна за некои корисници или профили, а за другите е деинсталирана"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Апликацијата е потребна за вашиот профил и не може да се деинсталира."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Апликацијата ја бара администраторот на вашиот уред и не може да се деинсталира."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Управувај со аплик. за администраторот на уредот"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Управувај со корисници"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> не може да се деинсталира."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Настана проблем при разложување на пакетот."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Ново"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Сè"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Приватност"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Пристап кон уредот"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Ова ажурирање не бара нови дозволи."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Одбиј"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Повеќе информации"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Сепак одбиј"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> од <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Дозволете &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Дали секогаш да се дозволи &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; да <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Само додека се користи апликацијата"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Секогаш"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Одбиј и не прашувај повторно"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Оневозможени се <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"сите се оневозможени"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ниедна не е оневозможена"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Овозможи"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Апликации"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Дозволи за апликацијата"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Не прашувај повторно"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Нема дозволи"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Дополнителни дозволи"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Отвора информации за апликација"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Уште <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Уште <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Оваа апликација е дизајнирана за постара верзија на Android. Одбивањето на дозволата може да предизвика веќе да не функционира како што треба."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"изврши непознато дејство"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Дозволени се <xliff:g id="COUNT_0">%1$d</xliff:g> од <xliff:g id="COUNT_1">%2$d</xliff:g> апликации"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Прикажи систем"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Сокриј систем"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Нема апликации"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Поставки за локација"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> е давател на услуги според локација за овој уред. Пристапот до локацијата може да се смени од Поставките за локација."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ако ја одбиете оваа дозвола, основните функции на вашиот уред можеби веќе нема да функционираат како што треба."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Наложено од политиката"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Пристапот од заднина е оневозможен со правилото"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Пристапот од заднина е овозможен со правилото"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Пристапот од преден план е овозможен со правилото"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Контролирано од администраторот"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Секогаш"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Само додека се користи аплик."</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Никогаш"</string>
-    <string name="loading" msgid="7811651799620593731">"Се вчитува..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Сите дозволи"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Други можности на апликацијата"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Барање дозвола"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Откривме преклопување на екранот"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"За да ја измените оваа поставка за дозвола, прво мора да го исклучите преклопувањето на екранот од Поставки &gt; Апликации"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Отвори поставки"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Дејствата инсталирај/деинсталирај не се поддржани на Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Изберете што да ѝ се овозможи на &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; за пристап"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; е ажурирана. Изберете што да ѝ се овозможи на оваа апликација за пристап."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Откажи"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Продолжи"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Нови дозволи"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Тековни дозволи"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Апликацијата се поставува…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Непознато"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"За ваша безбедност, таблетот нема дозвола за инсталирање непознати апликации од изворов."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"За ваша безбедност, телевизорот нема дозвола за инсталирање непознати апликации од изворов."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"За ваша безбедност, телефонот нема дозвола за инсталирање непознати апликации од изворов."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефонот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телефонот или губењето податоци што може да произлезат од нејзиното користење."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Таблетот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на таблетот или губењето податоци што може да произлезат од нејзиното користење."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Телевизорот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телевизорот или губењето податоци што може да произлезат од нејзиното користење."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Продолжи"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Поставки"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Се инсталираат/деинсталираат аплик. Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Инсталатор на пакет"</string>
+    <string name="install" msgid="711829760615509273">"Инсталирај"</string>
+    <string name="done" msgid="6632441120016885253">"Готово"</string>
+    <string name="cancel" msgid="1018267193425558088">"Откажи"</string>
+    <string name="installing" msgid="4921993079741206516">"Се инсталира…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Се инсталира <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Апликацијата е инсталирана."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Дали сакате да ја инсталирате апликацијава?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Дали сакате да инсталирате ажурирање на оваа постоечка апликација? Постоечките податоци нема да се изгубат."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Дали сакате да инсталирате ажурирање на оваа вградена апликација? Постоечките податоци нема да се изгубат."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Апликацијата не е инсталирана."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирањето на пакетот е блокирано."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Апликација што не е инсталирана како пакет е во конфликт со постоечки пакет."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Апликација што не е инсталирана како апликација не е компатибилна со вашиот таблет."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Оваа апликација не е компатибилна со вашиот телевизор."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Апликација што не е инсталирана како апликација не е компатибилна со вашиот телефон."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Апликација што не е инсталирана како пакет се чини дека е неважечка."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можеше да се инсталира на вашиот таблет."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Корисников не може да инсталира непознати апликации"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"На корисников не му е дозволено да инсталира апликации"</string>
+    <string name="ok" msgid="7871959885003339302">"Во ред"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Управување со апликациите"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Нема простор"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> не можеше да се инсталира. Ослободете простор и обидете се повторно."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Апликацијата не е најдена"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Апликацијата не е пронајдена во списокот инсталирани апликации."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Не е дозволено"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Тековниот корисник нема дозвола да ја изведе деинсталацијава."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Грешка"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Не можеше да се деинсталира апликацијата."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Деинсталирај ја апликацијата"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Деинсталирајте ажурирање"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> е дел од следната апликација:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Дали сакате да ја деинсталирате оваа апликација?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Дали сакате да ја деинсталирате оваа апликација за "<b>"сите"</b>" корисници? Апликацијата и нејзините податоци ќе се отстранат од "<b>"сите"</b>" корисници на уредот."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Дали сакате да ја деинсталирате апликацијава за корисникот <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Сакате да ја замените оваа апликација со фабричката верзија? Сите податоци ќе се отстранат."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Сакате да ја замените оваа апликација со фабричката верзија? Сите податоци ќе се отстранат. Тоа важи за сите корисници на овој уред, вклучувајќи ги и тие со работни профили."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Деинсталации во тек"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Неуспешни деинсталации"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Се деинсталира…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Се деинсталира <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Деинсталирањето заврши."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Дејствата „Инсталирај/деинсталирај“ не се поддржани на Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Апликацијата се поставува…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Непозната"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"За ваша безбедност, таблетот нема дозвола за инсталирање непознати апликации од изворов."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"За ваша безбедност, телевизорот нема дозвола за инсталирање непознати апликации од изворов."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"За ваша безбедност, телефонот нема дозвола за инсталирање непознати апликации од изворов."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефонот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телефонот или губењето податоци што може да произлезат од нејзиното користење."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблетот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на таблетот или губењето податоци што може да произлезат од нејзиното користење."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Телевизорот и личните податоци се поподложни на напади од непознати апликации. Ако ја инсталирате апликацијава, се согласувате дека сте одговорни за каква било штета на телевизорот или губењето податоци што може да произлезат од нејзиното користење."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Продолжи"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Поставки"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Се инсталираат/деинсталираат аплик. Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ml/strings.xml b/packages/PackageInstaller/res/values-ml/strings.xml
index 9fadd24..bb0d39c 100644
--- a/packages/PackageInstaller/res/values-ml/strings.xml
+++ b/packages/PackageInstaller/res/values-ml/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"പാക്കേജ് ഇൻസ്‌റ്റാളർ"</string>
-    <string name="next" msgid="3057143178373252333">"അടുത്തത്"</string>
-    <string name="install" msgid="5896438203900042068">"ഇൻസ്റ്റാളുചെയ്യുക"</string>
-    <string name="done" msgid="3889387558374211719">"പൂർത്തിയായി"</string>
-    <string name="cancel" msgid="8360346460165114585">"റദ്ദാക്കുക"</string>
-    <string name="installing" msgid="8613631001631998372">"ഇൻസ്റ്റാൾ ചെയ്യുന്നു..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു…"</string>
-    <string name="install_done" msgid="3682715442154357097">"അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തു."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്യണോ? ഇതിന് ഇവയിലേക്ക് ആക്‌സസ്സ് ലഭിക്കും:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"നിങ്ങൾക്ക് ഈ അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്യണോ? ഇത് പ്രത്യേക ആക്‌സസ്സൊന്നും ആവശ്യമില്ല."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"നിലവിലുള്ള ഈ അപ്ലിക്കേഷന് ഒരു അപ്‌ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യണോ? നിങ്ങളുടെ നിലവിലെ ഡാറ്റ നഷ്‌ടപ്പെടില്ല. അപ്‌ഡേറ്റുചെയ്‌ത അപ്ലിക്കേഷന് ഇവയിലേക്ക് ആക്‌സസ്സ് ലഭിക്കും:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ഈ അന്തർ നിർമ്മിത അപ്ലിക്കേഷന് ഒരു അപ്‌ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യണോ? നിങ്ങളുടെ നിലവിലെ ഡാറ്റ നഷ്‌ടപ്പെടില്ല. അപ്‌ഡേറ്റുചെയ്‌ത അപ്ലിക്കേഷന് ഇവയിലേക്ക് ആക്‌സസ്സ് ലഭിക്കും:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"നിലവിലുള്ള ഈ അപ്ലിക്കേഷന് ഒരു അപ്‌ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യണോ? നിങ്ങളുടെ നിലവിലെ ഡാറ്റ നഷ്‌ടപ്പെടില്ല. ഇതിന് പ്രത്യേക ആക്‌സസ്സൊന്നും ആവശ്യമില്ല."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ഈ അന്തർ നിർമ്മിത അപ്ലിക്കേഷന് ഒരു അപ്‌ഡേറ്റ് ഇൻസ്റ്റാളുചെയ്യണോ? നിങ്ങളുടെ നിലവിലെ ഡാറ്റ നഷ്‌ടപ്പെടില്ല. ഇതിന് പ്രത്യേക ആക്‌സസ്സൊന്നും ആവശ്യമില്ല."</string>
-    <string name="install_failed" msgid="6579998651498970899">"അപ്ലിക്കേഷൻ ഇൻസ്റ്റാളുചെയ്‌തില്ല."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ഇൻസ്റ്റാൾ ചെയ്യുന്നതിൽ നിന്നും പാക്കേജിനെ തടഞ്ഞു."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"നിലവിലുള്ള ഒരു പാക്കേജുമായി പാക്കേജിന് പൊരുത്തക്കേടുള്ളതിനാൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"നിങ്ങളുടെ ടാബ്‌ലെറ്റുമായി അനുയോജ്യത ഇല്ലാത്തതിനാൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"നിങ്ങളുടെ ടിവിയ്‌ക്ക് ഈ ആപ്പ് അനുയോജ്യമല്ല."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"നിങ്ങളുടെ ഫോണുമായി അനുയോജ്യത ഇല്ലാത്തതിനാൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"പാക്കേജ് അസാധുവായി കാണപ്പെടുന്നതിനാൽ ആപ്പ് ഇൻസ്റ്റാൾ ചെയ്തില്ല."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"നിങ്ങളുടെ ടാബ്‌ലെറ്റിൽ <xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്റ്റാളുചെയ്യാനായില്ല."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>, നിങ്ങളുടെ ടിവിയിൽ ഇൻസ്റ്റാളുചെയ്യാനായില്ല."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"നിങ്ങളുടെ ഫോണിൽ <xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്റ്റാളുചെയ്യാനായില്ല."</string>
-    <string name="launch" msgid="4826921505917605463">"തുറക്കുക"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"അജ്ഞാത ഉറവിടങ്ങളിൽ നിന്ന് സ്വന്തമാക്കിയ ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യാൻ നിങ്ങളുടെ അഡ്‌മിനിസ്‌ട്രേറ്റർ അനുവദിക്കുന്നില്ല"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ഈ ഉപയോക്താവിന്, തിരിച്ചറിയാനാകാത്ത ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയില്ല"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യുന്നതിന് ഈ ഉപയോക്താവിന് അനുവാദമില്ല"</string>
-    <string name="ok" msgid="3468756155452870475">"ശരി"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"അപ്ലിക്കേഷനുകൾ നിയന്ത്രിക്കുക"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"പരിധി കഴിഞ്ഞു"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്റ്റാളുചെയ്യാനായില്ല. കുറച്ച് ഇടം ശൂന്യമാക്കിയതിനുശേഷം വീണ്ടും ശ്രമിക്കുക."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"അപ്ലിക്കേഷൻ കണ്ടെത്തിയില്ല"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ഇൻസ്റ്റാളുചെയ്‌ത അപ്ലിക്കേഷനുകളുടെ ലിസ്റ്റിൽ അപ്ലിക്കേഷൻ കണ്ടെത്തിയില്ല."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"അനുവദിച്ചിട്ടില്ല"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ഈ അൺഇൻസ്റ്റലേഷൻ നിർവഹിക്കാൻ നിലവിലെ ഉപയോക്താവിനെ അനുവദിച്ചിട്ടില്ല."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"പിശക്"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ആപ്പ് അൺഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിഞ്ഞില്ല."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"അപ്ലിക്കേഷൻ അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"അപ്‌ഡേറ്റ് അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> എന്നത് ഇനിപ്പറയുന്ന അപ്ലിക്കേഷന്റെ ഭാഗമാണ്:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"ഈ അപ്ലിക്കേഷൻ അൺഇൻസ്റ്റാളുചെയ്യണോ?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ഈ അപ്ലിക്കേഷൻ "<b>"എല്ലാ"</b>" ഉപയോക്താക്കൾക്കുമായി അൺഇൻസ്റ്റാളുചെയ്യണോ? ഉപകരണത്തിലെ "<b>"എല്ലാ"</b>" ഉപയോക്താക്കളിൽ നിന്നും അപ്ലിക്കേഷനും അതിന്റെ ഡാറ്റയും നീക്കംചെയ്യപ്പെടും."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിനായി ഈ അപ്ലിക്കേഷൻ അൺഇൻസ്റ്റാളുചെയ്യണോ?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ഫാക്ടറി പതിപ്പ് ഉപയോഗിച്ച് ഈ ആപ്പ് മാറ്റിസ്ഥാപിക്കണോ? എല്ലാ ഡാറ്റയും നീക്കംചെയ്യപ്പെടും."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ഫാക്ടറി പതിപ്പ് ഉപയോഗിച്ച് ഈ ആപ്പ് മാറ്റിസ്ഥാപിക്കണോ? എല്ലാ ഡാറ്റയും നീക്കംചെയ്യപ്പെടും. ഔദ്യോഗിക പ്രൊഫൈലുകൾ ഉള്ളവർ ഉൾപ്പെടെ, ഈ ഉപകരണത്തിന്റെ എല്ലാ ഉപയോക്താക്കളെയും ഇത് ബാധിക്കുന്നു."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"അൺ ഇൻസ്‌റ്റാൾ ചെയ്‌തുകൊണ്ടിരിക്കുന്നവ"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"അൺ ഇൻസ്‌റ്റാൾ ചെയ്യാൻ കഴിയാഞ്ഞവ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"അൺഇൻസ്‌‌റ്റാൾ ചെയ്യുന്നു..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺഇൻസ്റ്റാൾ ചെയ്യുന്നു…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"അൺഇൻസ്റ്റാളുചെയ്യൽ പൂർത്തിയായി."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺഇൻസ്‌റ്റാൾ ചെയ്‌തു"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"അൺഇൻസ്റ്റാളുചെയ്തു."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺഇൻസ്റ്റാൾ ചെയ്യൽ പരാജയം."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"സജീവ ഉപകരണ അഡ്‌മിൻ ആപ്പ് അൺഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയില്ല"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിന്റെ സജീവ ഉപകരണ അഡ്‌മിൻ ആപ്പ് അൺഇൻസ്റ്റാൾ ചെയ്യാൻ കഴിയില്ല"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ചില ഉപയോക്താക്കൾക്കോ പ്രൊഫൈലുകൾക്കോ ഈ ആപ്പ് ആവശ്യമാണ്, മറ്റുള്ളവർക്ക് ഈ ആപ്പ് അൺഇൻസ്റ്റാൾ ചെയ്തിരിക്കുന്നു"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"നിങ്ങളുടെ ഔദ്യോഗിക പ്രൊഫൈലിന് ഈ ആപ്പ് ആവശ്യമുള്ളതിനാൽ അത് അൺ‌ഇൻസ്റ്റാൾ ചെയ്യാനാവില്ല."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"നിങ്ങളുടെ ഉപകരണ അഡ്മിനിസ്ട്രേറ്ററിന് ഈ അപ്ലിക്കേഷൻ ആവശ്യമുള്ളതിനാൽ ഇത് അൺഇൻസ്റ്റാൾ ചെയ്യാനാവില്ല."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"ഉപകരണ അഡ്‌മിൻ ആപ്പുകളെ മാനേജുചെയ്യുക"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ഉപയോക്താക്കളെ മാനേജുചെയ്യുക"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> അൺഇൻസ്റ്റാളുചെയ്യാനായില്ല."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"പാക്കേജ് പാഴ്‌സുചെയ്യുന്നതിൽ ഒരു പ്രശ്‌നമുണ്ടായിരുന്നു."</string>
-    <string name="newPerms" msgid="6039428254474104210">"പുതിയത്"</string>
-    <string name="allPerms" msgid="1024385515840703981">"എല്ലാം"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"സ്വകാര്യത"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ഉപകരണ ആക്‌സസ്സ്"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ഈ അപ്‌ഡേറ്റിന് പുതിയ അനുമതികളൊന്നും ആവശ്യമില്ല."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"നിരസിക്കുക"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"കൂടുതൽ‍ വിവരങ്ങള്‍"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"എന്തായാലും നിരസിക്കുക"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"<xliff:g id="ACTION">%2$s</xliff:g> &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ആപ്പിനെ അനുവദിക്കണോ?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; എന്നതിനെ എല്ലായ്‌പ്പോഴും <xliff:g id="ACTION">%2$s</xliff:g> എന്നതിന് അനുവദിക്കണമോ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ആപ്പ് ഉപയോഗിക്കുമ്പോൾ മാത്രം"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"എല്ലായ്‌പ്പോഴും"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"നിരസിക്കുക, വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> പ്രവർത്തനരഹിതമാക്കി"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"എല്ലാം പ്രവർത്തനരഹിതമാക്കി"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ഒന്നും പ്രവർത്തനരഹിതമാക്കിയിട്ടില്ല"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"അനുവദിക്കുക"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ആപ്സ്"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ആപ്പ് അനുമതികൾ"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"വീണ്ടും ആവശ്യപ്പെടരുത്"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"അനുമതികൾ ഇല്ല"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"അധിക അനുമതികൾ"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ആപ്പ് വിവരം തുറക്കുക"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> എണ്ണം കൂടി</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> എണ്ണം കൂടി</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ഈ ആപ്പ് Android-ന്റെ പഴയ പതിപ്പിനായാണ് രൂപകൽപ്പന ചെയ്‌തിരിക്കുന്നത്. അനുമതി നിരസിക്കുന്നത് തുടർന്ന് ഉദ്ദേശിച്ചവിധം പ്രവർത്തിക്കാതിരിക്കാനിടയാക്കുന്നു."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ഒരു അജ്ഞാതപ്രവർത്തനം നടത്തുക"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="COUNT_1">%2$d</xliff:g> ആപ്പുകൾ അനുവദനീയം"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"സിസ്റ്റം കാണിക്കുക"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"സിസ്റ്റം മറയ്‌ക്കുക"</string>
-    <string name="no_apps" msgid="1965493419005012569">"ആപ്സ് ഒന്നുമില്ല"</string>
-    <string name="location_settings" msgid="1774875730854491297">"ലൊക്കേഷൻ ക്രമീകരണം"</string>
-    <string name="location_warning" msgid="8778701356292735971">"ഈ ഉപകരണത്തിനായുള്ള ലൊക്കേഷൻ സേവനങ്ങളുടെ ദാതാവ് <xliff:g id="APP_NAME">%1$s</xliff:g> ആണ്. ലൊക്കേഷൻ ക്രമീകരണത്തിൽ നിന്ന് ലൊക്കേഷൻ ആക്സസ് പരിഷ്കരിക്കാവുന്നതാണ്."</string>
-    <string name="system_warning" msgid="7103819124542305179">"നിങ്ങൾ ഈ അനുമതി നിഷേധിക്കുന്നുവെങ്കിൽ, നിങ്ങളുടെ ഉപകരണത്തിന്റെ അടിസ്ഥാന ഫീച്ചറുകൾ ഉദ്ദേശിച്ചത് പോലെ തുടർന്ന് പ്രവർത്തിച്ചേക്കില്ല."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"നയം മുഖേനെ നടപ്പിലാക്കിയത്"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"നയം അനുസരിച്ച് ബാക്ക്‌ഗ്രൗണ്ട് ആക്‌സസ് പ്രവർത്തനരഹിതമാക്കി"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"നയം അനുസരിച്ച് ബാക്ക്‌ഗ്രൗണ്ട് ആക്‌സസ് പ്രവർത്തനക്ഷമമാക്കി"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"നയം അനുസരിച്ച് ഫോർഗ്രൗണ്ട് ആക്‌സസ് പ്രവർത്തനക്ഷമമാക്കി"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"അഡ്‌മിൻ നിയന്ത്രിക്കുന്നത്"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"എല്ലായ്‌പ്പോഴും"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"ആപ്പ് ഉപയോഗിക്കുമ്പോൾ മാത്രം"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ഒരിക്കലും"</string>
-    <string name="loading" msgid="7811651799620593731">"ലോഡുചെയ്യുന്നു..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"എല്ലാ അനുമതികളും"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"മറ്റ് ആപ്പ് ശേഷികൾ"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"അനുമതി അഭ്യർത്ഥന"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"സ്ക്രീൻ ഓവർലേ കണ്ടെത്തി"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ഈ അനുമതി ക്രമീകരണം മാറ്റുന്നതിന്, ക്രമീകരണം &gt; ആപ്സ് എന്നതിൽ നിന്ന് നിങ്ങളാദ്യം സ്ക്രീൻ ഓവർലേ ഓഫാക്കേണ്ടതാണ്"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ക്രമീകരണം തുറക്കുക"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ഇൻസ്റ്റാളോ അൺഇൻസ്റ്റാളോ ചെയ്യുന്നതിന് Wear-ൽ പിന്തുണയില്ല"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"എന്തൊക്കെ ആക്സസ്സ് ചെയ്യാനാണ് &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ആപ്പിനെ അനുവദിക്കേണ്ടതെന്ന് തിരഞ്ഞെടുക്കുക"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; അപ്‌ഡേറ്റ് ചെയ്തിരിക്കുന്നു. എന്തൊക്കെ ആക്സസ്സ് ചെയ്യാനാണ് ഈ ആപ്പിനെ അനുവദിക്കേണ്ടതെന്ന് തിരഞ്ഞെടുക്കുക."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"റദ്ദാക്കുക"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"തുടരുക"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"പുതിയ അനുമതികൾ"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"നിലവിലെ അനുമതികൾ"</string>
-    <string name="message_staging" msgid="6151794817691100003">"ആപ്പ് തയ്യാറാക്കുന്നു…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"അജ്ഞാതം"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"നിങ്ങളുടെ സുരക്ഷയ്ക്ക്, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, തിരിച്ചറിയാനാകാത്ത ആപ്‌സ് ഇൻസ്റ്റാൾ ചെയ്യാൻ നിങ്ങളുടെ ടാബ്‌ലെറ്റ് അനുവദിക്കപ്പെടില്ല."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"നിങ്ങളുടെ സുരക്ഷയ്ക്ക്, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, തിരിച്ചറിയാനാകാത്ത ആപ്‌സ് ഇൻസ്റ്റാൾ ചെയ്യാൻ നിങ്ങളുടെ ടിവി അനുവദിക്കപ്പെടില്ല."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"നിങ്ങളുടെ സുരക്ഷയ്ക്ക്, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, തിരിച്ചറിയാനാകാത്ത ആപ്‌സ് ഇൻസ്റ്റാൾ ചെയ്യാൻ നിങ്ങളുടെ ഫോൺ അനുവദിക്കപ്പെടില്ല."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"തിരിച്ചറിയാനാകാത്ത ആപ്പുകളാൽ നിങ്ങളുടെ ഫോണും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ഫോണിന് സംഭവിച്ചേക്കാവുന്ന എല്ലാ നാശനഷ്‌ടങ്ങൾക്കും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്‌ടങ്ങൾക്കും നിങ്ങൾക്കാണ് ഉത്തരവാദിത്തമെന്ന് നിങ്ങൾ അംഗീകരിക്കുന്നു."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"തിരിച്ചറിയാനാകാത്ത ആപ്പുകളാൽ നിങ്ങളുടെ ടാബ്‌ലെറ്റും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ടാബ്‌ലെറ്റിന് സംഭവിച്ചേക്കാവുന്ന എല്ലാ നാശനഷ്‌ടങ്ങൾക്കും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്‌ടങ്ങൾക്കും നിങ്ങൾക്കാണ് ഉത്തരവാദിത്തമെന്ന് നിങ്ങൾ അംഗീകരിക്കുന്നു."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"തിരിച്ചറിയാനാകാത്ത ആപ്പുകളാൽ നിങ്ങളുടെ ടിവിയും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ടിവിക്ക് സംഭവിച്ചേക്കാവുന്ന എല്ലാ നാശനഷ്‌ടങ്ങൾക്കും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്‌ടങ്ങൾക്കും നിങ്ങൾക്കാണ് ഉത്തരവാദിത്തമെന്ന് നിങ്ങൾ അംഗീകരിക്കുന്നു."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"തുടരുക"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ക്രമീകരണം"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear ആപ്പുകൾ ഇൻസ്‌റ്റാൾ/അൺ ഇൻസ്‌റ്റാൾ ചെയ്യൽ"</string>
+    <string name="app_name" msgid="7488448184431507488">"പാക്കേജ് ഇൻസ്‌റ്റാളർ"</string>
+    <string name="install" msgid="711829760615509273">"ഇൻസ്‌റ്റാൾ‌ ചെയ്യുക"</string>
+    <string name="done" msgid="6632441120016885253">"പൂർത്തിയായി"</string>
+    <string name="cancel" msgid="1018267193425558088">"റദ്ദാക്കുക"</string>
+    <string name="installing" msgid="4921993079741206516">"ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു…"</string>
+    <string name="install_done" msgid="5987363587661783896">"ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തു."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"ഈ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്യണോ?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"നിലവിലുള്ള ഈ ആപ്പിന്റെ അപ്‌ഡേറ്റ് ഇൻസ്‌റ്റാൾ ചെയ്യണോ നിലവിലുള്ള ഡാറ്റ നഷ്‌ടപ്പെടില്ല."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"ഈ അടങ്ങിയ ആപ്പിന് ഒരു അപ്‌ഡേറ്റ് ഇൻസ്‌റ്റാൾ ചെയ്യണോ? നിലവിലുള്ള ഡാറ്റ നഷ്‌ടപ്പെടില്ല."</string>
+    <string name="install_failed" msgid="5777824004474125469">"ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തിട്ടില്ല."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"പാക്കേജ് ഇൻസ്‌റ്റാൾ ചെയ്യുന്നത് ബ്ലോക്ക് ചെയ്‌തു."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"പാക്കേജിന് നിലവിലുള്ള പാക്കേജുമായി പൊരുത്തക്കേടുള്ളതിനാൽ, ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തില്ല."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"ടാബ്‌ലെറ്റിന് അനുയോജ്യമല്ലാത്തതിനാൽ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തില്ല."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"ടിവിയ്‌ക്ക് ഈ ആപ്പ് അനുയോജ്യമല്ല."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"ഫോണിന് അനുയോജ്യമല്ലാത്തതിനാൽ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തില്ല."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"പാക്കേജ് അസാധുവാണെന്ന് തോന്നുന്നതിനാൽ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്‌തില്ല."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"ടാബ്‌ലെറ്റിൽ <xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്‌റ്റാൾ ചെയ്യാനായില്ല."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"ഈ ഉപയോക്താവിന്, അജ്ഞാത ആപ്പുകൾ ഇൻസ്‌റ്റാൾ ചെയ്യാനാവില്ല"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ആപ്പുകൾ ഇൻ‌സ്‌റ്റാൾ ചെയ്യാൻ ഈ ഉപയോക്താവിന് അനുവാദമില്ല"</string>
+    <string name="ok" msgid="7871959885003339302">"ശരി"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"ആപ്പുകൾ മാനേജ് ചെയ്യുക"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"ഇടമില്ല"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഇൻസ്‌റ്റാൾ ചെയ്യാനായില്ല. കുറച്ച് ഇടമുണ്ടാക്കി, വീണ്ടും ശ്രമിക്കുക."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"ആപ്പ് കണ്ടെത്തിയില്ല"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ഇൻസ്‌റ്റാൾ ചെയ്‌ത ആപ്പുകളുടെ ലിസ്‌റ്റിൽ, ആപ്പ് കണ്ടെത്തിയില്ല."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"അനുവദനീയമല്ല"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"നിലവിലെ ഉപയോക്താവ് ഇത് അൺ ഇൻസ്‌റ്റാൾ ചെയ്യുന്നത് അനുവദനീയമല്ല."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"പിശക്"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"ആപ്പ് അൺ ഇൻസ്‌റ്റാൾ ചെയ്യാനായില്ല"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"ആപ്പ് അൺ ഇൻസ്‌റ്റാൾ ചെയ്യുക"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"അപ്‌ഡേറ്റ്, അൺ ഇ‌ൻസ്‌റ്റാൾ ചെയ്യുക"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>, ഇനിപ്പറയുന്ന ആപ്പിന്റെ ഭാഗമാണ് :"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"ഈ ആപ്പ് അൺ ഇൻസ്‌റ്റാൾ ചെയ്യണോ?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"ഈ അപ്പ് "<b>"എല്ലാ"</b>" ഉപയോക്താക്കൾക്കുമായി അൺ ഇൻസ്‌റ്റാൾ ചെയ്യണോ? ഉപകരണത്തിലെ "<b>"എല്ലാ"</b>" ഉപയോക്താക്കളിൽ നിന്നും ആപ്പും അതിന്റെ ഡാറ്റയും നീക്കം ചെയ്യപ്പെടും."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> എന്ന ഉപയോക്താവിനായി ഈ ആപ്പ് അൺ ഇൻസ്‌റ്റാൾ ചെയ്യണോ?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ഫാക്‌ടറി പതിപ്പ് ഉപയോഗിച്ച് ഈ ആപ്പിന് പകരം വയ്ക്കണോ? എല്ലാ ഡാറ്റയും നീക്കം ചെയ്യപ്പെടും."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ഫാക്‌ടറി പതിപ്പ് ഉപയോഗിച്ച് ഈ ആപ്പിന് പകരം വയ്ക്കണോ? എല്ലാ ഡാറ്റയും നീക്കം ചെയ്യപ്പെടും. ഔദ്യോഗിക പ്രൊഫൈലുകൾ ഉള്ളവർ ഉൾപ്പെടെ, ഈ ഉപകരണത്തിന്റെ എല്ലാ ഉപയോക്താക്കളെയും ഇത് ബാധിക്കും."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"നിലവിൽ അൺഇൻസ്‌റ്റാൾ ചെയ്യുന്നവ"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"അൺ ഇൻസ്‌റ്റാൾ ചെയ്യാൻ കഴിയാഞ്ഞവ"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"അണ്‍‌ ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> അൺ ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"അൺ ഇൻസ്‌റ്റാൾ ചെയ്യൽ പൂർത്തിയായി."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"ഇൻസ്‌റ്റാൾ/അൺഇൻസ്‌റ്റാൾ ചെയ്യുന്നത് Wear പിന്തുണയ്‌ക്കുന്നില്ല."</string>
+    <string name="message_staging" msgid="8032722385658438567">"ആപ്പ് തയ്യാറാക്കുന്നു…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"അജ്ഞാതം"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"നിങ്ങളുടെ സുരക്ഷയ്ക്കായി, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, അജ്ഞാത ആപ്പുകൾ ഡാബ്‌ലെറ്റിൽ ഇൻസ്‌റ്റാൾ ചെയ്യുന്നത് അനുവദനീയമല്ല."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"നിങ്ങളുടെ സുരക്ഷയ്ക്കായി, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, അജ്ഞാത ആപ്പുകൾ ടിവിയിൽ ഇൻസ്‌റ്റാൾ ചെയ്യുന്നത് അനുവദനീയമല്ല."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"നിങ്ങളുടെ സുരക്ഷയ്ക്കായി, ഈ ഉറവിടത്തിൽ നിന്നുള്ള, അജ്ഞാത ആപ്പുകൾ ഫോണിൽ ഇൻസ്‌റ്റാൾ ചെയ്യുന്നത് അനുവദനീയമല്ല."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"അജ്ഞാതമായ ആപ്പുകളാൽ നിങ്ങളുടെ ഫോണും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ഫോണിന് സംഭവിച്ചേക്കാവുന്ന ഏത് നാശനഷ്‌ടത്തിന്റെയും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്‌ടത്തിന്റെയും ഉത്തരവാദിത്തം നിങ്ങൾക്കായിരിക്കുമെന്ന് അംഗീകരിക്കുന്നു."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"അജ്ഞാതമായ ആപ്പുകളാൽ നിങ്ങളുടെ ടാബ്‌ലെറ്റും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ടാബ്‌ലെറ്റിന് സംഭവിച്ചേക്കാവുന്ന ഏത് നാശനഷ്‌ടത്തിന്റെയും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്‌ടത്തിന്റെയും ഉത്തരവാദിത്തം നിങ്ങൾക്കായിരിക്കുമെന്ന് അംഗീകരിക്കുന്നു."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"അജ്ഞാതമായ ആപ്പുകളാൽ നിങ്ങളുടെ ടിവിയും വ്യക്തിഗത ഡാറ്റയും ആക്രമിക്കപ്പെടാനുള്ള സാധ്യത വളരെ കൂടുതലാണ്. ഈ ആപ്പ് ഇൻസ്‌റ്റാൾ ചെയ്യുന്നതിലൂടെ, ഇത് ഉപയോഗിക്കുന്നതിനാൽ നിങ്ങളുടെ ടിവിക്ക് സംഭവിച്ചേക്കാവുന്ന ഏത് നാശനഷ്‌ടത്തിന്റെയും അല്ലെങ്കിൽ ഡാറ്റാ നഷ്‌ടത്തിന്റെയും ഉത്തരവാദിത്തം നിങ്ങൾക്കായിരിക്കുമെന്ന് അംഗീകരിക്കുന്നു."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"തുടരുക"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"ക്രമീകരണം"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear ആപ്പ് ഇൻസ്‌റ്റാൾ/അൺ ഇൻസ്‌റ്റാൾ ചെയ്യുന്നു"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml
index 1fd12a2..5b93736 100644
--- a/packages/PackageInstaller/res/values-mn/strings.xml
+++ b/packages/PackageInstaller/res/values-mn/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Багц суулгагч"</string>
-    <string name="next" msgid="3057143178373252333">"Дараах"</string>
-    <string name="install" msgid="5896438203900042068">"Суулгах"</string>
-    <string name="done" msgid="3889387558374211719">"Дуусгах"</string>
-    <string name="cancel" msgid="8360346460165114585">"Цуцлах"</string>
-    <string name="installing" msgid="8613631001631998372">"Суулгаж байна…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г суулгаж байна…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Апп суулгагдсан."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Та энэ аппликешныг суулгамаар байна уу? Энэ дараахад хандах болно:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Та энэ аппликешныг суулгах уу? Энэ тусгай хандалт шаардахгүй."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Та энэ аппликейшны шинэчлэлтийг суулгах уу? Таны хуучин дата устах болно. Шинэчлэгдсэн аппликейшн нь дараахад хандаж чадна:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Та энэ үндсэн аппликейшны шинэчлэлтийг суулгах уу? Таны хуучин дата устах болно. Шинэчлэгдсэн аппликейшн нь дараахад хандаж чадна:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Та энэ аппликешны шинэчлэлтийг суулгах уу? Таны хуучин дата устах болно. Энэ ямар нэгэн тусгай эрх шаардахгүй."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Та энэ үндсэн аппликешны шинэчлэлтийг суулгах уу? Таны хуучин дата устах болно. Энэ ямар нэгэн тусгай эрх шаардахгүй."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Апп суулгагдаагүй."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Багц суулгахыг блоклосон байна."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Багц одоогийн багцтай тохирохгүй байгаа тул апп-г суулгаж чадсангүй."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Апп таны таблеттай тохирохгүй байгаа тул үүнийг суулгасангүй."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Энэ апп нь таны ТВ-д нийцэхгүй."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Апп таны утсанд тохирохгүй байгаа тул үүнийг суулгасангүй."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Багц хүчингүй тул апп-г суулгасангүй."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> таны таблет дээр суусангүй."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь таны телевизэд суурилуулах боломжгүй байна."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г таны утсан дээр суулгах боломжгүй."</string>
-    <string name="launch" msgid="4826921505917605463">"Нээх"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Таны админ тодорхойгүй сурвалжаас татсан апп суулгахыг зөвшөөрдөггүй"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Энэ хэрэглэгч тодорхойгүй апп суулгах боломжгүй байна"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Энэ хэрэглэгч апп суулгах зөвшөөрөлгүй байна"</string>
-    <string name="ok" msgid="3468756155452870475">"ОК"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Апп удирдах"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Зай дутагдаж байна"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г суулгаж чадсангүй. Зайг чөлөөлөөд дахин оролдоно уу."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Апп олдсонгүй"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Суулгасан апп-н жагсаалт дотроос апп олдсонгүй."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Зөвшөөрөөгүй"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Одоогийн хэрэглэгч үүнийг устгах боломжгүй."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Алдаа"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Апп-г устгаж чадсангүй."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Апп устгах"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Шинэчлэлийг устгах"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> нь дараах апп-н хэсэг болно:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Та энэ апп-г устгамаар байна уу?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Та энэ апп-г "<b>"бүх"</b>" хэрэглэгчээс устгах уу? Аппикешн болон доторх дата нь төхөөрөмж дээрх "<b>"бүх"</b>" хэрэглэгчээс устгагдах болно."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Та энэ апп-г <xliff:g id="USERNAME">%1$s</xliff:g> хэрэглэгчийн хувьд устгах уу?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Энэ апп-г үйлдвэрээс ирсэн хувилбараар нь солих уу? Бүх өгөгдөл устах болно."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Энэ апп-г үйлдвэрээс ирсэн хувилбараар нь солих уу? Бүх өгөгдөл устах болно. Энэ нь ажлын профайлтай хэрэглэгч зэрэг энэ төхөөрөмжийн бүх хэрэглэгчдэд үйлчлэх болно."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Устгаж байна"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Устгаж чадсангүй"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Устгаж байна…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгаж байна…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Устгаж дуусав."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгасан"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Устгалт амжилтгүй болов."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгаж чадсангүй."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Идэвхтэй төхөөрөмжийн админ аппыг устгах боломжгүй"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>-д идэвхтэй төхөөрөмжийн админ аппыг устгах боломжгүй байна"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Энэ апп нь зарим хэрэглэгч эсвэл профайлд шаардлагатай учир үүнийг тэдгээрээс бусад хэрэглэгчдээс устгасан"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Энэ апп таны профайлд шаардлагатай бөгөөд устгах боломжгүй."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Энэ апп нь таны төхөөрөмжийн админд шаардлагатай бөгөөд устгах боломжгүй."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Төхөөрөмжийн админ аппыг удирдах"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Хэрэгчлэгчдийг удирдах"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г устгаж чадсангүй."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Багцийг задлахад алдаа гарав."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Шинэ"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Бүгд"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Нууцлал"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Төхөөрөмжид хандах"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Энэ шинэчлэл шинэ зөвшөөрөл шаардахгүй."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Татгалзах"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Дэлгэрэнгүй мэдээлэл"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Хэдийд ч татгалзах"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>-ийн <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г <xliff:g id="ACTION">%2$s</xliff:g>-г зөвшөөрөх үү?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г <xliff:g id="ACTION">%2$s</xliff:g>-д байнга зөвшөөрөх үү?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Зөвхөн апп ашиглах үед"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Байнга"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Taтгалзаад дахин бүү асуугаарай"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>-г цуцалсан"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"бүгдийг цуцалсан"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"алийг ч цуцлаагүй"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Зөвшөөрөх"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Апп"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Апп зөвшөөрөл"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Дахиж бүү асуу"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Зөвшөөрөлгүй байна"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Нэмэлт зөвшөөрөл"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Аппын мэдээллийг нээх"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> бусад</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> бусад</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Энэхүү аппыг нь Android-ын хуучин хувилбарт зориулсан. Зөвшөөрлийг үгүйсгэх нь цаашид ажиллахгүй болгож болно."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"Танигдаагүй үйлдлийг гүйцэтгэх"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>-с <xliff:g id="COUNT_0">%1$d</xliff:g> аппыг зөвшөөрдөг"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Системийг харуулах"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Системийг нуух"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Апп байхгүй"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Байршлын тохиргоо"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> нь энэ төхөөрөмжийн байршлын үйлчилгээ үзүүлэгч юм. Байршилд хандалтыг байршлын тохиргоо хэсгээс өөрчилж болно."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Хэрэв та энэ зөвшөөрөлд татгалзсан тохиолдолд таны төхөөрөмжийн үндсэн функц нь алдаатай ажиллаж магадгүй."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Бодлогын дагуу хэрэгжсэн"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Арын дэвсгэрийн хандалтыг удирдамжаас идэвхгүй болгосон"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Арын дэвсгэрийн хандалтыг удирдамжаас идэвхтэй болгосон"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Нүүрний дэвсгэрийн хандалтыг удирдамжаас идэвхтэй болгосон"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Админ удирддаг"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Байнга"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Зөвхөн апп ашиглах үед"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Хэзээ ч үгүй"</string>
-    <string name="loading" msgid="7811651799620593731">"Ачаалж байна..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Бүх зөвшөөрөл"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Бусад апп-ын боломж"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Зөвшөөрлийн хүсэлт"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Дэлгэцийн давхарга илрүүллээ"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Зөвшөөрлийн тохиргоог өөрчлөхийн тулд, эхлээд Тохиргоо ба Апп хэсгээс дэлгэцийн давхаргыг унтраана уу."</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Тохиргоог нээх"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Суулгах/Устгах үйлдлийг Wear дэмжээгүй."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-н хандаж болох зүйлсийг сонгоно уу"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;-г шинэчиллээ. Энэ апп-н хандаж болох зүйлсийг сонгоно уу."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Цуцлах"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Үргэлжлүүлэх"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Шинэ зөвшөөрөл"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Одоогийн зөвшөөрөл"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Апп-г байршуулж байна…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Тодорхойгүй"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Таны аюулгүй байдлыг хангахын тулд таны таблет энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Таны аюулгүй байдлыг хангахын тулд таны ТВ энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Таны аюулгүй байдлыг хангахын тулд таны утас энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Таны утас болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны утсанд гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Таны таблет болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны таблетад гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Таны ТВ болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны ТВ-д гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Үргэлжлүүлэх"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Тохиргоо"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Зүүсгэл аппыг суулгаж/устгаж байна"</string>
+    <string name="app_name" msgid="7488448184431507488">"Багц суулгагч"</string>
+    <string name="install" msgid="711829760615509273">"Суулгах"</string>
+    <string name="done" msgid="6632441120016885253">"Болсон"</string>
+    <string name="cancel" msgid="1018267193425558088">"Болих"</string>
+    <string name="installing" msgid="4921993079741206516">"Суулгаж байна…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г суулгаж байна…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Аппыг суулгасан."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Та энэ аппыг суулгахыг хүсэж байна уу?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Та одоо байгаа аппын шинэчлэлтийг суулгахыг хүсэж байна уу? Таны хуучин өгөгдөл устахгүй."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Та энэ үндсэн аппын шинэчлэлтийг суулгахыг хүсэж байна уу? Таны хуучин өгөгдөл устахгүй."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Аппыг суулгаагүй."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Багц суулгахыг блоклосон байна."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Багц одоо байгаа багцтай тохирохгүй байгаа тул аппыг суулгаж чадсангүй."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Апп таны таблеттай тохирохгүй байгаа тул аппыг суулгасангүй."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Энэ апп нь таны ТВ-д тохирохгүй байна."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Апп таны утсанд тохирохгүй байгаа тул аппыг суулгасангүй."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Багц хүчингүй тул аппыг суулгасангүй."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> таны таблет дээр суулгаж чадсангүй."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Энэ хэрэглэгч тодорхойгүй апп суулгах боломжгүй"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Энэ хэрэглэгч нь апп суулгах зөвшөөрөлгүй байна"</string>
+    <string name="ok" msgid="7871959885003339302">"ОК"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Аппуудыг удирдах"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Орон зай дутагдаж байна"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г суулгаж чадсангүй. Хэсэг зай чөлөөлөөд дахин оролдоно уу."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Апп олдсонгүй"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Суулгасан аппын жагсаалт дотроос апп олдсонгүй."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Зөвшөөрөөгүй"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Одоогийн хэрэглэгч үүнийг устгах боломжгүй."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Алдаа"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Аппыг устгаж чадсангүй."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Апп устгах"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Шинэчлэлтийг устгах"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> нь дараах аппын хэсэг болно:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Та энэ аппыг устгахыг хүсэж байна уу?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Та энэ аппыг "<b>"бүх"</b>" хэрэглэгчээс устгахыг хүсэж байна уу? Апп болон доторх өгөгдлийг төхөөрөмж дээрх "<b>"бүх"</b>" хэрэглэгчээс устгана."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Та энэ аппыг <xliff:g id="USERNAME">%1$s</xliff:g> хэрэглэгчийн өмнөөс устгахыг хүсэж байна уу?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Энэ аппыг үйлдвэрээс ирсэн хувилбараар солих уу? Бүх өгөгдөл устах болно."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Энэ аппыг үйлдвэрээс ирсэн хувилбараар солих уу? Бүх өгөгдөл устах болно. Энэ нь эдгээр ажлын профайлтай бүхий энэ төхөөрөмжийн бүх хэрэглэгчид нөлөөлнө."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Устгаж байна"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Устгаж чадсангүй"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Устгаж байна…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгаж байна…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Устгаж дууслаа."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Андройд Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear-д суулгах/устгах үйлдлийг дэмждэггүй."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Аппыг байршуулж байна…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Тодорхойгүй"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Таны аюулгүй байдлыг хангахын тулд таны таблет энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Таны аюулгүй байдлыг хангахын тулд таны ТВ энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Таны аюулгүй байдлыг хангахын тулд таны утас энэ эх сурвалжаас тодорхойгүй апп суулгахыг зөвшөөрдөггүй."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Таны утас болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны утсанд гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таны таблет болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны таблетад гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Таны ТВ болон хувийн өгөгдөл тодорхойгүй апп суулгасан тохиолдолд гэмтэж болзошгүй. Энэ аппыг суулгаснаар үүнийг ашигласнаас үүдэн таны ТВ-д гэмтэл гарах, эсвэл өгөгдөл устах зэрэг эрсдэлийг хариуцна гэдгээ зөвшөөрч байна."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Үргэлжлүүлэх"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Тохиргоо"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear аппуудыг суулгаж/устгаж байна"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-mr/strings.xml b/packages/PackageInstaller/res/values-mr/strings.xml
index b9acaa5..5bbf7b9c 100644
--- a/packages/PackageInstaller/res/values-mr/strings.xml
+++ b/packages/PackageInstaller/res/values-mr/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"पॅकेज स्‍थापनकर्ता"</string>
-    <string name="next" msgid="3057143178373252333">"पुढील"</string>
-    <string name="install" msgid="5896438203900042068">"स्‍थापित करा"</string>
-    <string name="done" msgid="3889387558374211719">"पूर्ण झाले"</string>
-    <string name="cancel" msgid="8360346460165114585">"रद्द करा"</string>
-    <string name="installing" msgid="8613631001631998372">"इंस्टॉल करत आहे..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> इन्‍स्टॉल करत आहे…"</string>
-    <string name="install_done" msgid="3682715442154357097">"अॅप इंस्टॉल झाला."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"तुम्ही हा अॅप्लिकेशन इंस्टॉल करू इच्छिता? यास यावर प्रवेश मिळेल:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"तुम्ही हा अॅप्लिकेशन इंस्टॉल करू इच्छिता? यास कोणत्याही विशेष प्रवेशाची आवश्यकता नसते."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"तुम्हाला सद्य अॅप्लिकेशनवर अपडेट इंस्टॉल करायची आहे? तुम्ही तुमचा सद्य डेटा गमावणार नाही. अपडेट केलेल्या अॅप्लिकेशनला यावर अॅक्सेस मिळेल:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"तुम्ही या बिल्ट-इन अॅप्लिकेशनवर अपडेट इंस्टॉल करायची आहे? तुम्ही तुमचा सद्य डेटा गमावणार नाही. अपडेट केलेल्या अॅप्लिकेशनला यावर अॅक्सेस मिळेल:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"तुम्हाला सद्य अॅप्लिकेशनवर अपडेट इंस्टॉल करायची आहे? तुम्ही तुमचा सद्य डेटा गमावणार नाही. यासाठी कोणताही विशेष अॅक्सेस आवश्यक नसतो."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"तुम्ही या बिल्ट-इन अॅप्लिकेशनवर अपडेट इंस्टॉल करायची आहे? तुम्ही तुमचा सद्य डेटा गमावणार नाही. यासाठी कोणताही विशेष अॅक्सेस आवश्यक नसतो."</string>
-    <string name="install_failed" msgid="6579998651498970899">"अॅप इंस्टॉल झाला नाही."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"पॅकेेच इंस्टॉल होण्यास अवरोधित केलेले होते."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"पॅकेजचा विद्यमान पॅकेजशी विरोध असल्याने अॅप इंस्टॉल केला नाही."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"अॅप आपल्या टॅब्लेटशी सुसंगत नसल्याने अॅप इंस्टॉल केला नाही."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"हा अॅप आपल्या टीव्हीशी सुसंगत नाही."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"अॅप आपल्या फोनशी सुसंगत नसल्याने अॅप इंस्टॉल केला नाही."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"पॅकेज अवैध असल्याचे दिसत असल्याने अॅप इंस्टॉल केले नाही."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपल्या टॅब्लेटवर इंस्टॉल केला जाऊ शकला नाही."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपल्या टीव्हीवर इंस्टॉल केले जाऊ शकले नाही."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपल्या फोनवर इंस्टॉल केला जाऊ शकला नाही."</string>
-    <string name="launch" msgid="4826921505917605463">"उघडा"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"अज्ञात स्रोतांकडून मिळवलेल्या अॅप्सच्या स्थापनेला आपला प्रशासक अनुमती देत नाही"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"या वापरकर्त्याद्वारे अज्ञात अ‍ॅप्स इंस्टॉल केली जाऊ शकत नाहीत"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"या वापरकर्त्याला अ‍ॅप्स इंस्टॉल करण्याची परवानगी नाही"</string>
-    <string name="ok" msgid="3468756155452870475">"ठीक"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"अ‍ॅप्स व्यवस्थापित करा"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"स्‍थानाबाहेर"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> इंस्टॉल केला जाऊ शकला नाही. काही स्थान मोकळे करा आणि पुन्हा प्रयत्न करा."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"अॅप आढळला नाही"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"इंस्टॉल केलेल्या अॅप्सच्या सूचीमध्ये अॅप आढळला नाही."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"अनुमती नाही"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"हे अनइंस्टॉल करण्याची वर्तमान वापरकर्त्यास अनुमती नाही."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"एरर"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"अॅप अनइंस्टॉल करणे शक्य झाले नाही."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"अॅप अनइंस्टॉल करा"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"अपडेट अनइंस्टॉल करा"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> खालील अॅप चा भाग आहे:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"तुम्ही हा अॅप अनइंस्टॉल करू इच्छिता?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"तुम्ही हा अॅप "<b>"सर्व"</b>" वापरकर्त्यांसाठी अनइंस्टॉल करू इच्छिता? अॅप्लिकेशन आणि त्याचा डेटा डिव्हाइसवरील "<b>"सर्व"</b>" वापरकर्त्यांवरून काढला जाईल."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"तुम्ही <xliff:g id="USERNAME">%1$s</xliff:g> वापरकर्त्यासाठी हा अ‍ॅप विस्‍थापित करु इच्‍छिता?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"फॅक्टरी आवृत्तीसह हा अॅप पुनर्स्थित करायचा? सर्व डेटा काढला जाईल."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"फॅक्टरी आवृत्तीसह हा अॅप पुनर्स्थित करायचा? सर्व डेटा काढला जाईल. हे कार्य प्रोफाईल असलेल्यांसह या डिव्हाइसच्या सर्व वापरकर्त्यांना प्रभावित करते."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"अनइंस्टॉल करणे चालू आहे"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"अनइंस्टॉल करणे अयशस्वी झाले"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"अनइंस्टॉल करत आहे…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करत आहे…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"अनइंस्टॉल करणे समाप्त."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल केले"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"अनइंस्टॉल करणे अयशस्वी."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करणे अयशस्वी झाले."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"अॅक्टिव्हेट डिव्हाइस प्रशासक अ‍ॅप अनइंस्टॉल करू शकत नाही"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> साठी अॅक्टिव्हेट डिव्हाइस प्रशासक अ‍ॅप अनइंस्टॉल करू शकत नाही"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"हा अॅप काही वापरकर्ते किंवा प्रोफाईलसाठी आवश्यक आहे आणि इतरांसाठी अनइंस्टॉल केला होता"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"आपल्या प्रोफाईलसाठी हा अ‍ॅप आवश्यक आहे आणि अनइंस्टॉल केला जाऊ शकत नाही."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"तुमच्या डिव्हाइस प्रशासकास हे अ‍ॅप आवश्यक आहे आणि ते अनइंस्टॉल केले जाऊ शकत नाही."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"डिव्हाइस प्रशासक अ‍ॅप्स व्यवस्थापित करा"</string>
-    <string name="manage_users" msgid="3125018886835668847">"वापरकर्त्यांना व्यवस्‍थापित करा"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> अनइंस्टॉल केला जाऊ शकला नाही."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"पॅकेज चे विश्लेषण करताना समस्या आली."</string>
-    <string name="newPerms" msgid="6039428254474104210">"नवीन"</string>
-    <string name="allPerms" msgid="1024385515840703981">"सर्व"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"गोपनीयता"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"डिव्हाइस अॅक्सेस"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"या अद्यतनास कोणत्याही नवीन परवानग्यांची आवश्यकता नाही."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"नकार द्या"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"अधिक माहिती"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"तरीही नकार द्या"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> पैकी <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला <xliff:g id="ACTION">%2$s</xliff:g> ची अनुमती द्यायची?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला नेहमी <xliff:g id="ACTION">%2$s</xliff:g> ची अनुमती द्यायची का?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"फक्त अॅप वापरत असताना"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"नेहमी"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"नकार द्या आणि पुन्हा विचारू नका"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> अक्षम केल्या"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"सर्व अक्षम केल्या"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"कोणत्याही अक्षम केल्या नाहीत"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"अनुमती द्या"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"अॅप्स"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"अॅप परवानग्या"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"पुन्हा विचारू नका"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"परवानग्या नाहीत"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"अतिरिक्त परवानग्या"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"अॅप माहिती उघडा"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">आणखी <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">आणखी <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"हा अॅप Android च्या जुन्या आवृत्तीसाठी डीझाइन करण्यात आला होता. परवानगी नाकारल्यामुळे तो यापुढे उद्देशाप्रमाणे कार्य करणार नाही."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"अज्ञात क्रिया करा"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> पैकी <xliff:g id="COUNT_0">%1$d</xliff:g> अ‍ॅप्सना अनुमती दिली"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"सिस्टम दर्शवा"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"सिस्‍टीम लपवा"</string>
-    <string name="no_apps" msgid="1965493419005012569">"कोणतेही अॅप्स नाहीत"</string>
-    <string name="location_settings" msgid="1774875730854491297">"स्थान सेटिंग्ज"</string>
-    <string name="location_warning" msgid="8778701356292735971">"या डिव्‍हाइससाठी <xliff:g id="APP_NAME">%1$s</xliff:g> स्थान सेवांचा प्रदाता आहे. स्थान प्रवेश स्थान सेटिंग्ज वरून सुधारित केला जाऊ शकतो."</string>
-    <string name="system_warning" msgid="7103819124542305179">"तुम्ही ही परवानगी नाकारल्यास, आपल्‍या डिव्‍हाइसची मुलभूत वैशिष्ट्ये अपेक्षित असल्याप्रमाणे कदाचित कार्य करू शकणार नाहीत."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"धोरणाद्वारे सक्ती केली"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"धोरणाद्वारे बॅकग्राउंड अॅक्सेस बंद केला आहे"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"धोरणाद्वारे बॅकग्राउंड अॅक्सेस सुरू केला आहे"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"धोरणाद्वारे फोरग्राउंड अॅक्सेस सुरू केला आहे"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"प्रशासनाद्वारे नियंत्रित केलेले"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"नेहमी"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"फक्त अॅप वापरत असताना"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"कधीही नाही"</string>
-    <string name="loading" msgid="7811651799620593731">"लोड करत आहे..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"सर्व परवानग्या"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"अन्य अॅप क्षमता"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"परवानगीची विनंती"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"स्क्रीन ओव्हरले आढळले"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"हे परवानगी सेटिंग बदलण्‍यासाठी, तुम्हाला सेटिंग्ज &gt; अॅप्स मधून स्क्रीन ओव्हरले बंद करावे लागेल"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"सेटिंग्ज उघडा"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"इंस्टॉल करा/अनइंस्टॉल करा क्रिया Wear वर समर्थित नाहीत."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ला कशामध्‍ये प्रवेश करण्‍याची अनुमती द्यावी ते निवडा"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; अपडेट केला गेला आहे. या अॅपला कशामध्‍ये प्रवेश करण्‍याची अनुमती द्यावी ते निवडा."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"रद्द करा"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"सुरू ठेवा"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"नवीन परवानग्या"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"वर्तमान परवानग्या"</string>
-    <string name="message_staging" msgid="6151794817691100003">"अॅप प्रारंभाच्या स्थितीत आहे..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"अज्ञात"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"आपल्या सुरक्षिततेसाठी, आपल्या टॅबलेटला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"आपल्या सुरक्षिततेसाठी, आपल्या टीव्हीला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"आपल्या सुरक्षिततेसाठी, आपल्या फोनला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"तुमचा फोन आणि वैयक्तिक डेटा अज्ञात अॅप्‍समुळे होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हा अॅप इन्‍स्‍टॉल करून, तुम्‍ही सहमती देता की तो वापरल्‍याने होणार्‍या तुमच्‍या फोनच्‍या कोणत्‍याही प्रकारच्‍या नुकसान किंवा डेटा हानीसाठी तुम्ही जबाबदार आहात."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"तुमचा टॅबलेट आणि वैयक्तिक डेटा अज्ञात अॅप्‍समुळे होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हा अॅप इन्‍स्‍टॉल करून, तुम्‍ही सहमती देता की तो वापरल्‍याने होणार्‍या तुमच्‍या टॅबलेटच्‍या कोणत्‍याही प्रकारच्‍या नुकसान किंवा डेटा हानीसाठी तुम्ही जबाबदार आहात."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"तुमचा टीव्‍ही आणि वैयक्तिक डेटा अज्ञात अॅप्‍समुळे होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हा अॅप इन्‍स्‍टॉल करून, तुम्ही सहमती देता की तो वापरल्‍याने होणार्‍या तुमच्‍या टीव्‍हीच्‍या कोणत्‍याही प्रकारच्‍या नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"सुरू ठेवा"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"सेटिंग्ज"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"वेअर अ‍ॅप्स इन्‍स्टॉल/अनइन्‍स्टॉल करणे"</string>
+    <string name="app_name" msgid="7488448184431507488">"पॅकेज इंस्टॉलर"</string>
+    <string name="install" msgid="711829760615509273">"इंस्टॉल करा"</string>
+    <string name="done" msgid="6632441120016885253">"पूर्ण झाले"</string>
+    <string name="cancel" msgid="1018267193425558088">"रद्द करा"</string>
+    <string name="installing" msgid="4921993079741206516">"इंस्‍टॉल होत आहे…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> इंस्टॉल होत आहे…"</string>
+    <string name="install_done" msgid="5987363587661783896">"अॅप इंस्टॉल झाले."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"तुम्हाला हे अॅप्लिकेशन इंस्टॉल करायचे आहे का?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"तुम्हाच्या विद्यमान अॅप्लिकेशनवर अपडेट इंस्टॉल करायचे आहे का? तुमचा विद्यमान डेटा गमावणार नाही."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"तुम्हाला या बिल्ट-इन अॅप्लिकेशनवर अपडेट इंस्टॉल करायचे आहे का? तुमचा विद्यमान डेटा गमावणार नाही."</string>
+    <string name="install_failed" msgid="5777824004474125469">"अॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"पॅकेज इंस्टॉल होण्यापासून ब्लॉक केले होते."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"पॅकेजचा विद्यमान पॅकेजशी विरोध असल्याने अॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"तुमच्या टॅबलेटशी कंपॅटिबल नसल्याने अॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"हे अॅप तुमच्या टीव्हीशी कंपॅटिबल नाही."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"तुमच्या फोनशी कंपॅटिबल नसल्याने अॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"पॅकेज अयोग्य असल्याचे दिसत असल्याने अॅप इंस्टॉल झाले नाही."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> तुमच्या टॅबलेटवर इंस्टॉल केले जाऊ शकत नाही."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"या वापरकर्त्याद्वारे अज्ञात अ‍ॅप्स इंस्टॉल केली जाऊ शकत नाहीत"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"या वापरकर्त्याला अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही"</string>
+    <string name="ok" msgid="7871959885003339302">"ओके"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"अ‍ॅप्स व्यवस्थापन"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"जागा संपली"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> इंस्टॉल केले जाऊ शकत नाही. काही जागा मोकळी करा आणि पुन्हा प्रयत्न करा."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"अॅप आढळले नाही"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"इंस्टॉल केलेल्या अॅप्सच्या सूचीमध्ये अॅप आढळले नाही."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"अनुमती नाही"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"हे अनइंस्टॉल करण्याची विद्यमान वापरकर्त्यास अनुमती नाही."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"एरर"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"अॅप अनइंस्टॉल करणे शक्य झाले नाही."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"अॅप अनइंस्टॉल करा"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"अपडेट अनइंस्टॉल करा"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> खालील अॅपचा भाग आहे:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"तुम्हाला हे अॅप अनइंस्टॉल करायचे आहे का?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"तुम्हाला हे अॅप "<b>"सर्व"</b>" वापरकर्त्यांसाठी अनइंस्टॉल करायचे आहे का? अॅप्लिकेशन आणि त्याचा डेटा डिव्हाइसवरील "<b>"सर्व"</b>" वापरकर्त्यांकडून काढला जाईल."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"तुम्हाला <xliff:g id="USERNAME">%1$s</xliff:g> वापरकर्त्यासाठी हे अ‍ॅप अनइंस्टॉल करायचे आहे का?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"फॅक्टरी आवृत्तीसह हे अॅप बदलायचे का? सर्व डेटा काढला जाईल."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"फॅक्टरी आवृत्तीसह हे अॅप बदलायचे? सर्व डेटा काढला जाईल. हे कार्य प्रोफाइल असलेल्यांसह या डिव्हाइसच्या सर्व वापरकर्त्यांना प्रभावित करते."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"अनइंस्टॉल रन होत आहेत"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"अनइंस्टॉल करता आले नाही"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"अनइंस्टॉल करत आहे…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> अनइंस्टॉल करत आहे…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"अनइंस्टॉल पूर्ण झाले."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"इंस्टॉल करा/अनइंस्टॉल करा क्रिया Wear वर सपोर्ट करत नाहीत."</string>
+    <string name="message_staging" msgid="8032722385658438567">"अॅप सुरुवातीच्या स्थितीत आहे…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"अज्ञात"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"तुमच्या सुरक्षिततेसाठी, तुमच्या टॅबलेटला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"तुमच्या सुरक्षिततेसाठी, तुमच्या टीव्हीला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"तुमच्या सुरक्षिततेसाठी, तुमच्या फोनला या स्रोताकडील अज्ञात अ‍ॅप्स इंस्टॉल करण्याची अनुमती नाही."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"तुमचा फोन आणि वैयक्तिक डेटा अज्ञात अॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अॅप इंस्टॉल करून, तुम्‍ही सहमती देता की ते वापरल्‍याने होणार्‍या तुमच्‍या फोनचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"तुमचा टॅबलेट आणि वैयक्तिक डेटा अज्ञात अॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अॅप इंस्टॉल करून, तुम्‍ही सहमती देता की ते वापरल्‍याने तुमच्‍या टॅबलेटचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"तुमचा टीव्‍ही आणि वैयक्तिक डेटा अज्ञात अॅप्‍सकडून होणार्‍या अटॅकमुळे अधिक असुरक्षित आहे. हे अॅप इंस्टॉल करून, तुम्ही सहमती देता की ते वापरल्‍याने तुमच्‍या टीव्‍हीचे कोणत्‍याही प्रकारे होणारे नुकसान किंवा डेटा हानीसाठी तुम्‍ही जबाबदार आहात."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"सुरू ठेवा"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"सेटिंग्ज"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"wear अ‍ॅप्स इंस्टॉल/अनइंस्टॉल करत आहे"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ms/strings.xml b/packages/PackageInstaller/res/values-ms/strings.xml
index 6ab23ac..620dc3f 100644
--- a/packages/PackageInstaller/res/values-ms/strings.xml
+++ b/packages/PackageInstaller/res/values-ms/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Pemasang pakej"</string>
-    <string name="next" msgid="3057143178373252333">"Seterusnya"</string>
-    <string name="install" msgid="5896438203900042068">"Pasang"</string>
-    <string name="done" msgid="3889387558374211719">"Selesai"</string>
-    <string name="cancel" msgid="8360346460165114585">"Batal"</string>
-    <string name="installing" msgid="8613631001631998372">"Memasang..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Memasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikasi dipasang."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Adakah anda mahu memasang aplikasi ini? Aplikasi ini akan mendapat akses kepada:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Adakah anda mahu memasang aplikasi ini? Aplikasi ini tidak memerlukan sebarang akses khas."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Adakah anda mahu memasang kemas kini kepada aplikasi sedia ada ini? Data sedia ada anda tidak akan hilang. Aplikasi yang dikemaskinikan akan mendapat akses kepada:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Adakah anda ingin memasang kemas kini kepada aplikasi terbina dalam ini? Data sedia ada anda tidak akan hilang. Aplikasi yang dikemaskinikan akan mendapat akses kepada:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Adakah anda mahu memasang kemas kini untuk aplikasi sedia ada ini? Data sedia ada anda tidak akan hilang. Hal ini tidak memerlukan sebarang akses khas."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Adakah anda mahu memasang kemas kini untuk aplikasi terbina dalam ini? Data sedia ada anda tidak akan hilang. Hal ini tidak memerlukan sebarang akses khas."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikasi tidak dipasang."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Pakej ini telah disekat daripada dipasang."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Apl tidak dipasang kerana pakej bercanggah dengan pakej yang sedia ada."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Apl tidak dipasang kerana apl tidak serasi dengan tablet anda."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Apl ini tidak serasi dengan TV anda."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Apl tidak dipasang kerana apl tidak serasi dengan telefon anda."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Apl tidak dipasang kerana pakej tidak sah."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasangkan pada tablet anda."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak boleh dipasang pada TV anda."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasangkan pada telefon anda."</string>
-    <string name="launch" msgid="4826921505917605463">"Buka"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Pentadbir anda tidak membenarkan pemasangan apl yang diperoleh daripada sumber yang tidak diketahui"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Apl yang tidak diketahui tidak boleh dipasang oleh pengguna ini"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Pengguna ini tidak dibenarkan memasang apl"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Urus aplikasi"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Kehabisan ruang"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang. Kosongkan sebahagian ruang dan cuba lagi."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikasi tidak ditemui"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikasi tidak ditemui dalam senarai aplikasi yang dipasang."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Tidak dibenarkan"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Pengguna semasa tidak dibenarkan untuk melaksanakan penyahpasangan ini."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Ralat"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Apl tidak dapat dinyapasang."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Nyahpasang aplikasi"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Nyahpasang kemas kini"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> merupakan sebahagian daripada aplikasi berikut:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Adakah anda mahu menyahpasang aplikasi ini?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Adakah anda mahu menyahpasang apl ini untuk "<b>"semua"</b>" pengguna? Aplikasi dan datanya akan dialih keluar daripada "<b>"semua"</b>" pengguna pada peranti."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Adakah anda ingin menyahpasang apl ini untuk pengguna <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Gantikan apl ini dengan versi kilang? Semua data akan dialih keluar."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Gantikan apl ini dengan versi kilang? Semua data akan dialih keluar. Tindakan ini melibatkan semua pengguna peranti ini, termasuk mereka yang mempunyai profil kerja."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Penyahpasangan yang sedang berjalan"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Penyahpasangan yang gagal"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Menyahpasang..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Nyahpasang selesai."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> dinyahpasang"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Nyahpasang tidak berjaya."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Tidak berjaya menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Tidak dapat menyahpasang apl pentadbir peranti yang aktif"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Tidak dapat menyahpasang apl pentadbir peranti yang aktif untuk <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Apl ini diperlukan untuk sesetengah pengguna atau profil dan telah dinyahpasang untuk yang lain"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Apl ini diperlukan untuk profil anda dan tidak boleh dinyahpasang."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Apl ini diperlukan oleh pentadbir peranti anda dan tidak boleh dinyahpasang."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Urus apl pentadbir peranti"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Urus pengguna"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dinyahpasang."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Terdapat masalah menghuraikan pakej."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Baharu"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Semua"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privasi"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Akses Peranti"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Kemas kini ini tidak memerlukan kebenaran baharu."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Tolak"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Maklumat lanjut"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tolak juga"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> daripada <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Sentiasa benarkan &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Hanya semasa menggunakan apl"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Sentiasa"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Tolak dan jangan tanya lagi"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> dilumpuhkan"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"semua dilumpuhkan"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"tiada apa-apa yang dilumpuhkan"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Benarkan"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apl"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Kebenaran apl"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Jangan tanya lagi"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Tiada kebenaran"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Kebenaran tambahan"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Buka maklumat apl"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> lagi</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> lagi</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Apl ini direka bentuk untuk versi Android yang lebih lama. Tindakan menafikan kebenaran boleh menyebabkannya tidak berfungsi seperti yang dimaksudkan lagi."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"laksanakan tindakan yang tidak diketahui"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> daripada <xliff:g id="COUNT_1">%2$d</xliff:g> apl dibenarkan"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Tunjukkan sistem"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Sembunyikan sistem"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Tiada apl"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Tetapan Lokasi"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ialah pembekal perkhidmatan lokasi untuk peranti ini. Akses lokasi boleh diubah suai daripada tetapan lokasi."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Jika anda tolak kebenaran ini, ciri asas peranti anda mungkin tidak berfungsi seperti yang dimaksudkan lagi."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Dikuatkuasakan oleh dasar"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Akses latar belakang dilumpuhkan oleh dasar"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Akses latar belakang didayakan oleh dasar"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Akses latar depan didayakan oleh dasar"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Dikawal oleh pentadbir"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Sentiasa"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Hanya semasa menggunakan apl"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Jangan sekali-kali"</string>
-    <string name="loading" msgid="7811651799620593731">"Memuatkan…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Semua kebenaran"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Keupayaan apl yang lain"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Permintaan kebenaran"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Tindanan skrin dikesan"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Untuk menukar tetapan kebenaran ini, anda perlu mematikan tindanan skrin daripada Tetapan &gt; Apl terlebih dahulu"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Buka tetapan"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Tindakan pasang/nyahpasang tidak disokong pada Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Pilih perkara yang boleh diakses oleh &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; telah dikemas kini. Pilih perkara yang boleh diakses oleh apl ini."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Batal"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Teruskan"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Kebenaran baharu"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Kebenaran semasa"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Pemeringkatan apl…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Tidak diketahui"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Untuk keselamatan, tablet anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Untuk keselamatan, TV anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Untuk keselamatan, telefon anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefon dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada telefon anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tablet dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada tablet anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada TV anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Teruskan"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Tetapan"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Memasang/menyahpasang apl wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Pemasang pakej"</string>
+    <string name="install" msgid="711829760615509273">"Pasang"</string>
+    <string name="done" msgid="6632441120016885253">"Selesai"</string>
+    <string name="cancel" msgid="1018267193425558088">"Batal"</string>
+    <string name="installing" msgid="4921993079741206516">"Memasang…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Memasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikasi dipasang."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Adakah anda ingin memasang aplikasi ini?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Adakah anda mahu memasang kemas kini pada aplikasi yang sedia ada? Data anda yang sedia ada tidak akan hilang."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Adakah anda mahu memasang kemas kini pada aplikasi terbina dalam ini? Data anda yang sedia ada tidak akan hilang."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikasi tidak dipasang."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Pakej ini telah disekat daripada dipasang."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Apl tidak dipasang kerana pakej bercanggah dengan pakej yang sedia ada."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Apl tidak dipasang kerana apl tidak serasi dengan tablet anda."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Apl ini tidak serasi dengan TV anda."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Apl tidak dipasang kerana apl tidak serasi dengan telefon anda."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Apl tidak dipasang kerana pakej tidak sah."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang pada tablet anda."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang pada TV anda."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang pada telefon anda."</string>
+    <string name="launch" msgid="3952550563999890101">"Buka"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Pentadbir anda tidak membenarkan pemasangan apl yang diperoleh daripada sumber yang tidak diketahui"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Apl yang tidak diketahui tidak boleh dipasang oleh pengguna ini"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Pengguna ini tidak dibenarkan memasang apl"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Urus apl"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Kehabisan ruang"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dipasang. Kosongkan sebahagian ruang dan cuba lagi."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Apl tidak ditemui"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Apl tidak ditemui dalam senarai aplikasi yang dipasang."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Tidak dibenarkan"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Pengguna semasa tidak dibenarkan melaksanakan penyahpasangan ini."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Ralat"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Apl tidak dapat dinyapasang."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Nyahpasang apl"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Nyahpasang kemas kini"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> merupakan sebahagian daripada apl berikut:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Adakah anda mahu menyahpasang apl ini?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Adakah anda mahu menyahpasang apl ini untuk "<b>"semua"</b>" pengguna? Aplikasi dan datanya akan dialih keluar daripada "<b>"semua"</b>" pengguna pada peranti."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Adakah anda ingin menyahpasang apl ini untuk pengguna <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Gantikan apl ini dengan versi kilang? Semua data akan dialih keluar."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Gantikan apl ini dengan versi kilang? Semua data akan dialih keluar. Tindakan ini melibatkan semua pengguna peranti ini, termasuk mereka yang mempunyai profil kerja."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Penyahpasangan yang sedang berjalan"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Penyahpasangan yang gagal"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Menyahpasang…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Nyahpasang selesai."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> dinyahpasang"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Penyahpasangan tidak berjaya."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Tidak berjaya menyahpasang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Tidak dapat menyahpasang apl pentadbir peranti yang aktif"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Tidak dapat menyahpasang apl pentadbir peranti yang aktif untuk <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Apl ini diperlukan untuk sesetengah pengguna atau profil dan telah dinyahpasang untuk yang lain"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Apl ini diperlukan untuk profil anda dan tidak boleh dinyahpasang."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Apl ini diperlukan oleh pentadbir peranti anda dan tidak boleh dinyahpasang."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Urus apl pentadbir peranti"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Urus pengguna"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dapat dinyahpasang."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Masalah telah berlaku semasa menghuraikan pakej."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Tindakan pasang/nyahpasang tidak disokong pada Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Pemeringkatan apl…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Tidak diketahui"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Untuk keselamatan, tablet anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Untuk keselamatan, TV anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Untuk keselamatan, telefon anda tidak dibenarkan memasang apl yang tidak diketahui daripada sumber ini."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefon dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada telefon anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tablet dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada tablet anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV dan data peribadi anda lebih mudah diserang oleh apl yang tidak diketahui. Dengan memasang apl ini, anda bersetuju bahawa anda bertanggungjawab atas sebarang kerosakan pada TV anda atau kehilangan data yang mungkin disebabkan oleh penggunaan apl tersebut."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Teruskan"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Tetapan"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Memasang/menyahpasang apl wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-my/strings.xml b/packages/PackageInstaller/res/values-my/strings.xml
index 02199c3..c115cad 100644
--- a/packages/PackageInstaller/res/values-my/strings.xml
+++ b/packages/PackageInstaller/res/values-my/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Package ထည့်သွင်းခြင်း"</string>
-    <string name="next" msgid="3057143178373252333">"ရှေ့သို့"</string>
-    <string name="install" msgid="5896438203900042068">"ထည့်သွင်းပါ"</string>
-    <string name="done" msgid="3889387558374211719">"ပြီးပါပြီ"</string>
-    <string name="cancel" msgid="8360346460165114585">"မလုပ်တော့"</string>
-    <string name="installing" msgid="8613631001631998372">"ထည့်သွင်းနေပါသည်"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ထည့်သွင်းနေသည်…"</string>
-    <string name="install_done" msgid="3682715442154357097">"အက်ပ်ထည့်သွင်းပြီး"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"ဤအပလီကေးရှင်းကို ထည့်သွင်းပါမလား။ ဤအပလီကေးရှင်း သုံးစွဲခွင့်ရှိမှာ ကတော့:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ဤအပလီကေးရှင်းကို ထည့်သွင်းပါမလား။ အထူးတလည် သုံးခွင့် မလိုအပ်ပါ"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"လက်ရှိ ရှိပြီးသား အပလီကေးရှင်းကို အပ်ဒိတ်လုပ်လိုပါသလား။ ရှိပြီးသား အချက်အလက်များကို ဆုံးရှုံးမည် မဟုတ်ပါ။ အပ်ဒိတ်လုပ်လိုက်သော အပလီကေးရှင်းသုံးစွဲခွင့်ရှိမှာ များကတော့-"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"အဆင့်သင့် ပါလာသော အပလီကေးရှင်းကို အပ်ဒိတ်လုပ်လိုပါသလား။  ရှိပြီးသား အချက်အလက်များကို ဆုံးရှုံးမည် မဟုတ်ပါ။ အပ်ဒိတ်လုပ်လိုက်သော အပလီကေးရှင်း သုံးစွဲခွင့်ရှိမှာ များကတော့ -"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"လက်ရှိ ရှိပြီးသား အပလီကေးရှင်းကို အပ်ဒိတ်လုပ်လိုပါသလား။  ရှိပြီးသား အချက်အလက်များကို ဆုံးရှုံးမည် မဟုတ်ပါ။ အထူးတလည် သုံးခွင့် မလိုအပ်ပါ"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"အဆင့်သင့် ပါလာသော အပလီကေးရှင်းကို အပ်ဒိတ်လုပ်လိုပါသလား။  ရှိပြီးသား အချက်အလက်များကို ဆုံးရှုံးမည် မဟုတ်ပါ။ အထူးတလည် သုံးခွင့် မလိုအပ်ပါ"</string>
-    <string name="install_failed" msgid="6579998651498970899">"အက်ပ်မထည့်သွင်းရသေးပါ"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ပက်ကေ့ထည့်သွင်းခြင်းကို ပိတ်ဆို့ထားသည်။"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"ပက်ကေ့ဂျ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် လက်ရှိပက်ကေ့ဂျ်နှင့် တိုက်နေသည်။"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"အက်ပ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် သင့်တက်ဘလက်နှင့် ကိုက်ညီမှုမရှိပါ။"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ဤ အက်ပ်သည် သင့်တီဗွီနှင့် တွဲဖက်သုံးမရပါ။"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"အက်ပ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် သင့်ဖုန်းနှင့် ကိုက်ညီမှုမရှိပါ။"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"ပက်ကေ့ဂျ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် မှန်ကန်မှုမရှိပုံပေါ်သည်။"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို သင့်တက်ဘလက်တွင် ထည့်သွင်းလို့ မရနိုင်ပါ"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"သင့်တီဗွီတွင် <xliff:g id="APP_NAME">%1$s</xliff:g> အား မတပ်ဆင်နိုင်ပါ။"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို သင့်ဖုန်းတွင် ထည့်သွင်းလို့ မရနိုင်ပါ"</string>
-    <string name="launch" msgid="4826921505917605463">"ဖွင့်သည်"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"သင်၏ စီမံခန့်ခွဲသူက ရင်းမြစ်မသိသော အက်ပ်များကို ထည့်သွင်းခွင့်မပြုပါ"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"အရင်းအမြစ်မသိသော အက်ပ်များကို ဤအသုံးပြုသူက ထည့်သွင်းခွင့်မရှိပါ"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ဤအသုံးပြုသူသည် အက်ပ်များကို ထည့်သွင်းခွင့်မရှိပါ"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"အပလီကေးရှင်းများအား ထိန်းသိမ်းခြင်း"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"နေရာလွတ်မရှိပါ"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ထည့်သွင်းလို့ မရနိုင်ပါ။ နေရာအပိုရအောင် ရှင်းလင်းပြီး ပြန်ကြိုးစားပါ"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"အက်ပ်အားမတွေ့ပါ"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ထည့်သွင်းထားသော အပလီကေးရှင်းထဲတွင် ဤအပလီကေးရှင်း မတွေ့ရှိပါ"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ခွင့်ပြုမထားပါ"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ဤဖယ်ရှားမှုပြုလုပ်ရန် လက်ရှိအသုံးပြုသူအား ခွင့်ပြုမထားပါ။"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"အမှားအယွင်း"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"အက်ပ်ကို ဖယ်ရှား၍မရနိုင်ပါ။"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"အပလီကေးရှင်းကို ဖယ်ရှားပါ"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"အပ်ဒိတ်လုပ်ထားခြင်းကို ပြန်ထုတ်ပါ"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ကတော့ အောက်ပါ အက်ပ်၏အစိတ်အပိုင်း တစ်ခု ဖြစ်ပါသည်:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"ဤအပလီကေးရှင်းကို သင်ဖယ်ရှားချင်ပါသလား"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ဤအပလီကေးရှင်းကို အသုံးပြုသူ"<b>" အားလုံး"</b>" အတွက် ဖယ်ရှားချင်ပါသလား? ဤအပလီကေးရှင်း နှင့် သက်ဆိုင်ရာ အချက်အလက်များ အားလုံးကို "<b>" မှ  အားလုံးသော "</b>" စက်အသုံးပြုသူတွေအတွက် ဖယ်ရှားပစ်ပါလိမ့်မည်"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"သင်သည် အသုံးပြုသူ <xliff:g id="USERNAME">%1$s</xliff:g> အတွက် ဒီအကောင့်ကို ဖြုတ်ပစ်လိုပါသလား?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ဤအက်ပ်ကို စက်ရုံထုတ်ဗားရှင်းဖြင့် အစားထိုးမလား။ ဒေတာများအားလုံးကို ဖယ်ရှားလိုက်ပါမည်။"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ဤအက်ပ်ကို စက်ရုံထုတ်ဗားရှင်းဖြင့် အစားထိုးမလား။ ဒေတာများအားလုံးကို ဖယ်ရှားလိုက်ပါမည်။ ၎င်းသည် အလုပ်ပရိုဖိုင်ဖြင့်သုံးသူများအပါအဝင် အသုံးပြုသူများအားလုံးကို အကျိုးသက်ရောက်စေပါလိမ့်မည်။"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ပရိုဂရမ်ကို ဖယ်ရှားနေပါသည်"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ပရိုဂရမ်ကို ဖယ်ရှားခြင်းမအောင်မြင်ပါ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"ဖယ်ထုတ်သည်"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားနေပါသည်…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"ဖယ်ရှားခြင်း ပြီးပါပြီ"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားလိုက်ပါပြီ"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"ဖယ်ရှားမှု မအောင်မြင်ပါ"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားခြင်း မအောင်မြင်ပါ။"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ဖွင့်ထားသော စက်ပစ္စည်းကို စီမံခန့်ခွဲရန်အက်ပ်အား ဖယ်ရှား၍မရပါ"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> အတွက် ဖွင့်ထားသော စက်ပစ္စည်းကို စီမံခန့်ခွဲရန် အက်ပ်အား ဖယ်ရှား၍မရပါ။"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"အချို့အသုံးပြုသူများ သို့မဟုတ် ပရိုဖိုင်များအတွက် ဤအက်ပ်ကို လိုအပ်သော်လည်း အချို့သူများအတွက် ဖြုတ်ထားပါသည်"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"သင့်ပရိုဖိုင်အတွက် ဤအက်ပ်ကိုလိုအပ်ပြီး ဖြုတ်၍မရပါ။"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ဒီအက်ပ်မှာ သင်၏ ကိရိယာ စီမံအုပ်ချုပ်သူက လိုအပ်သောကြောင့် ဖြုတ်၍ မရနိုင်ပါ။"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"စက်ပစ္စည်းကို စီမံခန့်ခွဲရန် အက်ပ်များအား စီမံရန်"</string>
-    <string name="manage_users" msgid="3125018886835668847">"အသုံးပြုသူများအား စီမံခန့်ခွဲပါ"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ဖယ်ရှားလို့ မရပါ"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ဒေတာအချက်အလက်အစုအားဖတ်ရှုစဉ် ပြသနာ တစ်ခု ဖြစ်ပေါ်ပါသည်"</string>
-    <string name="newPerms" msgid="6039428254474104210">"အသစ်"</string>
-    <string name="allPerms" msgid="1024385515840703981">"အားလုံး"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"လုံခြုံမှု"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"စက်ပစ္စည်း အသုံးပြုခွင့်"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ဤအပ်ဒိတ်အတွက် ခွင့်ပြုချက်အသစ် မလိုအပ်ပါ"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ငြင်းပယ်သည်"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"အခြားအချက်အလက်များ"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"မည်သို့ပင်ဖြစ်စေ ငြင်းပယ်ပါ"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ကို <xliff:g id="ACTION">%2$s</xliff:g> ရန်ခွင့်ပြုမလား။"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ကို <xliff:g id="ACTION">%2$s</xliff:g> ရန် အမြဲခွင့်ပြုသလား။"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"အက်ပ်အသုံးပြုစဉ်သာ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"အမြဲတမ်း"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ငြင်းဆိုသည်၊ ထပ်မမေးပါနှင့်"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ခု ပိတ်ထားသည်"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"အားလုံးပိတ်ထားသည်"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"တစ်ခုမျှ ပိတ်မထားပါ"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ခွင့်ပြုသည်"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"အက်ပ်များ"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"အက်ပ်ခွင့်ပြုချက်များ"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"နောက်ထပ်မမေးပါနှင့်"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"ခွင့်ပြုချက်မရှိ"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"ထပ်တိုး ခွင့်ပြုချက်များ"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"အက်ပ်အချက်အလက် ဖွင့်ရန်"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"> နောက်ထပ် <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one"> နောက်ထပ် <xliff:g id="COUNT_0">%1$d</xliff:g> </item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ဤအက်ပ် အား Android ၏ ဗားရှင်းဟောင်းအတွက် ပုံဆွဲရေးဆွဲထား၏။ ခွင့်ပြုချက်ပေးရန် ငြင်းဆိုပါက ရည်ရွယ်ထားသကဲ့သို့ ဆောင်ရွက်လိမ့်မည် မဟုတ်ပါ။"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"အမျိုးအမည်မသိ ဆောင်ရွက်ချက်တစ်ခု လုပ်ရန်"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"အက်ပ် <xliff:g id="COUNT_1">%2$d</xliff:g> မှ <xliff:g id="COUNT_0">%1$d</xliff:g> ခု ခွင့်ပြုသည်"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"စနစ်ကိုပြသရန်"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"စနစ်ကို ဖျောက်မည်"</string>
-    <string name="no_apps" msgid="1965493419005012569">"အက်ပ် မရှိပါ"</string>
-    <string name="location_settings" msgid="1774875730854491297">"တည်နေရာ ဆက်တင်များ"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် ဤစက်ပစ္စည်းအတွက် တည်နေရာ ဝန်ဆောင်မှုများ ထုတ်ပေးသူဖြစ်သည်။ တည်နေရာ အသုံးပြုမှုကို တည်နေရာချိန်ညှိမှုများတွင် ပြုပြင်နိုင်သည်။"</string>
-    <string name="system_warning" msgid="7103819124542305179">"ဤခွင့်ပြုချက်အား သင် ငြင်းဆိုပါက၊ သင့်စက်ကိရိယာ၏ အခြေခံလုပ်ဆောင်ချက်များသည် ရည်ရွယ်ထားသကဲ့သို့ အလုပ်လုပ်မည် မဟုတ်ပါ။"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"မူဝါဒအားဖြင့်ပြဌာန်းရန်"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"နောက်ခံတွင်ဝင်သုံးခွင့်ကို မူဝါဒက ပိတ်ထားသည်"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"နောက်ခံတွင်ဝင်သုံးခွင့်ကို မူဝါဒက ဖွင့်ထားသည်"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"မျက်နှာစာတွင်ဝင်သုံးခွင့်ကို မူဝါဒက ဖွင့်ထားသည်"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"စီမံခန့်ခွဲသူက ထိန်းချုပ်ထားသည်"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"အမြဲတမ်း"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"အက်ပ်အသုံးပြုစဉ်သာ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ဘယ်တော့မှ"</string>
-    <string name="loading" msgid="7811651799620593731">"တင်နေ…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"ခွင့်ပြုချက်များ အားလုံး"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"အခြားအပ်ဖ်၏ စွမ်းရည်များ"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"ခွင့်ပြုချက် တောင်းခံမှု"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"မျက်နှာပြင် ထပ်ပေးမှုကို ရှာတွေ့ခဲ့"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ဒီခွင့်ပြုချက် ဆက်တင်ကို ပြောင်းရန်၊ သင်ဟာ ဦးစွာ ဆက်တင်များ &gt; အက်ပ်များ ထဲတွင် မျက်နှာပြင် ထပ်ပေးမှုကို ပိတ်လိုက်ရန် လိုမယ်"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ဆက်တင်းများ ဖွင့်ရန်"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear ပေါ်တွင် ထည့်သွင်းခြင်း/ဖြုတ်ခြင်းများကို ပံ့ပိုးမထားပါ။"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&amp;It;b7gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&amp;It;/b&gt; က အသုံးပြုခွင့်ရမည့် အရာတို့ကို ရွေးပါ"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&amp;It;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&amp;It;/b&gt; ကို အပ်ဒိတ်လုပ်ပြီးပါပြီ။ ဤအက်ပ်က အသုံးပြုခွင့်ရမည့်အရာတို့ကို ရွေးပါ။"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"မလုပ်တော့"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"ဆက်လုပ်ရန်"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"ခွင့်ပြုချက် အသစ်များ"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"လက်ရှိ ခွင့်ပြုချက်များ"</string>
-    <string name="message_staging" msgid="6151794817691100003">"အက်ပ်ကို ပြင်ဆင်နေသည်…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"အမျိုးအမည်မသိ"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏တက်ဘလက်တွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏တီဗီတွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏ဖုန်းတွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"သင်၏ဖုန်းနှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော ဖုန်းပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"သင်၏ တက်ဘလက်နှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော တက်ဘလက်ပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"သင်၏ TV နှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော TV ပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ဆက်လုပ်ရန်"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ဆက်တင်များ"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"wear အက်ပ်ကိုထည့်သွင်းခြင်း/ဖယ်ရှားခြင်း"</string>
+    <string name="app_name" msgid="7488448184431507488">"ပက်ကေ့ဂျ်ထည့်သွင်းကိရိယာ"</string>
+    <string name="install" msgid="711829760615509273">"ထည့်သွင်းရန်"</string>
+    <string name="done" msgid="6632441120016885253">"ပြီးပြီ"</string>
+    <string name="cancel" msgid="1018267193425558088">"မလုပ်တော့"</string>
+    <string name="installing" msgid="4921993079741206516">"ထည့်သွင်းနေသည်…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ထည့်သွင်းနေသည်…"</string>
+    <string name="install_done" msgid="5987363587661783896">"အက်ပ်ထည့်သွင်းပြီးပါပြီ"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"ဤအပလီကေးရှင်းကို ထည့်သွင်းလိုသလား။"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"ဤလက်ရှိအပလီကေးရှင်းအတွက် အပ်ဒိတ်ကို ထည့်သွင်းလိုပါသလား။ သင်၏ လက်ရှိဒေတာများ ဆုံးရှုံးသွားမည် မဟုတ်ပါ။"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"ဤနဂိုအသင့်ပါ အပလီကေးရှင်းအတွက် အပ်ဒိတ်ကို ထည့်သွင်းလိုပါသလား။ သင်၏ လက်ရှိဒေတာများ ဆုံးရှုံးသွားမည် မဟုတ်ပါ။"</string>
+    <string name="install_failed" msgid="5777824004474125469">"အက်ပ်မထည့်သွင်းရသေးပါ"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"ပက်ကေ့ဂျ်ထည့်သွင်းခြင်းကို ပိတ်ထားသည်။"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"ပက်ကေ့ဂျ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် လက်ရှိပက်ကေ့ဂျ်နှင့် တိုက်နေသည်။"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"အက်ပ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် သင့်တက်ဘလက်နှင့် ကိုက်ညီမှုမရှိပါ။"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"ဤအက်ပ်သည် သင့် TV နှင့် တွဲဖက်သုံးမရပါ။"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"အက်ပ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် သင့်ဖုန်းနှင့် ကိုက်ညီမှုမရှိပါ။"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"ပက်ကေ့ဂျ်အဖြစ် ထည့်သွင်းမထားသော အက်ပ်သည် မှန်ကန်မှုရှိပုံ မပေါ်ပါ။"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို သင့်တက်ဘလက်တွင် ထည့်သွင်း၍ မရနိုင်ပါ။"</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို သင်၏ TV တွင် ထည့်သွင်း၍မရပါ။"</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_user_restriction_dlg_text" msgid="151020786933988344">"အရင်းအမြစ်မသိသော အက်ပ်များကို ဤအသုံးပြုသူက ထည့်သွင်းခွင့်မရှိပါ"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ဤအသုံးပြုသူသည် အက်ပ်များကို ထည့်သွင်းခွင့်မရှိပါ"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"အက်ပ်စီမံခြင်း"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"နေရာလွတ်မရှိပါ"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ထည့်သွင်း၍ မရနိုင်ပါ။ နေရာလွတ်ပြုလုပ်ပြီး ထပ်စမ်းကြည့်ပါ။"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"အက်ပ် မတွေ့ပါ"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ထည့်သွင်းထားသော အက်ပ်စာရင်းတွင် ဤအက်ပ်ကိုမတွေ့ပါ"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"ခွင့်ပြုမထားပါ"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"ဤဖယ်ရှားမှုပြုလုပ်ရန် လက်ရှိအသုံးပြုသူအား ခွင့်ပြုမထားပါ။"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"အမှား"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"အက်ပ်ကို ဖယ်ရှား၍မရနိုင်ပါ။"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"အက်ပ်ကို ဖယ်ရှားရန်"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"အပ်ဒိတ်ကို ဖယ်ရှားရန်"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> သည် အောက်ပါအက်ပ်၏ တစ်စိတ်တစ်ဒေသဖြစ်သည်−"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"ဤအက်ပ်ကို ဖယ်ရှားလိုပါသလား။"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"ဤအပလီကေးရှင်းကို အသုံးပြုသူ "<b>"အားလုံး"</b>" အတွက် ဖယ်ရှားလိုပါသလား။ ဤအပလီကေးရှင်းနှင့် သက်ဆိုင်ရာ အချက်အလက်များ အားလုံးကို "<b>" က "</b>" စက်အသုံးပြုသူများအတွက် ဖယ်ရှားလိုက်ပါမည်။"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"သင်သည် အသုံးပြုသူ <xliff:g id="USERNAME">%1$s</xliff:g> အတွက် ဤအကောင့်ကို ဖယ်ရှားလိုပါသလား။"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ဤအက်ပ်ကို စက်ရုံထုတ်ဗားရှင်းဖြင့် အစားထိုးလိုပါသလား။ ဒေတာများအားလုံးကို ဖယ်ရှားလိုက်ပါမည်။"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ဤအက်ပ်ကို စက်ရုံထုတ်ဗားရှင်းဖြင့် အစားထိုးလိုသလား။ ဒေတာများအားလုံးကို ဖယ်ရှားလိုက်ပါမည်။ ၎င်းသည် အလုပ်ပရိုဖိုင်ဖြင့်သုံးသူများအပါအဝင် အသုံးပြုသူများအားလုံးကို အကျိုးသက်ရောက်စေပါမည်။"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"ပရိုဂရမ်ကို ဖယ်ရှားနေပါသည်"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"ပရိုဂရမ်ကို ဖယ်ရှား၍မရပါ"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"ပရိုဂရမ်ကို ဖယ်ရှားနေသည်..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ကို ဖယ်ရှားနေပါသည်…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"ဖယ်ရှားပြီးပါပြီ။"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear ပေါ်တွင် ထည့်သွင်းခြင်း/ဖယ်ရှားခြင်းများကို ပံ့ပိုးမထားပါ။"</string>
+    <string name="message_staging" msgid="8032722385658438567">"အက်ပ်ကို ပြင်ဆင်နေသည်…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"အမည်မသိ"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏တက်ဘလက်တွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏တီဗီတွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"လုံခြုံရေးအရ ဤနေရာမှရယူထားသည့် အမျိုးအမည်မသိသောအက်ပ်များကို သင်၏ဖုန်းတွင် ထည့်သွင်းခွင့်မရှိပါ။"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"သင်၏ဖုန်းနှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော ဖုန်းပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"သင်၏ တက်ဘလက်နှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော တက်ဘလက်ပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"သင်၏ TV နှင့် ကိုယ်ရေးကိုယ်တာ အချက်အလက်များသည် အမျိုးအမည် မသိသောအက်ပ်များ၏ တိုက်ခိုက်ခြင်းကို ပိုမိုခံရနိုင်ပါသည်။ ဤအက်ပ်ကို ထည့်သွင်းအသုံးပြုခြင်းအားဖြင့် ဖြစ်ပေါ်လာနိုင်သော TV ပျက်စီးမှု သို့မဟုတ် ဒေတာဆုံးရှုံးမှုများအတွက် သင့်ထံ၌သာ တာဝန်ရှိကြောင်း သဘောတူရာရောက်ပါသည်။"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"ရှေ့ဆက်ရန်"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"ဆက်တင်များ"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"wear အက်ပ်ကိုထည့်သွင်းခြင်း/ဖယ်ရှားခြင်း"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-nb/strings.xml b/packages/PackageInstaller/res/values-nb/strings.xml
index 3ff3de4..f39bf2d 100644
--- a/packages/PackageInstaller/res/values-nb/strings.xml
+++ b/packages/PackageInstaller/res/values-nb/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Pakkeinstallasjon"</string>
-    <string name="next" msgid="3057143178373252333">"Neste"</string>
-    <string name="install" msgid="5896438203900042068">"Installer"</string>
-    <string name="done" msgid="3889387558374211719">"Ferdig"</string>
-    <string name="cancel" msgid="8360346460165114585">"Avbryt"</string>
-    <string name="installing" msgid="8613631001631998372">"Installerer…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Installerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
-    <string name="install_done" msgid="3682715442154357097">"Appen er installert."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Ønsker du å installere denne appen? Den får tilgang til følgende:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ønsker du å installere denne appen? Den krever ingen spesiell tilgang."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Ønsker du å installere en oppdatering for denne eksisterende appen? Du mister ingen eksisterende data. Den oppdaterte appen får tilgangen spesifisert nedenfor."</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ønsker du å installere en oppdatering for denne innebygde appen? Du mister ingen eksisterende data. Den oppdaterte appen får tilgangen spesifisert nedenfor."</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vil du installere en oppdatering av denne eksisterende appen? De eksisterende dataene dine går ikke tapt. Dette krever ingen spesiell tilgang."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vil du installere en oppdatering av denne innebygde appen? De eksisterende dataene dine går ikke tapt. Dette krever ingen spesiell tilgang."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Appen ble ikke installert."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Pakken er blokkert fra å bli installert."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Appen ble ikke installert fordi pakken er i konflikt med en eksisterende pakke."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Appen ble ikke installert fordi appen ikke er kompatibel med nettbrettet ditt."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Denne appen er ikke kompatibel med TV-en din."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Appen ble ikke installert fordi appen ikke er kompatibel med telefonen din."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Appen ble ikke installert fordi pakken ser ut til å være ugyldig."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på nettbrettet ditt."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på TV-en."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på telefonen din."</string>
-    <string name="launch" msgid="4826921505917605463">"Åpne"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratoren din tillater ikke installering av apper som er hentet fra ukjente kilder"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ukjente apper kan ikke installeres av denne brukeren"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Brukeren har ikke tillatelse til å installere apper"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Administrer apper"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Tom for plass"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres. Frigjør plass og prøv på nytt."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Appen ble ikke funnet"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Finner ikke appen i listen over installerte apper."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ikke tillatt"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Denne brukeren har ikke tillatelse til å utføre denne avinstalleringen."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Feil"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Kunne ikke avinstallere appen."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Avinstaller appen"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Avinstaller oppdateringen"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er del av følgende app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Vil du avinstallere denne appen?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vil du avinstallere denne appen for "<b>"alle"</b>" brukere? Appen og tilhørende data blir fjernet fra "<b>"alle"</b>" brukere på enheten."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ønsker du å avinstallere denne appen for brukeren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Vil du erstatte denne appen med den opprinnelige versjonen? Alle dataene fjernes."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vil du erstatte denne appen med den opprinnelige versjonen? Alle dataene fjernes. Dette påvirker alle som bruker denne enheten – også personer med jobbprofiler."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Avinstalleringer som er i gang"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mislykkede avinstalleringer"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Avinstallerer…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Avinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Avinstalleringen er  fullført."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Avinstallerte <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Avinstalleringen mislyktes."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Kunne ikke avinstallere <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Kan ikke avinstallere den aktive appen for enhetsadministrator"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Kan ikke avinstallere den aktive appen for enhetsadministrator for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Appen er nødvendig for noen brukere eller profiler, og den er avinstallert for andre"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Denne appen er nødvendig for profilen din og kan ikke avinstalleres."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Denne appen kreves av enhetsadministratoren din og kan ikke avinstalleres."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Administrer apper for enhetsadministrator"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Administrer brukere"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Det oppsto et problem med analysen av pakken."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nye"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Personvern"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Enhetstilgang"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Denne oppdateringen krever ingen nye tillatelser."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Ikke tillat"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Finn ut mer"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Avvis likevel"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> av <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Vil du gi &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; tillatelse til å <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vil du alltid tillate at &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; kan <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Bare når appen brukes"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Alltid"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Avvis, og ikke spør igjen"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> er slått av"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"alt er slått av"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ingen er slått av"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Tillat"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apper"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Apptillatelser"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ikke spør igjen"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Ingen tillatelser"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Flere tillatelser"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Åpne info om appen"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> til</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> til</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Denne appen er designet for en eldre versjon av Android. Hvis du nekter å gi tillatelse, kan det føre til at den ikke lenger fungerer etter hensikten."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"utfør en ukjent handling"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> av <xliff:g id="COUNT_1">%2$d</xliff:g> apper er tillatt"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Vis systemapper"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Skjul systemet"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Ingen apper"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Posisjonsinnstillinger"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> er en leverandør av posisjonstjenester for denne enheten. Tilgang til posisjon kan endres fra posisjonsinnstillingene."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Hvis du ikke gir denne tillatelsen, kan grunnleggende funksjoner på enheten slutte å fungere som de skal."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Påkrevd ifølge retningslinjene"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Bakgrunnstilgang er slått av pga. retningslinjene"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Bakgrunnstilgang er slått på pga. retningslinjene"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Forgrunnstilgang er slått på pga. retningslinjene"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrollert av administratoren"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Alltid"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Bare når appen brukes"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Aldri"</string>
-    <string name="loading" msgid="7811651799620593731">"Laster inn …"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Alle tillatelser"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Andre appfunksjoner"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Forespørsel om tillatelse"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Skjermoverlegg oppdaget"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"For å endre denne tillatelsesinnstilingen må du først slå av skjermoverlegget fra Innstillinger &gt; Apper"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Åpne innstillingene"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Handlinger for å installere og avinstallere er ikke støttet på Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Velg hva du vil gi <xliff:g id="APP_NAME">%1$s</xliff:g> tilgang til"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"<xliff:g id="APP_NAME">%1$s</xliff:g> er oppdatert. Velg hva du vil gi denne appen tilgang til."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Avbryt"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Fortsett"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nye tillatelser"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Gjeldende tillatelser"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Setter opp appen …"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Ukjent"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Nettbrettet ditt har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"TV-en din har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Telefonen din har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonen din og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på telefonen eller tap av data bruk av appen forårsaker."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Nettbrettet ditt og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på nettbrettet eller tap av data bruk av appen forårsaker."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV-en din og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på TV-en eller tap av data bruk av appen forårsaker."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Fortsett"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Innstillinger"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Installerer/avinstallerer wear-apper"</string>
+    <string name="app_name" msgid="7488448184431507488">"Pakkeinstallasjon"</string>
+    <string name="install" msgid="711829760615509273">"Installer"</string>
+    <string name="done" msgid="6632441120016885253">"Ferdig"</string>
+    <string name="cancel" msgid="1018267193425558088">"Avbryt"</string>
+    <string name="installing" msgid="4921993079741206516">"Installerer …"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Installerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+    <string name="install_done" msgid="5987363587661783896">"Appen er installert."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Ønsker du å installere denne appen?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Vil du installere en oppdatering for denne eksisterende appen? Du mister ikke de eksisterende dataene dine."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Vil du installere en oppdatering for denne innebygde appen? Du mister ikke de eksisterende dataene dine."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Appen ble ikke installert."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Pakken er blokkert fra å bli installert."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Appen ble ikke installert fordi pakken er i konflikt med en eksisterende pakke."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Appen ble ikke installert fordi appen ikke er kompatibel med nettbrettet ditt."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Denne appen er ikke kompatibel med TV-en din."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Appen ble ikke installert fordi appen ikke er kompatibel med telefonen din."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Appen ble ikke installert fordi pakken ser ut til å være ugyldig."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på nettbrettet ditt."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på TV-en."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres på telefonen din."</string>
+    <string name="launch" msgid="3952550563999890101">"Åpne"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administratoren din tillater ikke installering av apper som er hentet fra ukjente kilder"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ukjente apper kan ikke installeres av denne brukeren"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Brukeren har ikke tillatelse til å installere apper"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Administrer apper"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Tom for plass"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres. Frigjør plass og prøv på nytt."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Appen ble ikke funnet"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Finner ikke appen i listen over installerte apper."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Ikke tillatt"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Denne brukeren har ikke tillatelse til å utføre denne avinstalleringen."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Feil"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Kunne ikke avinstallere appen."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Avinstaller appen"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Avinstaller oppdateringen"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> er del av følgende app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Vil du avinstallere denne appen?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Vil du avinstallere denne appen for "<b>"alle"</b>" brukere? Appen og tilhørende data blir fjernet fra "<b>"alle"</b>" brukere på enheten."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Ønsker du å avinstallere denne appen for brukeren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Vil du erstatte denne appen med den opprinnelige versjonen? Alle dataene fjernes."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vil du erstatte denne appen med den opprinnelige versjonen? Alle dataene fjernes. Dette påvirker alle som bruker denne enheten – også personer med jobbprofiler."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Avinstalleringer som er i gang"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mislykkede avinstalleringer"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Avinstallerer …"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Avinstallerer <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Avinstalleringen er fullført."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Avinstallerte <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Avinstalleringen mislyktes."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Kunne ikke avinstallere <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Kan ikke avinstallere den aktive appen for enhetsadministrator"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Kan ikke avinstallere den aktive appen for enhetsadministrator for <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Appen er nødvendig for noen brukere eller profiler, og er avinstallert for andre"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Denne appen er nødvendig for profilen din og kan ikke avinstalleres."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Denne appen kreves av enhetsadministratoren din og kan ikke avinstalleres."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Administrer apper for enhetsadministrator"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Administrer brukere"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunne ikke installeres."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Det oppsto et problem med analysen av pakken."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Handlinger for å installere og avinstallere støttes ikke på Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Klargjør appen …"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Ukjent"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Nettbrettet ditt har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"TV-en din har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Telefonen din har ikke tillatelse til å installere ukjente apper fra denne kilden, for å ivareta sikkerheten din."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonen din og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på telefonen eller tap av data som kan skyldes bruk av appen"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Nettbrettet ditt og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på nettbrettet eller tap av data som kan skyldes bruk av appen."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV-en din og de personlige dataene dine er mer sårbare for angrep fra ukjente apper. Når du installerer denne appen, samtykker du i at du er ansvarlig for eventuelle skader på TV-en eller tap av data som kan skyldes bruk av appen."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Fortsett"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Innstillinger"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Installerer/avinstallerer Wear-apper"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index b2dea8f..4d17a3e 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"प्याकेज स्थापनकर्ता"</string>
-    <string name="next" msgid="3057143178373252333">"अर्को"</string>
-    <string name="install" msgid="5896438203900042068">"स्थापना गर्नुहोस्"</string>
-    <string name="done" msgid="3889387558374211719">"भयो"</string>
-    <string name="cancel" msgid="8360346460165114585">"रद्द गर्नुहोस्"</string>
-    <string name="installing" msgid="8613631001631998372">"स्थापित हुँदै…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> स्थापना गर्दै…"</string>
-    <string name="install_done" msgid="3682715442154357097">"अनुप्रयोग स्थापना भयो।"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"के तपाईं यो अनुप्रयोग स्थापन गर्न चाहनु हुन्छ? यसले पहुँच प्राप्त गर्ने छ:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"के तपाईं यस अनुप्रयोगलाई जडान गर्न चाहनु हुन्छ? यसको लागि कुनै विशेष पहुँचको आवश्यकता पर्दैन।"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"के तपाईँसँग अहिले भईरहेको अनुप्रयोगको एक अपडेट लाई स्थापित गर्न चाहानुहुन्छ? तपाईँको अहिलेको डेटा हराउने छैन। अपडेट भएको अनुप्रयोग पहुँच पाउनेछ मा:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"के तपाईं यस पूर्व-निर्मित अनुप्रयोगमा अपडेट स्थापित गर्न चाहनु हुन्छ? तपाईंको रहेको डेटा हराउने छैन। अपडेट गरिएको अनुप्रयोगले पहुँच पाउने छ:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"के तपाईँसँग अहिले भइरहेको अनुप्रयोगको एउटा अपडेटलाई स्थापित गर्न चाहनु हुन्छ? तपाईँको अहिलेको डेटा हराउने छैन। यसलाई कुनै विशेष पहुँचको आवश्यकता छैन।"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"के तपाईं यस जोडिएको अनुप्रयोगको एउटा अपडेटलाई स्थापित गर्न चाहनुहुन्छ? तपाईंको अहिलेको डेटा हराउने छैन। यसलाई कुनै विशेष पहुँचको आवश्यकता छैन।"</string>
-    <string name="install_failed" msgid="6579998651498970899">"अनुप्रयोग स्थापना भएन।"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"यो प्याकेज स्थापना हुनबाट अवरुद्ध भएको थियो।"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"प्याकेजका रूपमा स्थापना नगरिएको अनुप्रयोग विद्यमान प्याकेजसँग मेल खाँदैन।"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"अनुप्रयोगका रूपमा स्थापना नगरिएको अनुप्रयोग तपाईंको ट्याब्लेटसँग मिल्दो छैन।"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"यो अनुप्रयोग तपाईँको TV को लागि उपयुक्त छैन।"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"अनुप्रयोगका रूपमा स्थापना नगरिएको अनुप्रयोग तपाईंको फोनसँग मिल्दो छैन।"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"प्याकेजका रूपमा स्थापना नगरिएको अनुप्रयोग अमान्य जस्तो देखिन्छ।"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईँको ट्याब्लेटमा स्थापित हुन सकेन।"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"तपाईँको TVमा<xliff:g id="APP_NAME">%1$s</xliff:g>स्थापना गर्न सकिएन।"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"तपाईँको फोनमा <xliff:g id="APP_NAME">%1$s</xliff:g> जडान हुन सकेन।"</string>
-    <string name="launch" msgid="4826921505917605463">"खोल्नुहोस्"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"तपाईंका प्रशासकले अज्ञात स्रोतहरूबाट प्राप्त अनुप्रयोगहरूलाई स्थापना गर्ने अनुमति दिनुहुन्न"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"यस प्रयोगकर्ताले अज्ञात अनुप्रयोगहरू स्थापना गर्न सक्नुहुन्न"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"यो प्रयोगकर्तालाई अनुप्रयोगहरूको स्थापना गर्ने अनुमति छैन"</string>
-    <string name="ok" msgid="3468756155452870475">"ठिक छ"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"अनुप्रयोगहरूको व्यवस्थापन गर्नुहोस्"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ठाउँभन्दा बाहिर"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> स्थापन गर्न सकिएन। केही ठाउँ खाली गर्नुहोस् र फेरि कोसिस गर्नुहोस्"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"अनुप्रयोग फेला परेन"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"स्थापना भएको अनुप्रयोगहरू सूचीमा अनुप्रयोग फेला परेको थिएन।"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"अनुमति छैन"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"हालको प्रयोगकर्तालाई यो स्थापना रद्द गर्ने कार्य गर्ने अनुमति छैन।"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"त्रुटि"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"अनुप्रयोगको स्थापना रद्द गर्न सकिएन।"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"अनुप्रयोग अस्थापना गर्नुहोस्"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"परिस्कारहरू अस्थापना गर्नुहोस्"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> निम्न अनुप्रयोगको अंश हो:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"के तपाईं यो अनुप्रयोग अस्थापना गर्न चाहनु हुन्छ?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"के तपाईं यो अनुप्रयोग "<b>"सबै"</b>" प्रयोगकर्ताहरूको लागि स्थापना रद्द गर्न चाहनु हुन्छ? अनुप्रयोग र यसको डेटा "<b>"सबै"</b>" प्रयोगकर्ताहरूबाट उपकरणमा हटाइने छ।"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"के तपाईं प्रयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> को लागि यो अनुप्रयोग स्थापना रद्द गर्न चाहनुहुन्छ?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"यस अनुप्रयोगलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइनेछ।"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"यस अनुप्रयोगलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइनेछ। यसले यस यन्त्रका कार्य प्रोफाइल भएका लगायत सबै प्रयोगकर्ताहरूमा असर पार्छ।"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"चलिरहेका स्थापना रद्द गर्ने कार्यहरू"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"असफल भएका स्थापना रद्द गर्ने कार्यहरू"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"अस्थापना गर्दै..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्दै…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"स्थापना रद्द गर्न सकियो।"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गरियो"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"अस्थापना गर्न असफल"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्ने कार्य असफल भयो।"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"यन्त्रको सक्रिय प्रशासकीय अनुप्रयोगको स्थापना रद्द गर्न मिल्दैन"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> को यन्त्रको सक्रिय प्रशासकीय अनुप्रयोगको स्थापना रद्द गर्न मिल्दैन"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"अन्य प्रयोगकर्ताहरूका लागि यस अनु्प्रयोगको स्थापना रद्द गरे पनि केही प्रयोगकर्ता वा प्रोफाइलहरूलाई यसको आवश्यकता पर्दछ"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"यो अनुप्रयोग तपाईँको प्रोफाइलका लागि आवश्यक छ र यसको स्थापनालाई रद्द गर्न सकिँदैन।"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"यो अनुप्रयोग तपाईँको उपकरण प्रशासकलाई आवश्यक छ र स्थापना रद्द गर्न सकिँदैन।"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"यन्त्रका प्रशासकीय अनुप्रयोगहरूको व्यवस्थापन गर्नुहोस्"</string>
-    <string name="manage_users" msgid="3125018886835668847">"प्रयोगकर्ताहरूलाई व्यवस्थापन गर्नुहोस्"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना रद्द गर्न सकिँदैन।"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"प्याकेजलाई पार्सिङ गर्दा एउटा समस्या आयो।"</string>
-    <string name="newPerms" msgid="6039428254474104210">"नयाँ"</string>
-    <string name="allPerms" msgid="1024385515840703981">"सबै"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"गोपनीयता"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"उपकरण पहुँच"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"यस अपडेटलाई नयाँ अनुमति आवश्यक पर्दैन।"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"अस्वीकार गर्नुहोस्"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"थप जानकारी"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"जे भए पनि अस्वीकार गर्नुहोस्"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> को <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई <xliff:g id="ACTION">%2$s</xliff:g> गर्न अनुमति दिने हो?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई सधैँ <xliff:g id="ACTION">%2$s</xliff:g> गर्ने अनुमति दिने हो?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"अनुप्रयोग प्रयोग गर्दा मात्र"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"सधैँ"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"अस्वीकार गरी फेरि नसोध्नुहोस्"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> अनुमतिहरूलाई असक्षम पारिएको छ"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"सबै अनुमतिहरूलाई असक्षम पारिएको छ"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"कुनै पनि अनुमतिलाई असक्षम पारिएको छैन"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"अनुमति दिनुहोस्"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"अनुप्रयोगहरू"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"अनुप्रयोग अनुमतिहरू"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"फेरि नसोध्नुहोस्"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"कुनै अनुमतिहरू छैनन्"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"अतिरिक्त अनुमतिहरू"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"अनुप्रयोगसम्बन्धी जानकारी खोल्नुहोस्"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> थप</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> थप</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"यो अनुप्रयोग Android को पुरानो संस्करणका लागि डिजाइन गरिएको थियो। अनुमति अस्वीकृत गर्नाले यसले चाहिएको जस्तो कार्य नगर्न सक्छ।"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"एउटा अज्ञात कार्य गर्नुहोस्"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> को <xliff:g id="COUNT_0">%1$d</xliff:g> अनुप्रयोगहरूलाई अनुमति छ"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"प्रणाली देखाउनुहोस्"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"प्रणाली लुकाउनुहोस्"</string>
-    <string name="no_apps" msgid="1965493419005012569">"कुनै अनुप्रयोगहरू छैनन्।"</string>
-    <string name="location_settings" msgid="1774875730854491297">"स्थान सेटिङहरू"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> यो यन्त्रका लागि स्थान सेवाहरूको एउटा प्रदायक हो। स्थान पहुँच स्थान सेटिङहरूबाट परिमार्जन गर्न सकिन्छ।"</string>
-    <string name="system_warning" msgid="7103819124542305179">"तपाईँले यो अनुमति अस्वीकार गर्नुभयो भने तपाईँको यन्त्रका मूल विशेषताहरू अब चाहेअनुसार कार्य नगर्न सक्छ।"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"नीतिद्वारा लागू गरियो"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"नीतिले पृष्ठभूमिको प‍हुँचलाई असक्षम पारेको छ"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"नीतिले पृष्ठभूमिको प‍हुँचलाई सक्षम पारेको छ"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"नीतिले अग्रभूमिको पहुँचलाई सक्षम पारेको छ"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"प्रशासकले नियन्त्रण गर्नुभएको"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"सधैँ"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"अनुप्रयोग प्रयोग गर्दा"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"कहिल्यै होइन"</string>
-    <string name="loading" msgid="7811651799620593731">"लोड हुँदैछ..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"सबै अनुमतिहरू"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"अन्य अनुप्रयोग क्षमताहरू"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"अनुमति अनुरोध"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"स्क्रिन ओभरले पत्ता लाग्यो"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"यो अनुमति सेटिङ परिवर्तन गर्न, तपाईँले पहिला सेटिङ अनुप्रयोगबाट स्क्रिन ओभरले बन्द गर्नु पर्दछ।"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"सेटिङहरू खोल्नुहोस्"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear मा स्थापना/स्थापना रद्द गर्ने कारबाहीहरू समर्थित छैनन्।"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई के माथि पहुँच राख्न दिने भन्ने कुरा छनौट गर्नुहोस्"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; लाई अद्यावधिक गरिएको छ। यस अनुप्रयोगलाई के माथि पहुँच राख्न दिने भन्ने कुरा छनौट गर्नुहोस्।"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"रद्द गर्नुहोस्"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"जारी राख्नुहोस्"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"नयाँ अनुमतिहरू"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"वर्तमान अनुमतिहरू"</string>
-    <string name="message_staging" msgid="6151794817691100003">"अनुप्रयोगलाई तयार पार्दै…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"अज्ञात"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"तपाईंको सुरक्षाको लागि, तपाईंको ट्याब्लेटलाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"तपाईंको सुरक्षाको लागि, तपाईंको TV लाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"तपाईंको सुरक्षाको लागि, तपाईंको फोनलाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"तपाईंको फोन र व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको फोनलाई हुनसक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुनुहुन्छ भन्ने कुरामा सहमत हुनुहुन्छ।"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"तपाईंको ट्याब्लेट र व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको ट्याब्लेटलाई हुनसक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुनुहुन्छ भन्ने कुरामा सहमत हुनुहुन्छ।"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"तपाईंको TV र व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको TV लाई हुनसक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुनुहुन्छ भन्ने कुरामा सहमत हुनुहुन्छ।"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"जारी राख्नुहोस्"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"सेटिङहरू"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"वेयर एपहरूको स्थापना/स्थापना रद्द गर्दै"</string>
+    <string name="app_name" msgid="7488448184431507488">"प्याकेज स्थापनाकर्ता"</string>
+    <string name="install" msgid="711829760615509273">"स्थापना गर्नु…"</string>
+    <string name="done" msgid="6632441120016885253">"सम्पन्न भयो"</string>
+    <string name="cancel" msgid="1018267193425558088">"रद्द गर्नुहोस्"</string>
+    <string name="installing" msgid="4921993079741206516">"स्थापना गर्दै…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> स्थापना गर्दै…"</string>
+    <string name="install_done" msgid="5987363587661783896">"अनुप्रयोग स्थापना गरियो।"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"तपाईं यो अनुप्रयोग स्थापना गर्न चाहनुहुन्छ?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"तपाईं यो पहिलेदेखि नै विद्यमान अनुप्रयोगको साटो यसको अद्यावधिक संस्करण स्थापना गर्न चाहनुहुन्छ? तपाईंको विद्यमान डेटा गुम्ने छैन।"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"तपाईं यो अन्तर्निर्मित अनुप्रयोगको साटो यसको अद्यावधिक संस्करण स्थापना गर्न चाहनुहुन्छ? तपाईंको विद्यमान डेटा गुम्ने छैन।"</string>
+    <string name="install_failed" msgid="5777824004474125469">"अनुप्रयोग स्थापना गरिएन।"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"यो प्याकेज स्थापना गर्ने क्रममा अवरोध गरियो।"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"प्याकेजका रूपमा स्थापना नगरिएको अनुप्रयोग विद्यमान प्याकेजसँग मेल खाँदैन।"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"अनुप्रयोगका रूपमा स्थापना नगरिएको अनुप्रयोग तपाईंको ट्याब्लेटसँग मिल्दो छैन।"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"यो अनुप्रयोग तपाईंको TV सँग मिल्दो छैन।"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"अनुप्रयोगका रूपमा स्थापना नगरिएको अनुप्रयोग तपाईंको फोनसँग मिल्दो छैन।"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"प्याकेजका रूपमा स्थापना नगरिएको अनुप्रयोग अमान्य जस्तो देखिन्छ।"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"तपाईंको ट्याब्लेटमा <xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना गर्न सकिएन।"</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"तपाईंको TV मा <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_user_restriction_dlg_text" msgid="151020786933988344">"यी प्रयोगकर्ता अज्ञात अनुप्रयोगहरू स्थापना गर्न सक्नुहुन्न"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"यो प्रयोगकर्तालाई अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन"</string>
+    <string name="ok" msgid="7871959885003339302">"ठिक छ"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"एपको प्रबन्ध गर्नु…"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"खाली ठाउँ छैन"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> स्थापना गर्न सकिएन। केही ठाउँ खाली गरेर फेरि प्रयास गर्नुहोस्।"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"अनुप्रयोग फेला परेन"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"स्थापना गरिएका अनुप्रयोगहरूको सूचीमा उक्त अनुप्रयोग भेटिएन।"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"अनुमति छैन"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"हालका प्रयोगकर्तालाई यो स्थापना रद्द गर्ने कार्य गर्ने अनुमति छैन।"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"त्रुटि"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"अनुप्रयोगको स्थापना रद्द गर्न सकिएन।"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"अनुप्रयोगको स्थापना रद्द गर्नु…"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"अद्यावधिकको स्थापना रद्द गर्नु…"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> निम्न अनुप्रयोगको अंश हो:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"तपाईं यो अनुप्रयोगको स्थापना रद्द गर्न चाहनुहुन्छ?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"तपाईं "<b>"सबै"</b>" प्रयोगकर्ताका लागि यो अनुप्रयोगको स्थापना रद्द गर्न चाहनुहुन्छ? यन्त्रका "<b>"सबै"</b>" प्रयोगकर्ताहरूबाट उक्त अनुप्रयोग र यसको डेटा हटाइने छ।"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"तपाईं प्रयोगकर्ता <xliff:g id="USERNAME">%1$s</xliff:g> का लागि यो अनुप्रयोगको स्थापना रद्द गर्न चाहनुहुन्छ?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"यस अनुप्रयोगलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइने छ।"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"यस अनुप्रयोगलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइने छ। यसले यस यन्त्रका कार्य प्रोफाइल भएका लगायत सबै प्रयोगकर्ताहरूमा असर पार्छ।"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"चलिरहेका स्थापना रद्द गर्ने कार्यहरू"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"असफल भएका स्थापना रद्द गर्ने कार्यहरू"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"स्थापना रद्द गर्दै…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> को स्थापना रद्द गर्दै…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"स्थापना रद्द गर्ने काम सम्पन्न भयो।"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear मा स्थापना/स्थापना रद्द गर्ने कारबाहीहरू समर्थित छैनन्।"</string>
+    <string name="message_staging" msgid="8032722385658438567">"अनुप्रयोग स्थापना गर्न तयारी गर्दै…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"अज्ञात"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"तपाईंको सुरक्षाका लागि, तपाईंको ट्याब्लेटलाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"तपाईंको सुरक्षाका लागि, तपाईंको TV लाई यस स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"तपाईंको सुरक्षाका लागि, तपाईंको फोनलाई यो स्रोतबाट प्राप्त हुने अज्ञात अनुप्रयोगहरू स्थापना गर्ने अनुमति छैन।"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"तपाईंको फोन तथा व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको फोनमा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"तपाईंको ट्याब्लेट तथा व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको ट्याब्लेटमा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"तपाईंको TV तथा व्यक्तिगत डेटा अज्ञात अनुप्रयोगहरूबाट हुने आक्रमणको चपेटामा पर्ने बढी जोखिममा हुन्छन्। यो अनुप्रयोग स्थापना गरेर तपाईं यसको प्रयोगबाट तपाईंको TV मा हुन सक्ने क्षति वा डेटाको नोक्सानीका लागि स्वयं जिम्मेवार हुने कुरामा सहमत हुनुहुन्छ।"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"जारी राख्नुहोस्"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"सेटिङहरू"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"वेयर एपहरूको स्थापना/स्थापना रद्द गर्दै"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-nl/strings.xml b/packages/PackageInstaller/res/values-nl/strings.xml
index a9e8940..39fb8f0 100644
--- a/packages/PackageInstaller/res/values-nl/strings.xml
+++ b/packages/PackageInstaller/res/values-nl/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Pakket-installatie"</string>
-    <string name="next" msgid="3057143178373252333">"Volgende"</string>
-    <string name="install" msgid="5896438203900042068">"Installeren"</string>
-    <string name="done" msgid="3889387558374211719">"Gereed"</string>
-    <string name="cancel" msgid="8360346460165114585">"Annuleren"</string>
-    <string name="installing" msgid="8613631001631998372">"Installeren..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeren…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App geïnstalleerd."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Wil je deze app installeren? Deze krijgt toegang tot:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Wil je deze app installeren? Hiervoor is geen speciale toegang vereist."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Wil je een update voor deze bestaande app installeren? Je huidige gegevens gaan niet verloren. De bijgewerkte app krijgt toegang tot:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Wil je een update van deze ingebouwde app installeren? Je huidige gegevens gaan niet verloren. De bijgewerkte app krijgt toegang tot:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Wil je een update voor deze bestaande app installeren? Je huidige gegevens gaan niet verloren. Hiervoor is geen speciale toegang vereist."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Wil je een update voor deze ingebouwde app installeren? Je huidige gegevens gaan niet verloren. Hiervoor is geen speciale toegang vereist."</string>
-    <string name="install_failed" msgid="6579998651498970899">"App niet geïnstalleerd."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"De installatie van het pakket is geblokkeerd."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"App die niet is geïnstalleerd als pakket conflicteert met een bestaand pakket."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"App die niet is geïnstalleerd als app is niet geschikt voor je tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Deze app is niet compatibel met je tv."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"App die niet is geïnstalleerd als app is niet geschikt voor je telefoon."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"App die niet is geïnstalleerd als pakket lijkt ongeldig te zijn."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je tv."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je telefoon."</string>
-    <string name="launch" msgid="4826921505917605463">"Openen"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Je beheerder staat de installatie van apps afkomstig van onbekende bronnen niet toe"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Onbekende apps kunnen niet worden geïnstalleerd door deze gebruiker"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Deze gebruiker mag geen apps installeren"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Apps beheren"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Geen ruimte beschikbaar"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd. Maak ruimte vrij en probeer het opnieuw."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App niet gevonden"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"De app is niet gevonden in de lijst met geïnstalleerde apps."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Niet toegestaan"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"De huidige gebruiker mag deze verwijdering niet uitvoeren."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fout"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"App kan niet worden verwijderd."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"App verwijderen"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Update verwijderen"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> maakt deel uit van de volgende app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Wil je deze app verwijderen?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Wil je deze app verwijderen voor "<b>"alle"</b>" gebruikers? Deze app en de gegevens ervan worden verwijderd voor "<b>"alle"</b>" gebruikers van het apparaat."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Wil je deze app verwijderen voor de gebruiker <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Deze app vervangen door de fabrieksversie? Alle gegevens worden verwijderd."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Deze app vervangen door de fabrieksversie? Alle gegevens worden verwijderd. Dit geldt voor alle gebruikers van het apparaat, dus ook voor gebruikers met een werkprofiel."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Actieve verwijderingen"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mislukte verwijderingen"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Verwijderen..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderen…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Verwijdering voltooid."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderd"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Verwijdering mislukt."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kan niet worden verwijderd."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Kan actieve apparaatbeheer-app niet verwijderen"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Kan actieve apparaatbeheer-app niet verwijderen voor <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Deze app is vereist voor sommige gebruikers of profielen en is verwijderd voor andere"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Deze app is vereist voor je profiel en kan niet worden verwijderd."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Deze app is vereist door je apparaatbeheerder en kan niet worden verwijderd."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Apparaatbeheer-apps beheren"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gebruikers beheren"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden verwijderd."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Er is een probleem opgetreden bij het parseren van het pakket."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nieuw"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Alle"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Apparaattoegang"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Voor deze update zijn geen nieuwe machtigingen vereist."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Weigeren"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Meer informatie"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Toch weigeren"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> van <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; het volgende toestaan: <xliff:g id="ACTION">%2$s</xliff:g>."</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; altijd toestaan om <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Alleen als app in gebruik is"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Altijd"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Weigeren en niet meer vragen"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> uitgeschakeld"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"alle rechten uitgeschakeld"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"geen rechten uitgeschakeld"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Toestaan"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"App-machtigingen"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Niet meer vragen"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Geen machtigingen"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Aanvullende machtigingen"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"App-info openen"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Nog <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Nog <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Deze app is ontworpen voor een oudere versie van Android. Als u geen toestemming geeft, kan de app mogelijk niet functioneren zoals is bedoeld."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"een onbekende actie uitvoeren"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Verleend aan <xliff:g id="COUNT_0">%1$d</xliff:g> van <xliff:g id="COUNT_1">%2$d</xliff:g> apps"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Systeem weergeven"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Systeem-apps verbergen"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Geen apps"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Locatie-instellingen"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> is een leverancier van locatieservices voor dit apparaat. Locatietoegang kan worden aangepast via de locatie-instellingen."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Als je deze machtiging weigert, kan het zijn dat basisfuncties van je apparaat niet meer werken zoals bedoeld."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Afgedwongen door beleid"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Toegang op de achtergrond uitgeschakeld op basis van beleid"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Toegang op de achtergrond ingeschakeld op basis van beleid"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Toegang op de voorgrond ingeschakeld op basis van beleid"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Ingesteld door beheerder"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Altijd"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Alleen als app in gebruik is"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nooit"</string>
-    <string name="loading" msgid="7811651799620593731">"Laden…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Alle machtigingen"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Andere app-mogelijkheden"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Toestemmingsverzoek"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Schermoverlay gedetecteerd"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Als u deze instelling voor rechten wilt wijzigen, moet u eerst de schermoverlay uitschakelen via \'Instellingen\' &gt; \'Apps\'"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Instellingen openen"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Acties voor installeren/verwijderen niet ondersteund op Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Kiezen waartoe &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; toegang krijgt"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; is geüpdatet. Kies waartoe je deze app toegang wilt geven."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Annuleren"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Doorgaan"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nieuwe machtigingen"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Huidige machtigingen"</string>
-    <string name="message_staging" msgid="6151794817691100003">"App uitvoeren…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Onbekend"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Uit veiligheidsoverwegingen heeft je tablet geen toestemming om onbekende apps van deze bron te installeren."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Uit veiligheidsoverwegingen heeft je tv geen toestemming om onbekende apps van deze bron te installeren."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Uit veiligheidsoverwegingen heeft je telefoon geen toestemming om onbekende apps van deze bron te installeren."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Je telefoon en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je telefoon of gegevensverlies als gevolg van het gebruik van de app."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Je tablet en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je tablet of gegevensverlies als gevolg van het gebruik van de app."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Je tv en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je tv of gegevensverlies als gevolg van het gebruik van de app."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Doorgaan"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Instellingen"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear-apps installeren/verwijderen"</string>
+    <string name="app_name" msgid="7488448184431507488">"Pakket-installatie"</string>
+    <string name="install" msgid="711829760615509273">"Installeren"</string>
+    <string name="done" msgid="6632441120016885253">"Gereed"</string>
+    <string name="cancel" msgid="1018267193425558088">"Annuleren"</string>
+    <string name="installing" msgid="4921993079741206516">"Installeren…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeren…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App geïnstalleerd."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Wil je deze app installeren?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Wil je een update voor deze bestaande app installeren? Je huidige gegevens gaan niet verloren."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Wil je een update voor deze ingebouwde app installeren? Je huidige gegevens gaan niet verloren."</string>
+    <string name="install_failed" msgid="5777824004474125469">"App niet geïnstalleerd."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"De installatie van het pakket is geblokkeerd."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"App die niet is geïnstalleerd als pakket conflicteert met een bestaand pakket."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"App die niet is geïnstalleerd als app is niet geschikt voor je tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Deze app is niet geschikt voor je tv."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"App die niet is geïnstalleerd als app is niet geschikt voor je telefoon."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"App die niet is geïnstalleerd als pakket blijkt ongeldig te zijn."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je tv."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd op je telefoon."</string>
+    <string name="launch" msgid="3952550563999890101">"Openen"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Je beheerder staat de installatie van apps afkomstig van onbekende bronnen niet toe"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Onbekende apps kunnen niet worden geïnstalleerd door deze gebruiker"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Deze gebruiker mag geen apps installeren"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Apps beheren"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Geen ruimte beschikbaar"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden geïnstalleerd. Maak ruimte vrij en probeer het opnieuw."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App niet gevonden"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"De app is niet gevonden in de lijst met geïnstalleerde apps."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Niet toegestaan"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"De huidige gebruiker mag deze verwijdering niet uitvoeren."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Fout"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"App kan niet worden verwijderd."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"App verwijderen"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Update verwijderen"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> maakt deel uit van de volgende app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Wil je deze app verwijderen?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Wil je deze app verwijderen voor "<b>"alle"</b>" gebruikers? Deze app en de gegevens ervan worden verwijderd voor "<b>"alle"</b>" gebruikers van het apparaat."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Wil je deze app verwijderen voor de gebruiker <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Deze app vervangen door de fabrieksversie? Alle gegevens worden verwijderd."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Deze app vervangen door de fabrieksversie? Alle gegevens worden verwijderd. Dit geldt voor alle gebruikers van het apparaat, dus ook voor gebruikers met een werkprofiel."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Actieve verwijderingen"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mislukte verwijderingen"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Verwijderen…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderen…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Verwijdering voltooid."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> verwijderd"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Verwijdering mislukt."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kan niet worden verwijderd."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Kan actieve apparaatbeheer-app niet verwijderen"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Kan actieve apparaatbeheer-app niet verwijderen voor <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Deze app is vereist voor sommige gebruikers of profielen en is verwijderd voor andere"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Deze app is vereist voor je profiel en kan niet worden verwijderd."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Deze app is vereist door je apparaatbeheerder en kan niet worden verwijderd."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Apparaatbeheer-apps beheren"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gebruikers beheren"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> kan niet worden verwijderd."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Er is een probleem opgetreden bij het parseren van het pakket."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Acties voor installeren/verwijderen niet ondersteund op Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"App uitvoeren…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Onbekend"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Uit veiligheidsoverwegingen heeft je tablet geen toestemming om onbekende apps van deze bron te installeren."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Uit veiligheidsoverwegingen heeft je tv geen toestemming om onbekende apps van deze bron te installeren."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Uit veiligheidsoverwegingen heeft je telefoon geen toestemming om onbekende apps van deze bron te installeren."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Je telefoon en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je telefoon of gegevensverlies als gevolg van het gebruik van de app."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Je tablet en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je tablet of gegevensverlies als gevolg van het gebruik van de app."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Je tv en persoonlijke gegevens zijn kwetsbaarder voor aanvallen door onbekende apps. Als je deze app installeert, ga je ermee akkoord dat je verantwoordelijk bent voor eventuele schade aan je tv of gegevensverlies als gevolg van het gebruik van de app."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Doorgaan"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Instellingen"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear-apps installeren/verwijderen"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-or/strings.xml b/packages/PackageInstaller/res/values-or/strings.xml
deleted file mode 100644
index 8d93c6f..0000000
--- a/packages/PackageInstaller/res/values-or/strings.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  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.
- -->
-
-<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="2738748390251381682">"ପ୍ୟାକେଜ୍‌ ଇନଷ୍ଟଲର୍‍"</string>
-    <string name="next" msgid="3057143178373252333">"ପରବର୍ତ୍ତୀ"</string>
-    <string name="install" msgid="5896438203900042068">"ଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
-    <string name="done" msgid="3889387558374211719">"ହୋଇଗଲା"</string>
-    <string name="cancel" msgid="8360346460165114585">"କ୍ୟାନ୍ସଲ୍‍ କରନ୍ତୁ"</string>
-    <string name="installing" msgid="8613631001631998372">"ଇନଷ୍ଟଲ୍ କରାଯାଉଛି…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଇନଷ୍ଟଲ୍‌ କରାଯାଉଛି…"</string>
-    <string name="install_done" msgid="3682715442154357097">"ଆପ୍‍ ଇନଷ୍ଟଲ୍‌ ହୋଇଗଲା।"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"ଏହି ଆପ୍ଲିକେଶନ୍‍ ଆପଣ ଇନଷ୍ଟଲ୍‍ କରିବେ କି? ଏହିଗୁଡ଼ିକୁ ଏହା ଆକ୍ସେସ୍‌ କରିପାରିବ:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ଏହି ଆପ୍ଲିକେଶନ୍‍ ଆପଣ ଇନଷ୍ଟଲ୍‍ କରିବେ କି? ଏହା କୌଣସି ବିଶେଷ ପ୍ରକାରର ଆକ୍ସେସ୍‌ ଆବଶ୍ୟକ କରେନାହିଁ।"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"ପୂର୍ବରୁ ଥିବା ଏହି ଆପ୍ଲିକେଶନ୍‍ରେ ଆପଣ ଏକ ଅପଡେଟ୍‍ ଇନଷ୍ଟଲ୍‍ କରିବେ କି? ଏଥିରେ ଥିବା ଆପଣଙ୍କ ଡାଟା ନଷ୍ଟ ହେବନାହିଁ। ଅପଡେଟ୍‍ ହେବାପରେ ଆପ୍ଲିକେଶନ୍‍‍ଟି ଏହିଗୁଡ଼ିକୁ ଆକ୍ସେସ୍‌ କରିପାରିବ:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ଏହି ବିଲ୍ଟ-ଇନ୍‌ ଆପ୍ଲିକେଶନ୍‍ରେ ଆପଣ ଏକ ଅପଡେଟ୍‍ ଇନଷ୍ଟଲ୍‍ କରିବେ କି? ଏଥିରେ ଥିବା ଆପଣଙ୍କ ଡାଟା ନଷ୍ଟ ହେବନାହିଁ। ଅପଡେଟ୍‍ ହେବାପରେ ଆପ୍ଲିକେଶନ୍‍‍ଟି ଏହିଗୁଡ଼ିକୁ ଆକ୍ସେସ୍‌ କରିପାରିବ:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ଆପଣ ବର୍ତ୍ତମାନର ଏହି ଆପ୍ଲିକେଶନ୍‍ର ଏକ ଅପଡେଟ୍‌ ଇନଷ୍ଟଲ୍‍ କରିବାକୁ ଚାହୁଁଛନ୍ତି କି? ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ଡାଟା ନଷ୍ଟ ହେବନାହିଁ। ଏଥିରେ କୌଣସି ବିଶେଷ ଆକ୍ସେସ୍‍ର ଆବଶ୍ୟକତା ନାହିଁ।"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ଆପଣ ବର୍ତ୍ତମାନର ଏହି ବିଲ୍ଟ-ଇନ୍‍ ଆପ୍ଲିକେଶନ୍‍ର ଏକ ଅପଡେଟ୍‌ ଇନଷ୍ଟଲ୍‍ କରିବାକୁ ଚାହୁଁଛନ୍ତି କି? ଆପଣଙ୍କ ବର୍ତ୍ତମାନର ଡାଟା ନଷ୍ଟ ହେବନାହିଁ। ଏଥିରେ କୌଣସି ବିଶେଷ ଆକ୍ସେସ୍‍ର ଆବଶ୍ୟକତା ନାହିଁ।"</string>
-    <string name="install_failed" msgid="6579998651498970899">"ଆପ୍‍ ଇନଷ୍ଟଲ୍‌ ହୋଇନାହିଁ।"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ଏହି ପ୍ୟାକେଜ୍‌କୁ ଇନଷ୍ଟଲ୍‍ କରାଯିବାରେ ଅବରୋଧ କରାଯାଇଥିଲା।"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"ପୂର୍ବରୁ ଥିବା ପ୍ୟାକେଜ୍‍ ସହ ଏହି ପ୍ୟାକେଜ୍‌ର ସମସ୍ୟା ଉପୁଯିବାରୁ ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ ହୋଇପାରିଲା ନାହିଁ।"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ଆପ୍‍ ଆପଣଙ୍କ ଟାବଲେଟ୍‌ ସହ କମ୍ପାଟିବଲ୍‍ ନଥିବା ହେତୁ ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ ହୋଇପାରିଲା ନାହିଁ।"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ଏହି ଆପ୍‍, ଆପଣଙ୍କ ଟିଭି ସହ କମ୍ପାଟିବଲ୍‍ ନୁହେଁ।"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ଆପ୍‍ ଆପଣଙ୍କ ଫୋନ୍‌ ସହ କମ୍ପାଟିବଲ୍‍ ନଥିବା ହେତୁ ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ ହୋଇପାରିଲା ନାହିଁ।"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"ପ୍ୟାକେଜ୍‍ ଅମାନ୍ୟ ଥିବା ପରି ଜଣାପଡ଼ିବାରୁ ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ ହୋଇପାରିଲା ନାହିଁ।"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>ଟି ଆପଣଙ୍କ ଟାବଲେଟ୍‍ରେ ଇନଷ୍ଟଲ୍‌ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ ଟିଭିରେ ଇନଷ୍ଟଲ୍‍ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ଟି ଆପଣଙ୍କ ଫୋନ୍‍ରେ ଇନଷ୍ଟଲ୍‌ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
-    <string name="launch" msgid="4826921505917605463">"ଖୋଲନ୍ତୁ"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ଅଜଣା ସୋର୍ସରୁ ଆସିଥିବା ଆପଗୁଡ଼ିକ ଇନଷ୍ଟଲ୍‌ କରିବାକୁ ଆପଣଙ୍କ ଆଡମିନ୍‍ ଅନୁମତି ଦିଅନ୍ତି ନାହିଁ"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ଏହି ୟୁଜରଙ୍କ ଦ୍ୱାରା ଅଜଣା ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ କରାଯାଇ ପାରିବ ନାହିଁ"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ଏହି ୟୁଜର୍‌ ଜଣକ ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ କରିପାରିବେ ନାହିଁ"</string>
-    <string name="ok" msgid="3468756155452870475">"ଠିକ୍‍ ଅଛି"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"ଆପ୍‌ଗୁଡ଼ିକର ପରିଚାଳନା କରନ୍ତୁ"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ଆଉ ସ୍ଥାନ ନାହିଁ"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଇନଷ୍ଟଲ୍‌ କରାଯାଇପାରିଲା ନାହିଁ। କିଛି ସ୍ଥାନ ଖାଲିକରି ପୁଣିଥରେ ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ଆପ୍‍ ମିଳିଲା ନାହିଁ"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ଇନଷ୍ଟଲ୍‌ କରାଯାଇଥିବା ଆପ୍‍ ତାଲିକାରେ ଆପ୍‍ଟି ମିଳିଲା ନାହିଁ।"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ଅନୁମତି ଦିଆଯାଇନାହିଁ"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ଏହି ଅନଇନଷ୍ଟଲେଶନ୍‍ କରିବାକୁ ବର୍ତ୍ତମାନର ୟୁଜରଙ୍କୁ ଅନୁମତି ଦିଆଯାଇନାହିଁ।"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"ତ୍ରୁଟି"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ଆପ୍‍ ଅନଇନଷ୍ଟଲ୍‍ କରାହେଲା ନାହିଁ"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ଆପ୍‍ ଅନଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"ଅପଡେଟ୍‍ ଅନଇନଷ୍ଟଲ୍‌ କରନ୍ତୁ"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ହେଉଛି ନିମ୍ନ ଆପ୍‍ର ଏକ ଅଂଶ।"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"ଆପଣ ଏହି ଆପ୍‍ ଅନଇନଷ୍ଟଲ୍‌ କରିବାକୁ ଚାହାଁନ୍ତି କି?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ଆପଣ "<b>"ସମସ୍ତ"</b>" ୟୁଜର୍‌ଙ୍କ ପାଇଁ ଏହି ଆପ୍‌କୁ ଅନଷ୍ଟଲ୍‍ କରିବାକୁ ଚାହୁଁଛନ୍ତି କି? ଡିଭାଇସ୍‌ରେ ଥିବା "<b>"ସମସ୍ତ"</b>" ୟୁଜର୍‌ ଆପ୍ଲିକେଶନ୍‍ ଏବଂ ତାହାର ଡାଟା ବାହାର କରିଦିଆଯିବ।"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"ୟୁଜର୍‌ <xliff:g id="USERNAME">%1$s</xliff:g>ଙ୍କ ପାଇଁ ଆପଣ ଏହି ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ କରିବେ କି?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ଏହି ଆପ୍‍ ଫ୍ୟାକ୍ଟୋରୀ ଭର୍ସନ୍‍‍ ସହ ବଦଳାଇବେ? ସମସ୍ତ ଡାଟା କାଢ଼ିଦିଆଯିବ।"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ଏହି ଆପ୍‍ ଫ୍ୟାକ୍ଟୋରୀ ଭର୍ସନ୍‍‍ ସହ ବଦଳାଇବେ? ସମସ୍ତ ଡାଟା ବାହାର କରିଦିଆଯିବ। ୱର୍କ ପ୍ରୋଫାଇଲ୍‍ ଥିବା ସମେତ, ଏହାଦ୍ୱାରା ଡିଭାଇସରେ ଥିବା ସମସ୍ତ ୟୁଜର୍‌ ପ୍ରଭାବିତ ହେବେ।"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ଅନଇନଷ୍ଟଲ୍‌ ଚାଲୁଛି"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ଅନଇନଷ୍ଟଲ୍‌ କରାଯାଇ ପାରିଲା ନାହିଁ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"ଅନଇନଷ୍ଟଲ୍‌ କରାଯାଉଛି…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍‍ କରାଯାଉଛି…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"ଅନଇନଷ୍ଟଲ୍‌ ହୋଇଗଲା।"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍‌ କରାଗଲା"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"ଅନଇନଷ୍ଟଲ୍‌ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍‍ କରିବା ସଫଳ ହେଲାନାହିଁ।"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ସକ୍ରିୟ ଡିଭାଇସ୍‍ ଆପ୍‍ ଅନଇନଷ୍ଟଲ୍‌ କରିପାରିବ ନାହିଁ"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>ଙ୍କ ପାଇଁ ସକ୍ରିୟ ଡିଭାଇସ୍‍ ଆଡମିନ୍‍ ଆପ୍‍ ଅନଇନଷ୍ଟଲ୍‍ କରାଯାଇ ପାରିବ ନାହିଁ"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"କିଛି ୟୁଜର୍‌ କିମ୍ବା ପ୍ରୋଫାଇଲ୍‍ ପାଇଁ ଏହି ଆପ୍‍ ଆବଶ୍ୟକ ଏବଂ ଅନ୍ୟ ସମସ୍ତଙ୍କ ପାଇଁ ଅନଇନଷ୍ଟଲ୍‍ କରାଯାଇଥିଲା"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ଏହି ଆପ୍‍ ଆପଣଙ୍କ ପ୍ରୋଫାଇଲ୍‍ ପାଇଁ ଆବଶ୍ୟକ ଅଟେ ଏବଂ ଅନଇନଷ୍ଟଲ୍‍ କରାଯାଇପାରିବ ନାହିଁ।"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ଆପଣଙ୍କ ଡିଭାଇସ୍‍ ଆଡମିନିଷ୍ଟ୍ରେଟର୍‍ ଏହି ଆପ୍‍ ଆବଶ୍ୟକ କରନ୍ତୁ ଏବଂ ଏହାକୁ ଅନ୍‍ଇନଷ୍ଟଲ୍‍ କରାଯାଇପାରିବ ନାହିଁ।"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"ଡିଭାଇସ୍‌ ଆଡମିନ୍‌ ଆପ୍‌ ପରିଚାଳନା କରନ୍ତୁ"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ୟୁଜର୍‌ଙ୍କୁ ପରିଚାଳନା କରନ୍ତୁ"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଅନଇନଷ୍ଟଲ୍‍ କରାଯାଇପାରିଲା ନାହିଁ।"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ଏହି ପ୍ୟାକେଜ୍‍ ପାର୍ସ କରିବାରେ ସମସ୍ୟା ଥିଲା।"</string>
-    <string name="newPerms" msgid="6039428254474104210">"ନୂଆ"</string>
-    <string name="allPerms" msgid="1024385515840703981">"ସମସ୍ତ"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"ଗୋପନୀୟତା"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ଡିଭାଇସ୍ ଆକ୍ସେସ୍‌"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ଏହି ଅପଡେଟ୍‍ କୌଣସି ନୂଆ ଅନୁମତି ଆବଶ୍ୟକ କରେନାହିଁ"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ପ୍ରତ୍ୟାଖ୍ୟାନ"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ଅଧିକ ସୂଚନା"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ତଥାପି ଖାରଜ କରନ୍ତୁ"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>ଟିରୁ <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>ଟି"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;କୁ <xliff:g id="ACTION">%2$s</xliff:g> ପାଇଁ ଅନୁମତି ଦେବେ କି?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ସବୁବେଳେ <xliff:g id="ACTION">%2$s</xliff:g>କୁ ଅନୁମତି ଦେବେ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"କେବଳ ଆପ୍‍ ବ୍ୟବହାର କରୁଥିବା ସମୟରେ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ସର୍ବଦା"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ମନାକରନ୍ତୁ ଏବଂ ପୁଣି ପଚାରନ୍ତୁ ନାହିଁ"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g>ଟି ଅକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"ସମସ୍ତ ଅକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"କିଛିବି ଅକ୍ଷମ କରାଯାଇନାହିଁ"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ଅନୁମତି ଦିଅନ୍ତୁ"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ଆପ୍‌‍"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ଆପ୍‌ ଅନୁମତି"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"ପୁଣି ପଚାରନ୍ତୁ ନାହିଁ"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"କୌଣସି ଅନୁମତି ନାହିଁ"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"ଅତିରିକ୍ତ ଅନୁମତି"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ଆପ୍‌ର ତଥ୍ୟ ଖୋଲନ୍ତୁ"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ଟି ଅଧିକ</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>ଟି ଅଧିକ</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ଏହି ଆପ୍‍ Androidର ଏକ ପୁରୁଣା ସଂସ୍କରଣ ପାଇଁ ଡିଜାଇନ୍‍ କରାଯାଇଥିଲା। ଅନୁମତି ପ୍ରତ୍ୟାଖ୍ୟାନ କରିବା ଦ୍ୱାରା ଏହା ଠିକ୍‍ ଭାବେ ଆଉ କାମ ନକରିପାରେ।"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ଏକ ଅଜଣା କାମ କରେ"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>ଟି ଆପରୁ <xliff:g id="COUNT_0">%1$d</xliff:g>ଟିକୁ ଅନୁମତି ଦିଆଯାଇଛି"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"ସିଷ୍ଟମ୍‌କୁ ଦେଖାନ୍ତୁ"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"ସିଷ୍ଟମ୍‌କୁ ଲୁଚାନ୍ତୁ"</string>
-    <string name="no_apps" msgid="1965493419005012569">"କୌଣସି ଆପ୍‌ ନାହିଁ"</string>
-    <string name="location_settings" msgid="1774875730854491297">"ଲୋକେଶନ୍‌ ସେଟିଙ୍ଗ"</string>
-    <string name="location_warning" msgid="8778701356292735971">"ଏହି ଡିଭାଇସ୍‍ ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଲୋକେଶନ୍‍ ସେବା ପ୍ରଦାନ କରେ। ଲୋକେଶନ୍‍ ସେଟିଙ୍ଗରୁ ଲୋକେଶନ୍‍ ଆକ୍ସେସ୍‍ ସଂଶୋଧନ କରାଯାଇପାରିବ।"</string>
-    <string name="system_warning" msgid="7103819124542305179">"ଏହି ଅନୁମତିକୁ ଯଦି ଆପଣ ପ୍ରତ୍ୟାଖ୍ୟାନ କରନ୍ତି, ଆପଣଙ୍କ ଡିଭାଇସ୍‌ର ସାଧାରଣ ସୁବିଧାଗୁଡ଼ିକ ଆଉ କାମ ନକରିପାରେ।"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ପଲିସୀ ଦ୍ୱାରା ଲାଗୁ"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ନିତୀ ଅନୁସାରେ ବ୍ୟାକ୍‌ଗ୍ରାଉଣ୍ଡ ଆକ୍ସେସ୍‌ ଅକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ନିତୀ ଅନୁସାରେ ପୃଷ୍ଠପଟ ଆକ୍ସେସ୍‌ ସକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ନିତୀ ଅନୁସାରେ ସମ୍ମୁଖଭାଗ ଆକ୍ସେସ୍‌ ସକ୍ଷମ କରାଯାଇଛି"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ଆଡ୍‌ମିନ୍‌ ଦ୍ୱାରା ନିୟନ୍ତ୍ରିତ"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ସର୍ବଦା"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"କେବଳ ଆପ୍‍ ବ୍ୟବହାର କରୁଥିବା ସମୟରେ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"କେବେ ନୁହେଁ"</string>
-    <string name="loading" msgid="7811651799620593731">"ଲୋଡ୍ କରାଯାଉଛି…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"ସମସ୍ତ ଅନୁମତି"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"ଅନ୍ୟାନ୍ୟ ଆପ୍‍ ଦକ୍ଷତା"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"ଅନୁମତି ଅନୁରୋଧ"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"ସ୍କ୍ରୀନ୍‍ ଓଭର୍‌ଲେ ଚିହ୍ନଟ ହୋଇଛି"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ଏହି ଅନୁମତି ସେଟିଙ୍ଗ ବଦଳାଇବାକୁ, ପ୍ରଥମେ ଆପଣ ସେଟିଙ୍ଗ ଓ ଆପ୍‌ରୁ ସ୍କ୍ରୀନ୍‍ ଅଫ୍‍ କରନ୍ତୁ"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android ୱିୟର୍‍"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wearରେ ଇନଷ୍ଟଲ୍‍/ଅନଇନଷ୍ଟଲ୍‍ କାର୍ଯ୍ୟ ସପୋର୍ଟ କରେ ନାହିଁ।"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ଆକ୍ସେସ୍‍ କରିବା ପାଇଁ କ\'ଣ କ\'ଣ ଅନୁମତି ଦିଆଯିବ, ତାହା ବାଛନ୍ତୁ"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ଅପଡେଟ୍‍ କରାଯାଇଛି। ଏହି ଆପ୍‍ କ\'ଣ କ\'ଣ ଆକ୍ସେସ୍‍ କରିପାରିବ, ତାହା ବାଛନ୍ତୁ।"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"କ୍ୟାନ୍ସଲ୍‍ କରନ୍ତୁ"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"ଜାରି ରଖନ୍ତୁ"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"ନୂଆ ଅନୁମତି"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"ବର୍ତ୍ତମାନର ଅନୁମତି"</string>
-    <string name="message_staging" msgid="6151794817691100003">"ଆପ୍‍ ପର୍ଯ୍ୟାୟଭୁକ୍ତ କରାଯାଉଛି…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"ଅଜଣା"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ଆପଣଙ୍କ ସୁରକ୍ଷା ପାଇଁ, ଆପଣଙ୍କ ଟାବଲେଟକୁ ଏହି ସୋର୍ସରୁ ଆସିଥିବା ଅଜଣା ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ।"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ଆପଣଙ୍କ ସୁରକ୍ଷା ପାଇଁ, ଆପଣଙ୍କ ଟିଭିକୁ ଏହି ସୋର୍ସରୁ ଆସିଥିବା ଅଜଣା ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ।"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ଆପଣଙ୍କ ସୁରକ୍ଷା ପାଇଁ, ଆପଣଙ୍କ ଫୋନକୁ ଏହି ସୋର୍ସରୁ ଆସିଥିବା ଅଜଣା ଆପ୍‍ ଇନଷ୍ଟଲ୍‍ କରିବାକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ।"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ଅଜଣା ଆପ୍‌ ଦ୍ୱାରା ଆପଣଙ୍କ ଫୋନ୍‍ ଏବଂ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ନଷ୍ଟ କରାଯାଇ ପାରିବାର ସମ୍ଭାବନା ବହୁତ ଅଧିକ। ଏହି ଆପଜୁ ଇନଷ୍ଟଲ୍‌ କରିବାର ଅର୍ଥ, ଆପଣଙ୍କ ଫୋନରେ ଘଟିବା କୌଣସି ପ୍ରକାର କ୍ଷତି କିମ୍ବା ସେଗୁଡ଼ିକର ବ୍ୟବହାରରୁ ହେବା କୌଣସି ପ୍ରକାର ଡାଟାର ହାନୀ ପାଇଁ ଆପଣ ଦାୟୀ ରହିବାକୁ ରାଜି ହୁଅନ୍ତି।"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ଅଜଣା ଆପ୍‌ ଦ୍ୱାରା ଆପଣଙ୍କ ଟାବଲେଟ୍‍ ଏବଂ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ନଷ୍ଟ କରାଯାଇ ପାରିବାର ସମ୍ଭାବନା ବହୁତ ଅଧିକ। ଏହି ଆପଜୁ ଇନଷ୍ଟଲ୍‌ କରିବାର ଅର୍ଥ, ଆପଣଙ୍କ ଟାବଲେଟରେ ଘଟିବା କୌଣସି ପ୍ରକାର କ୍ଷତି କିମ୍ବା ସେଗୁଡ଼ିକର ବ୍ୟବହାରରୁ ହେବା କୌଣସି ପ୍ରକାର ଡାଟାର ହାନୀ ପାଇଁ ଆପଣ ଦାୟୀ ରହିବାକୁ ରାଜି ହୁଅନ୍ତି।"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ଅଜଣା ଆପ୍‌ ଦ୍ୱାରା ଆପଣଙ୍କ ଟିଭି ଏବଂ ବ୍ୟକ୍ତିଗତ ଡାଟାକୁ ନଷ୍ଟ କରାଯାଇ ପାରିବାର ସମ୍ଭାବନା ବହୁତ ଅଧିକ। ଏହି ଆପଜୁ ଇନଷ୍ଟଲ୍‌ କରିବାର ଅର୍ଥ, ଆପଣଙ୍କ ଟିଭିରେ ଘଟିବା କୌଣସି ପ୍ରକାର କ୍ଷତି କିମ୍ବା ସେଗୁଡ଼ିକର ବ୍ୟବହାରରୁ ହେବା କୌଣସି ପ୍ରକାର ଡାଟାର ହାନୀ ପାଇଁ ଆପଣ ଦାୟୀ ରହିବାକୁ ରାଜି ହୁଅନ୍ତି।"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ଜାରି ରଖନ୍ତୁ"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ସେଟିଙ୍ଗ"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"ୱେର୍‍ ଆପ୍‍ ଇନଷ୍ଟଲ୍‌/ଅନଇନଷ୍ଟଲ୍‍ କରାଯାଉଛି"</string>
-</resources>
diff --git a/packages/PackageInstaller/res/values-pa/strings.xml b/packages/PackageInstaller/res/values-pa/strings.xml
index b364c78..6a1d7eb 100644
--- a/packages/PackageInstaller/res/values-pa/strings.xml
+++ b/packages/PackageInstaller/res/values-pa/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"ਪੈਕੇਜ ਸਥਾਪਨਾਕਾਰ"</string>
-    <string name="next" msgid="3057143178373252333">"ਅੱਗੇ"</string>
-    <string name="install" msgid="5896438203900042068">"ਸਥਾਪਤ ਕਰੋ"</string>
-    <string name="done" msgid="3889387558374211719">"ਹੋ ਗਿਆ"</string>
-    <string name="cancel" msgid="8360346460165114585">"ਰੱਦ ਕਰੋ"</string>
-    <string name="installing" msgid="8613631001631998372">"ਇੰਸਟੌਲ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="install_done" msgid="3682715442154357097">"ਐਪ ਇੰਸਟੌਲ ਕੀਤਾ।"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"ਕੀ ਤੁਸੀਂ ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਇਹ ਇਸ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੇਗਾ:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਇਸ ਲਈ ਕਿਸੇ ਖਾਸ ਪਹੁੰਚ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"ਕੀ ਤੁਸੀਂ ਇਸ ਮੌਜੂਦਾ ਐਪਲੀਕੇਸ਼ਨ ਤੇ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਕੀਤਾ ਜਾਏਗਾ। ਅੱਪਡੇਟ ਕੀਤੀ ਐਪਲੀਕੇਸ਼ਨ ਇਸ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੇਗੀ:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ਕੀ ਤੁਸੀਂ ਇਸ ਬਿਲਟ-ਇਨ ਐਪਲੀਕੇਸ਼ਨ ਤੇ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਕੀਤਾ ਜਾਏਗਾ। ਅੱਪਡੇਟ ਕੀਤੀ ਐਪਲੀਕੇਸ਼ਨ ਇਸ ਤੱਕ ਪਹੁੰਚ ਪ੍ਰਾਪਤ ਕਰੇਗੀ:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"ਕੀ ਤੁਸੀਂ ਇਸ ਮੌਜੂਦਾ ਐਪਲੀਕੇਸ਼ਨ ਵਿੱਚ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਨਹੀਂ ਹੋਵੇਗਾ। ਇਸ ਲਈ ਕਿਸੇ ਖਾਸ ਪਹੁੰਚ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"ਕੀ ਤੁਸੀਂ ਇਸ ਬਿਲਟ-ਇਨ ਐਪਲੀਕੇਸ਼ਨ ਵਿੱਚ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਨਹੀਂ ਹੋਵੇਗਾ। ਇਸ ਲਈ ਕਿਸੇ ਖਾਸ ਪਹੁੰਚ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
-    <string name="install_failed" msgid="6579998651498970899">"ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ।"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ਪੈਕੇਜ ਨੂੰ ਸਥਾਪਿਤ ਹੋਣ ਤੋਂ ਬਲੌਕ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"ਪੈਕੇਜ ਦੇ ਇੱਕ ਮੌਜੂਦਾ ਪੈਕੇਜ ਨਾਲ ਵਿਵਾਦ ਹੋਣ ਕਰਕੇ ਐਪ ਦੀ ਸਥਾਪਨਾ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ਐਪ ਦੇ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਦੇ ਅਨੁਰੂਪ ਨਾ ਹੋਣ ਕਰਕੇ ਐਪ ਦੀ ਸਥਾਪਨਾ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ ਦੇ ਅਨੁਕੂਲ ਨਹੀਂ ਹੈ।"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ਐਪ ਦੇ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੇ ਅਨੁਰੂਪ ਨਾ ਹੋਣ ਕਰਕੇ ਐਪ ਦੀ ਸਥਾਪਨਾ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"ਪੈਕੇਜ ਦੇ ਅਵੈਧ ਪ੍ਰਤੀਤ ਹੋਣ ਕਰਕੇ ਐਪ ਦੀ ਸਥਾਪਨਾ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੀ ਟੈਬਲੈੱਟ ਤੇ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੇ TV ਤੇ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੇ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
-    <string name="launch" msgid="4826921505917605463">"ਖੋਲ੍ਹੋ"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ਤੁਹਾਡਾ ਪ੍ਰਸ਼ਾਸਕ ਅਗਿਆਤ ਸਰੋਤਾਂ ਤੋਂ ਪ੍ਰਾਪਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੰਦਾ"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ਇਸ ਵਰਤੋਂਕਾਰ ਵੱਲੋਂ ਅਗਿਆਤ ਐਪਾਂ ਨੂੰ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
-    <string name="ok" msgid="3468756155452870475">"ਠੀਕ"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"ਐਪਸ ਵਿਵਸਥਿਤ ਕਰੋ"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ਖਾਲੀ ਸਪੇਸ"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਕੁਝ ਸਪੇਸ ਖਾਲੀ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ਐਪ ਨਹੀਂ ਮਿਲਿਆ"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ਐਪ ਇੰਸਟੌਲ ਕੀਤੇ ਐਪਸ ਦੀ ਸੂਚੀ ਵਿੱਚ ਨਹੀਂ ਮਿਲਿਆ ਸੀ।"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ਇਜਾਜ਼ਤ ਨਹੀਂ"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ਮੌਜੂਦਾ ਵਰਤੋਂਕਾਰ ਨੂੰ ਇਹ ਅਣਸਥਾਪਨਾ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ।"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"ਗੜਬੜ"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ਐਪ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ।"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ਐਪ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"ਅੱਪਡੇਟ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ਇਸ ਐਪ ਦਾ ਭਾਗ ਹੈ:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ "<b>"ਸਾਰੇ"</b>" ਵਰਤੋਂਕਾਰਾਂ ਲਈ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਐਪਲੀਕੇਸ਼ਨ ਅਤੇ ਇਸਦਾ ਡਾਟਾ ਡੀਵਾਈਸ ਤੇ "<b>"ਸਾਰੇ"</b>" ਵਰਤੋਂਕਾਰਾਂ ਵੱਲੋਂ ਹਟਾ ਦਿੱਤਾ ਜਾਏਗਾ।"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"ਕੀ ਤੁਸੀਂ ਵਰਤੋਂਕਾਰ <xliff:g id="USERNAME">%1$s</xliff:g> ਲਈ ਇਸ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ਕੀ ਇਸ ਐਪ ਨੂੰ ਫੈਕਟਰੀ ਸੰਸਕਰਣ ਨਾਲ ਬਦਲਣਾ ਹੈ? ਸਾਰਾ  ਡਾਟਾ  ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ਕੀ ਇਸ ਐਪ ਨੂੰ ਫੈਕਟਰੀ ਵਰਜਨ ਨਾਲ ਬਦਲਣਾ ਹੈ? ਸਾਰਾ ਡਾਟਾ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ। ਇਹ ਇਸ ਡੀਵਾਈਸ ਦੇ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰੇਗਾ, ਜਿਸ ਵਿੱਚ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਾਲੇ ਵਰਤੋਂਕਾਰ ਵੀ ਸ਼ਾਮਲ ਹਨ।"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"ਚੱਲ ਰਹੀਆਂ ਅਣਸਥਾਪਨਾਵਾਂ"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ਅਸਫਲ ਅਣਸਥਾਪਨਾਵਾਂ"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"ਅਣਇੰਸਟੌਲ ਕਰ  ਰਿਹਾ ਹੈ…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"ਅਣਸਥਾਪਨਾ ਪੂਰੀ ਹੋਈ।"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"ਅਣਸਥਾਪਨਾ ਅਸਫਲ।"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ।"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ਕਿਰਿਆਸ਼ੀਲ ਡੀਵਾਈਸ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> ਲਈ ਕਿਰਿਆਸ਼ੀਲ ਡੀਵਾਈਸ ਪ੍ਰਸ਼ਾਸਕ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ਇਹ ਐਪ ਕੁਝ ਵਰਤੋਂਕਾਰਾਂ ਜਾਂ ਪ੍ਰੋਫਾਈਲਾਂ ਲਈ ਲੋੜੀਂਦੀ ਹੈ ਅਤੇ ਹੋਰਾਂ ਲਈ ਅਣਸਥਾਪਤ ਕੀਤੀ ਗਈ ਸੀ"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ਇਹ ਐਪ ਤੁਹਾਡੀ ਪ੍ਰੋਫਾਈਲ ਲਈ ਲੋੜੀਂਦੀ ਹੈ ਅਤੇ ਇਸ ਨੂੰ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਡੀਵਾਈਸ ਪ੍ਰਬੰਧਕ ਵੱਲੋਂ ਲੋੜੀਂਦੀ ਹੈ ਅਤੇ ਇਸਨੂੰ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"ਡੀਵਾਈਸ ਪ੍ਰਸ਼ਾਸਕ ਐਪਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
-    <string name="manage_users" msgid="3125018886835668847">"ਵਰਤੋਂਕਾਰਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਅਣਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ਪੈਕੇਜ ਨੂੰ ਪਾਰਸ ਕਰਨ ਵਿੱਚ ਇੱਕ ਸਮੱਸਿਆ ਸੀ।"</string>
-    <string name="newPerms" msgid="6039428254474104210">"ਨਵਾਂ"</string>
-    <string name="allPerms" msgid="1024385515840703981">"ਸਭ"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"ਪ੍ਰਾਈਵੇਸੀ"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"ਡੀਵਾਈਸ ਪਹੁੰਚ"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ਇਸ ਅੱਪਡੇਟ ਲਈ ਕਿਸੇ ਨਵੀਆਂ ਅਨੁਮਤੀਆਂ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ਅਸਵੀਕਾਰ ਕਰੋ"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ਹੋਰ ਜਾਣਕਾਰੀ"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ਫੇਰ ਵੀ ਅਸਵੀਕਾਰ ਕਰੋ"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> ਦਾ <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"ਕੀ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ <xliff:g id="ACTION">%2$s</xliff:g> ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"ਹਮੇਸ਼ਾਂ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ <xliff:g id="ACTION">%2$s</xliff:g> ਕਰਨ ਦਿਓ?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ਸਿਰਫ਼ ਐਪ ਵਰਤਣ ਵੇਲੇ"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ਹਮੇਸ਼ਾਂ"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ਅਸਵੀਕਾਰ ਕਰੋ ਅਤੇ ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"ਸਭ ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ਕਿਸੇ ਨੂੰ ਵੀ ਅਯੋਗ ਨਹੀਂ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ਆਗਿਆ ਦਿਓ"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ਐਪਾਂ"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ਐਪ ਇਜਾਜ਼ਤਾਂ"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"ਕੋਈ ਇਜਾਜ਼ਤਾਂ ਨਹੀਂ ਹਨ"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"ਵਧੀਕ ਇਜਾਜ਼ਤਾਂ"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ਐਪ ਜਾਣਕਾਰੀ ਖੋਲ੍ਹੋ"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਹੋਰ</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਹੋਰ</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ਇਹ ਐਪ Android ਦੇ ਕਿਸੇ ਪੁਰਾਣੇ ਸੰਸਕਰਣ ਲਈ ਬਣਾਈ ਗਈ ਸੀ। ਅਨੁਮਤੀ ਨੂੰ ਇਨਕਾਰ ਕਰਨਾ ਇਸਦੇ ਉਦੇਸ਼ਿਤ ਫੰਕਸ਼ਨ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰ ਸਕਦਾ ਹੈ।"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ਕੋਈ ਅਗਿਆਤ ਕਾਰਵਾਈ ਕਰੋ"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> ਵਿੱਚੋਂ <xliff:g id="COUNT_0">%1$d</xliff:g> ਐਪਾਂ ਨੂੰ ਆਗਿਆ ਦਿੱਤੀ"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"ਸਿਸਟਮ ਦਿਖਾਓ"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"ਸਿਸਟਮ ਲੁਕਾਓ"</string>
-    <string name="no_apps" msgid="1965493419005012569">"ਕੋਈ ਐਪਾਂ ਨਹੀਂ"</string>
-    <string name="location_settings" msgid="1774875730854491297">"ਟਿਕਾਣਾ ਸੈਟਿੰਗਾਂ"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਇਸ ਡੀਵਾਈਸ ਲਈ ਟਿਕਾਣਾ ਸੇਵਾਵਾਂ ਦਾ ਇੱਕ ਪ੍ਰਦਾਤਾ ਹੈ। ਟਿਕਾਣਾ ਪਹੁੰਚ ਨੂੰ ਟਿਕਾਣਾ ਸੈਟਿੰਗਾਂ ਤੋਂ ਸੰਸ਼ੋਧਿਤ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।"</string>
-    <string name="system_warning" msgid="7103819124542305179">"ਜੇਕਰ ਤੁਸੀਂ ਇਸ ਇਜਾਜ਼ਤ ਨੂੰ ਅਸਵੀਕਾਰ ਕਰਦੇ ਹੋ, ਤਾਂ ਤੁੁਹਾਡੇ ਡੀਵਾਈਸ ਦੀਆਂ ਮੂੂਲ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਆਪਣੇ ਫੰਕਸ਼ਨ ਮੁਤਾਬਕ ਕੰਮ ਨਹੀਂ ਵੀ ਕਰ ਸਕਦੀਆਂ।"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ਨੀਤੀ ਮੁਤਾਬਕ ਲਾਗੂ ਕੀਤਾ"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ਨੀਤੀ ਵੱਲੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"ਨੀਤੀ ਵੱਲੋਂ ਬੈਕਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"ਨੀਤੀ ਵੱਲੋਂ ਫੋਰਗ੍ਰਾਊਂਡ ਪਹੁੰਚ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਕੰਟਰੋਲ ਕੀਤੀ ਗਈ"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ਹਮੇਸ਼ਾਂ"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"ਸਿਰਫ਼ ਐਪ ਵਰਤਣ ਦੌਰਾਨ"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ਕਦੇ ਵੀ ਨਹੀਂ"</string>
-    <string name="loading" msgid="7811651799620593731">"ਲੋਡ ਕਰ ਰਿਹਾ ਹੈ…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"ਸਾਰੀਆਂ ਅਨੁਮਤੀਆਂ"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"ਹੋਰ ਐਪ ਸਮਰੱਥਤਾਵਾਂ"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"ਇਜਾਜ਼ਤ ਬੇਨਤੀ"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"ਸਕਰੀਨ ਓਵਰਲੇਅ ਲੱਭ ਗਿਆ"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ਇਸ ਇਜ਼ਾਜਤ ਸੈਟਿੰਗ ਨੂੰ ਬਦਲਣ ਲਈ; ਤੁਹਾਨੂੰ ਪਹਿਲਾਂ ਸੈਟਿੰਗਾਂ ਅਤੇ ਐਪਾਂ ਤੋਂ ਸਕ੍ਰੀਨ ਓਵਰਲੇਅ ਬੰਦ ਕਰਨਾ ਪਵੇਗਾ"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ਵੀਅਰ \'ਤੇ ਸਥਾਪਤ/ਅਣਸਥਾਪਤ ਕਾਰਵਾਈਆਂ ਸਮਰਥਿਤ ਨਹੀਂ ਹਨ।"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"ਇਹ ਚੁਣੋ ਕਿ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਕਿਸ \'ਤੇ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ਨੂੰ ਅੱਪਡੇਟ ਕੀਤਾ ਜਾ ਚੁੱਕਿਆ ਹੈ। ਇਹ ਚੁਣੋ ਕਿ ਇਸ ਐਪ ਨੂੰ ਕਿਸ \'ਤੇ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ।"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"ਰੱਦ ਕਰੋ"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"ਜਾਰੀ ਰੱਖੋ"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"ਨਵੀਆਂ ਇਜਾਜ਼ਤਾਂ"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"ਵਰਤਮਾਨ ਇਜਾਜ਼ਤਾਂ"</string>
-    <string name="message_staging" msgid="6151794817691100003">"ਐਪ ਨੂੰ ਪੜਾਅਬੱਧ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"ਅਗਿਆਤ"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਟੀਵੀ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਫ਼ੋਨ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ਿੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਕਮਜ਼ੋਰ ਹੈ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ਿੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ਤੁਹਾਡਾ ਟੀਵੀ ਅਤੇ ਨਿੱਜੀ  ਡਾਟਾ  ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਟੀਵੀ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ  ਡਾਟੇ  ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ਿੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ਜਾਰੀ ਰੱਖੋ"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ਸੈਟਿੰਗਾਂ"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"ਵੀਅਰ ਐਪਾਂ ਨੂੰ ਸਥਾਪਤ/ਅਣਸਥਾਪਤ ਕਰਨਾ"</string>
+    <string name="app_name" msgid="7488448184431507488">"ਪੈਕੇਜ ਸਥਾਪਨਾਕਾਰ"</string>
+    <string name="install" msgid="711829760615509273">"ਸਥਾਪਤ ਕਰੋ"</string>
+    <string name="done" msgid="6632441120016885253">"ਹੋ ਗਿਆ"</string>
+    <string name="cancel" msgid="1018267193425558088">"ਰੱਦ ਕਰੋ"</string>
+    <string name="installing" msgid="4921993079741206516">"ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="install_done" msgid="5987363587661783896">"ਐਪ ਸਥਾਪਤ ਕੀਤੀ ਗਈ।"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"ਕੀ ਤੁਸੀਂ ਇਹ ਐਪਲੀਕੇਸ਼ਨ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"ਕੀ ਤੁਸੀਂ ਇਸ ਮੌਜੂਦਾ ਐਪਲੀਕੇਸ਼ਨ ਵਿੱਚ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"ਕੀ ਤੁਸੀਂ ਇਸ ਬਿਲਟ-ਇਨ ਐਪਲੀਕੇਸ਼ਨ ਵਿੱਚ ਇੱਕ ਅੱਪਡੇਟ ਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਤੁਹਾਡਾ ਮੌਜੂਦਾ ਡਾਟਾ ਨਸ਼ਟ ਨਹੀਂ ਹੋਵੇਗਾ।"</string>
+    <string name="install_failed" msgid="5777824004474125469">"ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"ਪੈਕੇਜ ਨੂੰ ਸਥਾਪਤ ਹੋਣ ਤੋਂ ਬਲਾਕ ਕੀਤਾ ਗਿਆ ਸੀ।"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"ਪੈਕੇਜ ਦੇ ਇੱਕ ਮੌਜੂਦਾ ਪੈਕੇਜ ਨਾਲ ਵਿਵਾਦ ਹੋਣ ਕਰਕੇ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"ਐਪ ਦੇ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਦੇ ਅਨੁਰੂਪ ਨਾ ਹੋਣ ਕਰਕੇ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਟੀਵੀ ਦੇ ਅਨੁਰੂਪ ਨਹੀਂ ਹੈ।"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"ਐਪ ਦੇ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੇ ਅਨੁਰੂਪ ਨਾ ਹੋਣ ਕਰਕੇ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"ਪੈਕੇਜ ਦੇ ਅਵੈਧ ਪ੍ਰਤੀਤ ਹੋਣ ਕਰਕੇ ਐਪ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਗਈ।"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ \'ਤੇ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"ਇਹ ਵਰਤੋਂਕਾਰ ਅਗਿਆਤ ਐਪਾਂ ਨੂੰ ਸਥਾਪਤ ਨਹੀਂ ਕਰ ਸਕਦਾ"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ"</string>
+    <string name="ok" msgid="7871959885003339302">"ਠੀਕ ਹੈ"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"ਐਪਾਂ ਪ੍ਰਬੰਧਿਤ ਕਰੋ"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"ਜਗ੍ਹਾ ਖਾਲੀ ਨਹੀਂ"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਸਥਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ। ਕੁਝ ਜਗ੍ਹਾ ਖਾਲੀ ਕਰਕੇ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"ਐਪ ਨਹੀਂ ਮਿਲੀ"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ਇਹ ਐਪ ਸਥਾਪਤ ਕੀਤੀਆਂ ਐਪਾਂ ਦੀ ਸੂਚੀ ਵਿੱਚ ਨਹੀਂ ਮਿਲੀ।"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"ਮਨਜ਼ੂਰਸ਼ੁਦਾ ਨਹੀਂ"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"ਮੌਜੂਦਾ ਵਰਤੋਂਕਾਰ ਨੂੰ ਇਹ ਅਣਸਥਾਪਨਾ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੱਤੀ ਗਈ ਹੈ।"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"ਗੜਬੜ"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"ਐਪ ਅਣਸਥਾਪਤ ਨਹੀਂ ਕੀਤੀ ਜਾ ਸਕੀ।"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"ਐਪ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"ਅੱਪਡੇਟ ਅਣਸਥਾਪਤ ਕਰੋ"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ਅੱਗੇ ਦਿੱਤੀ ਐਪ ਦਾ ਭਾਗ ਹੈ:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"ਕੀ ਤੁਸੀਂ ਇਸ ਐਪ ਨੂੰ "<b>"ਸਾਰੇ"</b>" ਵਰਤੋਂਕਾਰਾਂ ਲਈ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ? ਐਪਲੀਕੇਸ਼ਨ ਅਤੇ ਇਸਦਾ ਡਾਟਾ ਡੀਵਾਈਸ \'ਤੇ "<b>"ਸਾਰੇ"</b>" ਵਰਤੋਂਕਾਰਾਂ ਵੱਲੋਂ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"ਕੀ ਤੁਸੀਂ ਵਰਤੋਂਕਾਰ <xliff:g id="USERNAME">%1$s</xliff:g> ਲਈ ਇਸ ਐਪ ਨੂੰ ਅਣਸਥਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ਕੀ ਇਸ ਐਪ ਨੂੰ ਫੈਕਟਰੀ ਵਰਜਨ ਨਾਲ ਬਦਲਣਾ ਹੈ? ਸਾਰਾ ਡਾਟਾ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ।"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ਕੀ ਇਸ ਐਪ ਨੂੰ ਫੈਕਟਰੀ ਵਰਜਨ ਨਾਲ ਬਦਲਣਾ ਹੈ? ਸਾਰਾ ਡਾਟਾ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ। ਇਹ ਇਸ ਡੀਵਾਈਸ ਦੇ ਸਾਰੇ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕਰੇਗਾ, ਜਿਸ ਵਿੱਚ ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਵਾਲੇ ਵਰਤੋਂਕਾਰ ਵੀ ਸ਼ਾਮਲ ਹਨ।"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"ਚੱਲ ਰਹੀਆਂ ਅਣਸਥਾਪਨਾਵਾਂ"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"ਅਸਫਲ ਅਣਸਥਾਪਨਾਵਾਂ"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"ਅਣਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ਨੂੰ ਅਣਸਥਾਪਤ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"ਅਣਸਥਾਪਤ ਕਰਨਾ ਮੁਕੰਮਲ ਹੋਇਆ।"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear \'ਤੇ ਸਥਾਪਤ ਜਾਂ ਅਣਸਥਾਪਤ ਕਰਨ ਦੀਆਂ ਕਾਰਵਾਈਆਂ ਸਮਰਥਿਤ ਨਹੀਂ ਹਨ।"</string>
+    <string name="message_staging" msgid="8032722385658438567">"ਐਪ ਨੂੰ ਸਟੇਜ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"ਅਗਿਆਤ"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਟੈਬਲੈੱਟ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਟੀਵੀ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"ਤੁਹਾਡੀ ਸੁਰੱਖਿਆ ਲਈ, ਤੁਹਾਡੇ ਫ਼ੋਨ ਨੂੰ ਇਸ ਸਰੋਤ ਤੋਂ ਅਗਿਆਤ ਐਪਾਂ ਸਥਾਪਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ।"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"ਤੁਹਾਡਾ ਫ਼ੋਨ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਫ਼ੋਨ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ੁੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"ਤੁਹਾਡਾ ਟੈਬਲੈੱਟ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ੁੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ਤੁਹਾਡਾ ਟੀਵੀ ਅਤੇ ਨਿੱਜੀ ਡਾਟਾ ਅਗਿਆਤ ਐਪਾਂ ਤੋਂ ਹਮਲੇ ਪ੍ਰਤੀ ਵਧੇਰੇ ਵਿੰਨਣਸ਼ੀਲ ਹਨ। ਇਹ ਐਪ ਸਥਾਪਤ ਕਰਕੇ, ਤੁਸੀਂ ਸਹਿਮਤੀ ਦਿੰਦੇ ਹੋ ਕਿ ਆਪਣੇ ਟੀਵੀ ਨੂੰ ਹੋਣ ਵਾਲੇ ਕਿਸੇ ਵੀ ਨੁਕਸਾਨ ਜਾਂ ਡਾਟੇ ਦੀ ਹਾਨੀ ਲਈ ਤੁਸੀਂ ਜ਼ੁੰਮੇਵਾਰ ਹੋ ਜੋ ਸ਼ਾਇਦ ਇਸ ਐਪ ਨੂੰ ਵਰਤਣ ਦੇ ਨਤੀਜੇ ਵਜੋਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"ਜਾਰੀ ਰੱਖੋ"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"ਸੈਟਿੰਗਾਂ"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"ਵੀਅਰ ਐਪਾਂ ਸਥਾਪਤ ਜਾਂ ਅਣਸਥਾਪਤ ਕਰਨਾ"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pl/strings.xml b/packages/PackageInstaller/res/values-pl/strings.xml
index dbedfad..01b2db9 100644
--- a/packages/PackageInstaller/res/values-pl/strings.xml
+++ b/packages/PackageInstaller/res/values-pl/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"Instalator pakietu"</string>
-    <string name="next" msgid="3057143178373252333">"Dalej"</string>
-    <string name="install" msgid="5896438203900042068">"Instaluj"</string>
-    <string name="done" msgid="3889387558374211719">"Gotowe"</string>
-    <string name="cancel" msgid="8360346460165114585">"Anuluj"</string>
-    <string name="installing" msgid="8613631001631998372">"Instalowanie..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instaluję pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikacja została zainstalowana."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Zainstalować tę aplikację? Będzie miała następujące uprawnienia:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Zainstalować tę aplikację? Nie ma specjalnych wymagań dotyczących dostępu."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Zainstalować aktualizację tej aplikacji? Nie utracisz wcześniejszych danych. Zaktualizowana aplikacja będzie miała następujące uprawnienia:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Zainstalować aktualizację fabrycznej aplikacji? Nie utracisz wcześniejszych danych. Zaktualizowana aplikacja będzie miała następujące uprawnienia:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Chcesz zaktualizować tę istniejącą aplikację? Nie utracisz danych. Nie są wymagane specjalne uprawnienia dostępu."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Chcesz zaktualizować tę wbudowaną aplikację? Nie utracisz danych. Nie są wymagane specjalne uprawnienia dostępu."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikacja nie została zainstalowana."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Instalacja pakietu została zablokowana."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacja nie została zainstalowana, bo powoduje konflikt z istniejącym pakietem."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacja nie została zainstalowana, bo jest niezgodna z Twoim tabletem."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Aplikacja jest niezgodna z Twoim telewizorem."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacja nie została zainstalowana, bo jest niezgodna z Twoim telefonem."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacja nie została zainstalowana, bo pakiet wygląda na nieprawidłowy."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim tablecie."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Nie udało się zainstalować <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim telewizorze."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim telefonie."</string>
-    <string name="launch" msgid="4826921505917605463">"Otwórz"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Twój administrator nie zezwala na instalowanie aplikacji pochodzących z nieznanych źródeł."</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ten użytkownik nie może instalować nieznanych aplikacji"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ten użytkownik nie może instalować aplikacji"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Zarządzaj aplikacjami"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Brak miejsca"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>. Zwolnij trochę miejsca i spróbuj ponownie."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Nie znaleziono aplikacji"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacji nie znaleziono na liście zainstalowanych programów."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Niedozwolone"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Bieżący użytkownik nie może tego odinstalować."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Błąd"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Nie można odinstalować aplikacji."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Odinstaluj aplikację"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Odinstaluj aktualizację"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> jest częścią następującej aplikacji:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Odinstalować tę aplikację?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Chcesz odinstalować tę aplikację dla "<b>"wszystkich"</b>" użytkowników? Ta aplikacja i jej dane zostaną usunięte dla "<b>"wszystkich"</b>" użytkowników na urządzeniu."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Chcesz odinstalować tę aplikację dla użytkownika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Przywrócić fabryczną wersję tej aplikacji? Wszystkie dane zostaną usunięte."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Przywrócić fabryczną wersję tej aplikacji? Wszystkie dane zostaną usunięte. Dotyczy to wszystkich użytkowników tego urządzenia, również tych korzystających z profilu do pracy."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Aktywne odinstalowania"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Nieudane odinstalowania"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Odinstalowywanie..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Odinstalowuję pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Odinstalowywanie zakończone"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Odinstalowano pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Nie udało się odinstalować."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Nie udało się odinstalować pakietu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nie można odinstalować aktywnej aplikacji do administrowania urządzeniem"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nie można odinstalować aplikacji do administrowania urządzeniem aktywnej dla użytkownika <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Niektórzy użytkownicy i niektóre profile wymagają tej aplikacji, a w innych przypadkach została odinstalowana"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ta aplikacja jest potrzebna w Twoim profilu i nie można jej odinstalować."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Administrator urządzenia wymaga tej aplikacji i nie można jej odinstalować."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Zarządzaj aplikacjami do administrowania urządzeniem"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Zarządzaj użytkownikami"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Nie można odinstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Podczas analizowania pakietu wystąpił problem."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nowe"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Wszystkie"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Prywatność"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Dostęp do urządzenia"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Ta aktualizacja nie wymaga nowych uprawnień."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odmów"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Więcej informacji"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Odmów mimo to"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> z <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Zezwolić aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Zawsze zezwalać aplikacji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Tylko przy używaniu aplikacji"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Zawsze"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Odmów i nie pytaj ponownie"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"wyłączone: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"wszystkie wyłączone"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"brak wyłączonych"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Zezwól"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacje"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Uprawnienia aplikacji"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Nie pytaj ponownie"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Brak uprawnień"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Dodatkowe uprawnienia"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otwórz informacje o aplikacji"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="few">Jeszcze <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="many">Jeszcze <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Jeszcze <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Jeszcze <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ta aplikacja jest na straszą wersję Androida. Jeśli odmówisz uprawnień, aplikacja może nie działać prawidłowo."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"wykonywanie nieznanych działań"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Dostęp ma: <xliff:g id="COUNT_0">%1$d</xliff:g> z <xliff:g id="COUNT_1">%2$d</xliff:g> aplikacji"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Pokaż systemowe"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ukryj systemowe"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Brak aplikacji"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Ustawienia lokalizacji"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> jest dostawcą usług lokalizacyjnych dla tego urządzenia. Dostęp do danych lokalizacji można zmienić w ustawieniach lokalizacji."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Jeśli nie przyznasz tych uprawnień, podstawowe funkcje urządzenia mogą nie działać prawidłowo."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Narzucone przez zasady"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Dostęp w tle wyłączony przez zasady"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Dostęp w tle włączony przez zasady"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Dostęp na pierwszym planie włączony przez zasady"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolowane przez administratora"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Zawsze"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Tylko przy używaniu aplikacji"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nigdy"</string>
-    <string name="loading" msgid="7811651799620593731">"Ładuję…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Wszystkie uprawnienia"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Inne funkcje aplikacji"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Prośba o pozwolenie"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Wykryto nakładkę ekranową"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Aby zmodyfikować te uprawnienia, musisz najpierw wyłączyć nakładkę ekranową, klikając Ustawienia &gt; Aplikacje"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Otwórz ustawienia"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear nie obsługuje instalowania ani odinstalowywania."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Wybierz, jakie uprawnienia dostępu ma mieć &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacja &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; została zaktualizowana. Wybierz dla niej uprawnienia dostępu."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Anuluj"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Dalej"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nowe uprawnienia"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Aktualne uprawnienia"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Przygotowuję aplikację…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Nieznana"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Ze względów bezpieczeństwa na Twoim tablecie nie można instalować nieznanych aplikacji z tego źródła."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Ze względów bezpieczeństwa na Twoim telewizorze nie można instalować nieznanych aplikacji z tego źródła."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Ze względów bezpieczeństwa na Twoim telefonie nie można instalować nieznanych aplikacji z tego źródła."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Dane na telefonie i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie telefonu lub utratę danych w wyniku jej używania."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Dane na tablecie i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie tabletu lub utratę danych w wyniku jej używania."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Dane na telewizorze i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie telewizora lub utratę danych w wyniku jej używania."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Dalej"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Ustawienia"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalowanie/odinstalowywanie aplikacji na Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instalator pakietu"</string>
+    <string name="install" msgid="711829760615509273">"Zainstaluj"</string>
+    <string name="done" msgid="6632441120016885253">"Gotowe"</string>
+    <string name="cancel" msgid="1018267193425558088">"Anuluj"</string>
+    <string name="installing" msgid="4921993079741206516">"Instaluję…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instaluję pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikacja została zainstalowana."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Czy zainstalować tę aplikację?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Czy chcesz zainstalować aktualizację posiadanej aplikacji? Dotychczasowe dane nie zostaną utracone."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Czy chcesz zainstalować aktualizację fabrycznej aplikacji? Dotychczasowe dane nie zostaną utracone."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikacja nie została zainstalowana."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Instalacja pakietu została zablokowana."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacja nie została zainstalowana, bo powoduje konflikt z istniejącym pakietem."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikacja nie została zainstalowana, bo jest niezgodna z Twoim tabletem."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Aplikacja jest niezgodna z Twoim telewizorem."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikacja nie została zainstalowana, bo jest niezgodna z Twoim telefonem."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikacja nie została zainstalowana, bo pakiet wygląda na nieprawidłowy."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim tablecie."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Nie udało się zainstalować <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim telewizorze."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g> na Twoim telefonie."</string>
+    <string name="launch" msgid="3952550563999890101">"Otwórz"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Twój administrator nie zezwala na instalowanie aplikacji pochodzących z nieznanych źródeł."</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ten użytkownik nie może instalować nieznanych aplikacji"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ten użytkownik nie może instalować aplikacji"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Zarządzaj aplikacjami"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Brak miejsca"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Nie można zainstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>. Zwolnij trochę miejsca i spróbuj ponownie."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Nie znaleziono aplikacji"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikacji nie znaleziono na liście zainstalowanych programów."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Niedozwolone"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Bieżący użytkownik nie może tego odinstalować."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Błąd"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Nie można odinstalować aplikacji."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Odinstaluj aplikację"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Odinstaluj aktualizację"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> jest częścią następującej aplikacji:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Odinstalować tę aplikację?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Chcesz odinstalować tę aplikację dla "<b>"wszystkich"</b>" użytkowników? Ta aplikacja i jej dane zostaną usunięte dla "<b>"wszystkich"</b>" użytkowników na urządzeniu."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Chcesz odinstalować tę aplikację dla użytkownika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Przywrócić fabryczną wersję tej aplikacji? Wszystkie dane zostaną usunięte."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Przywrócić fabryczną wersję tej aplikacji? Wszystkie dane zostaną usunięte. Dotyczy to wszystkich użytkowników tego urządzenia, również tych korzystających z profilu do pracy."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Aktywne odinstalowania"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Nieudane odinstalowania"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Odinstalowuję…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Odinstalowuję pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Odinstalowywanie zakończone."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Odinstalowano pakiet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Nie udało się odinstalować."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Nie udało się odinstalować pakietu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Nie można odinstalować aktywnej aplikacji do administrowania urządzeniem"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Nie można odinstalować aplikacji do administrowania urządzeniem aktywnej dla użytkownika <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Niektórzy użytkownicy i niektóre profile wymagają tej aplikacji, a w innych przypadkach została odinstalowana"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ta aplikacja jest potrzebna w Twoim profilu i nie można jej odinstalować."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Administrator urządzenia wymaga tej aplikacji i nie można jej odinstalować."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Zarządzaj aplikacjami do administracji urządzeniem"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Zarządzaj użytkownikami"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Nie można odinstalować aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Podczas analizowania pakietu wystąpił problem."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear nie obsługuje instalowania ani odinstalowywania."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Przygotowuję aplikację…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Inny"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Ze względów bezpieczeństwa na Twoim tablecie nie można instalować nieznanych aplikacji z tego źródła."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Ze względów bezpieczeństwa na Twoim telewizorze nie można instalować nieznanych aplikacji z tego źródła."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Ze względów bezpieczeństwa na Twoim telefonie nie można instalować nieznanych aplikacji z tego źródła."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Dane na telefonie i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie telefonu lub utratę danych w wyniku jej używania."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Dane na tablecie i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie tabletu lub utratę danych w wyniku jej używania."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Dane na telewizorze i prywatne są bardziej narażone na atak nieznanych aplikacji. Instalując tę aplikację, bierzesz na siebie odpowiedzialność za ewentualne uszkodzenie telewizora lub utratę danych w wyniku jej używania."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Dalej"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Ustawienia"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalacja/usuwanie aplikacji na Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pt-rBR/strings.xml b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
index feb2337..47289f9 100644
--- a/packages/PackageInstaller/res/values-pt-rBR/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rBR/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Instalador do pacote"</string>
-    <string name="next" msgid="3057143178373252333">"Próximo"</string>
-    <string name="install" msgid="5896438203900042068">"Instalar"</string>
-    <string name="done" msgid="3889387558374211719">"Concluído"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
-    <string name="installing" msgid="8613631001631998372">"Instalando..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App instalado."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Quer instalar este app? Ele terá acesso a:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Quer instalar este app? Não requer acesso especial."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Quer instalar uma atualização para este app? Os dados existentes não serão perdidos. O app atualizado terá acesso a:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Quer instalar uma atualização para este app integrado? Os dados existentes não serão perdidos. O app atualizado terá acesso a:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Quer instalar uma atualização para este app existente? Seus dados existentes não serão perdidos. A atualização não requer qualquer acesso especial."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Quer instalar uma atualização para este app integrado? Seus dados existentes não serão perdidos. A atualização não requer qualquer acesso especial."</string>
-    <string name="install_failed" msgid="6579998651498970899">"O app não foi instalado."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"A instalação do pacote foi bloqueada."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Como o app não é compatível com seu tablet, ele não foi instalado."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Este app não é compatível com sua TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Como o app não é compatível com seu smartphone, ele não foi instalado."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Como o pacote parece ser inválido, o app não foi instalado."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> em seu tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> na sua TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> em seu telefone."</string>
-    <string name="launch" msgid="4826921505917605463">"Abrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Seu administrador não permite a instalação de apps transferidos por download de fontes desconhecidas"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Apps desconhecidos não podem ser instalados por este usuário"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuário não tem permissão para instalar apps"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Gerenciar apps"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sem espaço"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libere um pouco de espaço e tente novamente."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App não encontrado"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"O app não foi encontrado na lista de apps instalados."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Não permitido"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"O usuário atual não tem permissão para executar essa desinstalação."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erro"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Não foi possível desinstalar o app."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar app"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar atualização"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> é parte do seguinte app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Quer desinstalar este app?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Quer desinstalar este app para "<b>"todos"</b>" os usuários? O app e seus dados serão removidos para "<b>"todos"</b>" os usuários do dispositivo."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Substituir este app pela versão de fábrica? Todos os dados serão removidos."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Substituir este app pela versão de fábrica? Todos os dados serão removidos. Isso afeta todos os usuários deste dispositivo, incluindo aqueles com perfis de trabalho."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Executando desinstalações"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Falha nas desinstalações"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Desinstalando..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Desinstalação concluída."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Desinstalação malsucedida."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Não é possível desinstalar o app para administrador ativo do dispositivo"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Não é possível desinstalar o app para administrador ativo do dispositivo de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"O app é necessário para alguns usuários ou perfis e foi desinstalado para outros"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Este app é necessário para seu perfil e não pode ser desinstalado."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"O app é exigido pelo administrador do dispositivo e não pode ser desinstalado."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gerenciar apps do administrador do dispositivo"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gerenciar usuários"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Não foi possível desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ocorreu um problema ao analisar o pacote."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Novas"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Todas"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacidade"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Acesso ao dispositivo"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Esta atualização não requer novas permissões."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Negar"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mais informações"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Negar mesmo assim"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Permitir que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Sempre permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Apenas ao usar o app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Negar e não perguntar novamente"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desativada(s)"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"todas desativadas"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"nenhuma desativada"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Permissões do app"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Não perguntar novamente"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Sem permissões"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Outras permissões"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir informações do app"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Este app foi projetado para uma versão anterior do Android. Negar a permissão pode fazer com que ele deixe de funcionar conforme esperado."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"executar uma ação desconhecida"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> apps permitidos"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nenhum app"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Configurações de localização"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> é um provedor de serviços de localização para este dispositivo. O acesso local pode ser modificado nas configurações de localização."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Se você negar essa permissão, recursos básicos do seu dispositivo poderão não funcionar mais como deveriam."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicável por política"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acesso em segundo plano desativado pela política"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acesso em segundo plano ativado pela política"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acesso em primeiro plano ativado pela política"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlada pelo administrador"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Apenas ao usar o app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
-    <string name="loading" msgid="7811651799620593731">"Carregando…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Todas as permissões"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Outros recursos do app"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Solicitação de permissão"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Sobreposição de tela detectada"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Para alterar a configuração dessa permissão, você deve primeiro desativar a sobreposição de tela em \"Config.\" &gt; \"Apps\""</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir configurações"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Escolha o que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; terá permissão de acessar"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"O app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; foi atualizado. Escolha o que esse app terá permissão de acessar."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Novas permissões"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Permissões atuais"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Promovendo app…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Desconhecido"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Para sua segurança, seu tablet não tem permissão para instalar apps desconhecidos dessa fonte."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Para sua segurança, sua TV não tem permissão para instalar apps desconhecidos dessa fonte."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Para sua segurança, seu smartphone não tem permissão para instalar apps desconhecidos dessa fonte."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Seu smartphone e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu smartphone ou pela perda de dados que possa resultar do uso desse app."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Seu tablet e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu tablet ou pela perda de dados que possa resultar do uso desse app."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Sua TV e seus dados pessoais estão mais vulneráveis a ataques por apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano à sua TV ou pela perda de dados que possa resultar do uso dese app."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Configurações"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps do Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instalador do pacote"</string>
+    <string name="install" msgid="711829760615509273">"Instalar"</string>
+    <string name="done" msgid="6632441120016885253">"Concluído"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancelar"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalando…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App instalado."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Quer instalar este aplicativo?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Quer instalar uma atualização para este aplicativo? Seus dados existentes não serão perdidos."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Quer instalar uma atualização para este aplicativo integrado? Seus dados existentes não serão perdidos."</string>
+    <string name="install_failed" msgid="5777824004474125469">"O app não foi instalado."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"A instalação do pacote foi bloqueada."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Como o app não é compatível com seu tablet, ele não foi instalado."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Este app não é compatível com sua TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Como o app não é compatível com seu smartphone, ele não foi instalado."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Como o pacote parece ser inválido, o app não foi instalado."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Não foi possível instalar o app <xliff:g id="APP_NAME">%1$s</xliff:g> no seu tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Não foi possível instalar o app <xliff:g id="APP_NAME">%1$s</xliff:g> na sua TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Não foi possível instalar o app <xliff:g id="APP_NAME">%1$s</xliff:g> no seu smartphone."</string>
+    <string name="launch" msgid="3952550563999890101">"Abrir"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Seu administrador não permite a instalação de apps transferidos por download de fontes desconhecidas"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Apps desconhecidos não podem ser instalados por este usuário"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuário não tem permissão para instalar apps"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gerenciar apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sem espaço"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libere um pouco de espaço e tente novamente."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App não encontrado"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"O app não foi encontrado na lista de apps instalados."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Não permitido"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"O usuário atual não tem permissão para executar essa desinstalação."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Erro"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Não foi possível desinstalar o app."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalar app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar atualização"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> é parte do seguinte app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Quer desinstalar este app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Quer desinstalar este app para "<b>"todos"</b>" os usuários? O aplicativo e os dados dele serão removidos para "<b>"todos"</b>" os usuários do dispositivo."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Substituir este app pela versão de fábrica? Todos os dados serão removidos."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Substituir este app pela versão de fábrica? Todos os dados serão removidos. Isso afeta todos os usuários deste dispositivo, incluindo aqueles com perfis de trabalho."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Executando desinstalações"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Falha nas desinstalações"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Falha na desinstalação."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Não é possível desinstalar o app de administração ativo do dispositivo"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Não é possível desinstalar o app de administração ativo do dispositivo de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"O app é necessário para alguns usuários ou perfis e foi desinstalado para outros"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Este app é necessário para seu perfil e não pode ser desinstalado."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"O app é exigido pelo administrador do dispositivo e não pode ser desinstalado."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gerenciar apps do administrador do dispositivo"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gerenciar usuários"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Não foi possível desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Ocorreu um problema ao analisar o pacote."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Testando app…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Desconhecido"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Para sua segurança, seu tablet não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Para sua segurança, sua TV não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Para sua segurança, seu smartphone não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Seu smartphone e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu smartphone ou pela perda de dados que possa resultar do uso do app."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Seu tablet e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu tablet ou pela perda de dados que possa resultar do uso do app."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Sua TV e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano à sua TV ou pela perda de dados que possa resultar do uso do app."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuar"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Configurações"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalando/desinstalando apps do Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pt-rPT/strings.xml b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
index c380839..871b0a1 100644
--- a/packages/PackageInstaller/res/values-pt-rPT/strings.xml
+++ b/packages/PackageInstaller/res/values-pt-rPT/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Programa de instalação do pacote"</string>
-    <string name="next" msgid="3057143178373252333">"Seguinte"</string>
-    <string name="install" msgid="5896438203900042068">"Instalar"</string>
-    <string name="done" msgid="3889387558374211719">"Concluído"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
-    <string name="installing" msgid="8613631001631998372">"A instalar..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"A instalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplicação instalada."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Pretende instalar esta aplicação? Terá acesso a:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Pretende instalar esta aplicação? Não requer qualquer acesso especial."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Pretende instalar uma atualização para a aplicação existente? Os dados existentes não serão perdidos. A aplicação atualizada terá acesso a:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Pretende instalar uma atualização para a aplicação existente? Os dados existentes não serão perdidos. A aplicação atualizada terá acesso a:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Pretende instalar uma atualização para a aplicação existente? Os dados existentes não serão perdidos. Não é necessário um acesso específico."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Pretende instalar uma atualização para a aplicação integrada? Os dados existentes não serão perdidos. Não é necessário um acesso específico."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplicação não instalada."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Foi bloqueada a instalação do pacote."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"A aplicação não foi instalada porque o pacote entra em conflito com um pacote existente."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"A aplicação não foi instalada porque não é compatível com o seu tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Esta aplicação não é compatível com a sua TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"A aplicação não foi instalada porque não é compatível com o seu telemóvel."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"A aplicação não foi instalada porque o pacote parece ser inválido."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> no tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Não foi possível instalar o <xliff:g id="APP_NAME">%1$s</xliff:g> na sua TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> no telemóvel."</string>
-    <string name="launch" msgid="4826921505917605463">"Abrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"O gestor não permite a instalação de aplicações obtidas de fontes desconhecidas"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Este utilizador não pode instalar aplicações desconhecidas"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este utilizador não tem permissão para instalar aplicações"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Gerir aplicações"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sem espaço"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Liberte algum espaço e tente novamente."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplicação não encontrada"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"A aplicação não foi encontrada na lista de aplicações instaladas."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Não autorizado"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"O utilizador atual não tem autorização para efetuar esta desinstalação."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erro"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Não foi possível desinstalar a aplicação."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar a aplicação"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar atualização"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> faz parte da seguinte aplicação:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Pretende desinstalar esta aplicação?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Pretende desinstalar esta aplicação para "<b>"todos"</b>" os utilizadores? A aplicação e os respetivos dados serão removidos de "<b>"todos"</b>" os utilizadores do dispositivo."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Pretende desinstalar esta aplicação para o utilizador <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Pretende substituir esta aplicação pela versão de fábrica? Todos os dados são removidos."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Pretende substituir esta aplicação pela versão de fábrica? Todos os dados são removidos. Esta ação afeta todos os utilizadores deste dispositivo, incluindo os que têm perfis de trabalho."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Desinstalações em execução"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Desinstalações com falha"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"A desinstalar..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"A desinstalar a aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Desinstalação concluída."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"A aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> foi desinstalada"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Desinstalação sem êxito."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Falha ao desinstalar a aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Não é possível desinstalar a aplicação de administração de dispositivos ativa"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Não é possível desinstalar a aplicação de administração de dispositivos ativa para <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Esta aplicação é necessária para alguns utilizadores ou perfis e foi desinstalada para outros"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"O perfil necessita desta aplicação e não é possível desinstalá-la."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Esta aplic. é exigida pelo gestor do disp. e não pode ser desinstalada."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gerir aplicações de administração de dispositivos"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gerir utilizadores"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Não foi possível desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ocorreu um problema ao analisar o pacote."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Novas"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Todas"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacidade"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Acesso ao Dispositivo"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Esta atualização não requer novas permissões."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Recusar"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mais informações"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Recusar mesmo assim"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Pretende permitir à(ao) &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Pretende permitir que a aplicação &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g> sempre?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Apenas ao utilizar a aplicação"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Recusar e não perguntar novamente"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desativadas"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"todas desativadas"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"nenhuma desativada"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicações"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Permissões da aplicação"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Não perguntar novamente"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Sem autorizações"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Autorizações adicionais"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir informações da aplicação"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Mais <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Esta aplicação foi concebida para uma versão mais antiga do Android. Negar autorização pode fazer com que deixe de funcionar como pretendido."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"executar uma ação desconhecida"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> aplicações autorizadas"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Sem aplicações"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Definições de localização"</string>
-    <string name="location_warning" msgid="8778701356292735971">"O <xliff:g id="APP_NAME">%1$s</xliff:g> é um fornecedor de serviços de localização para este dispositivo. É possível modificar o acesso à localização a partir das definições de localização."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Se negar esta autorização, as funcionalidades básicas do seu dispositivo podem deixar de funcionar corretamente."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Imposta pela política"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acesso em segundo plano desativado pela política"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acesso em segundo plano ativado pela política"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acesso em primeiro plano ativado pela política"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlado pelo administrador"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Apenas ao utilizar a aplicação"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
-    <string name="loading" msgid="7811651799620593731">"A carregar…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Todas as autorizações"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Outras capacidades de aplicações"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Pedido de autorização"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Sobreposição de ecrã detetada"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Para alterar esta definição de autorização, primeiro tem de desativar a sobreposição do ecrã em Definições &gt; Aplicações"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir definições"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Escolher a que conteúdos permite que o &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; aceda"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"O &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; foi atualizado. Escolha a que conteúdos permite que esta aplicação aceda."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Novas autorizações"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Autorizações atuais"</string>
-    <string name="message_staging" msgid="6151794817691100003">"A preparar a aplicação…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Desconhecido"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Para sua segurança, o tablet não está autorizado a instalar aplicações desconhecidas a partir desta fonte."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Para sua segurança, a TV não está autorizada a instalar aplicações desconhecidas a partir desta fonte."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Para sua segurança, o telemóvel não está autorizado a instalar aplicações desconhecidas a partir desta fonte."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"O seu telemóvel e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados ao telemóvel ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"O seu tablet e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados ao tablet ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"A sua TV e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados à TV ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Definições"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalar/desinstalar aplicações Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instalador do pacote"</string>
+    <string name="install" msgid="711829760615509273">"Instalar"</string>
+    <string name="done" msgid="6632441120016885253">"Concluído"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancelar"</string>
+    <string name="installing" msgid="4921993079741206516">"A instalar…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"A instalar <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplicação instalada."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Pretende instalar esta aplicação?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Pretende instalar uma atualização para esta aplicação existente? Os seus dados existentes não serão perdidos."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Pretende instalar uma atualização para esta aplicação incorporada? Os seus dados existentes não serão perdidos."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplicação não instalada."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Foi bloqueada a instalação do pacote."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"A aplicação não foi instalada porque o pacote entra em conflito com um pacote existente."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"A aplicação não foi instalada porque não é compatível com o seu tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Esta aplicação não é compatível com a sua TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"A aplicação não foi instalada porque não é compatível com o seu telemóvel."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"A aplicação não foi instalada porque o pacote parece ser inválido."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Não foi possível instalar a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> no tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Não foi possível instalar a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> na TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Não foi possível instalar a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g> no telemóvel."</string>
+    <string name="launch" msgid="3952550563999890101">"Abrir"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"O administrador não permite a instalação de aplicações obtidas de fontes desconhecidas."</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Este utilizador não pode instalar aplicações desconhecidas."</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este utilizador não tem autorização para instalar aplicações."</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gerir aplic."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sem espaço"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Não foi possível instalar a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>. Liberte algum espaço e tente novamente."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplicação não encontrada"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"A aplicação não foi encontrada na lista de aplicações instaladas."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Não permitido."</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"O utilizador atual não tem autorização para efetuar esta desinstalação."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Erro"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Não foi possível desinstalar a aplicação."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalar aplicação"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar atualização"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> faz parte da seguinte aplicação:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Pretende desinstalar esta aplicação?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Pretende desinstalar esta aplicação para "<b>"todos"</b>" os utilizadores? A aplicação e os respetivos dados serão removidos de "<b>"todos"</b>" os utilizadores do dispositivo."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Pretende desinstalar esta aplicação para o utilizador <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Pretende substituir esta aplicação pela versão de fábrica? Todos os dados são removidos."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Pretende substituir esta aplicação pela versão de fábrica? Todos os dados são removidos. Esta ação afeta todos os utilizadores deste dispositivo, incluindo os que têm perfis de trabalho."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalações em execução"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalações com falha"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"A desinstalar…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"A desinstalar a aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"A aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> foi desinstalada"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Desinstalação sem êxito."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha ao desinstalar a aplicação <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Não é possível desinstalar a aplicação de administração de dispositivos ativa."</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Não é possível desinstalar a aplicação de administração de dispositivos ativa para <xliff:g id="USERNAME">%1$s</xliff:g>."</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Esta aplicação é necessária para alguns utilizadores ou perfis e foi desinstalada para outros."</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"O perfil necessita desta aplicação e não é possível desinstalá-la."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Esta aplic. é exigida pelo administrador do disp. e não pode ser desinstalada."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gerir aplicações de administração de dispositivos"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gerir utilizadores"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Não foi possível desinstalar a aplicação <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Ocorreu um problema ao analisar o pacote."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"A preparar a aplicação…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Desconhecida"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Para sua segurança, o tablet não está autorizado a instalar aplicações desconhecidas a partir desta fonte."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Para sua segurança, a TV não está autorizada a instalar aplicações desconhecidas a partir desta fonte."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Para sua segurança, o telemóvel não está autorizado a instalar aplicações desconhecidas a partir desta fonte."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"O seu telemóvel e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados ao telemóvel ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"O seu tablet e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados ao tablet ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"A sua TV e os dados pessoais estão mais vulneráveis a ataques por parte de aplicações desconhecidas. Ao instalar esta aplicação, concorda que é responsável por quaisquer danos causados à TV ou pelas perdas de dados que possam resultar da utilização da mesma."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuar"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Definições"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalar/desinstalar aplicações Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-pt/strings.xml b/packages/PackageInstaller/res/values-pt/strings.xml
index feb2337..47289f9 100644
--- a/packages/PackageInstaller/res/values-pt/strings.xml
+++ b/packages/PackageInstaller/res/values-pt/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Instalador do pacote"</string>
-    <string name="next" msgid="3057143178373252333">"Próximo"</string>
-    <string name="install" msgid="5896438203900042068">"Instalar"</string>
-    <string name="done" msgid="3889387558374211719">"Concluído"</string>
-    <string name="cancel" msgid="8360346460165114585">"Cancelar"</string>
-    <string name="installing" msgid="8613631001631998372">"Instalando..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"App instalado."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Quer instalar este app? Ele terá acesso a:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Quer instalar este app? Não requer acesso especial."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Quer instalar uma atualização para este app? Os dados existentes não serão perdidos. O app atualizado terá acesso a:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Quer instalar uma atualização para este app integrado? Os dados existentes não serão perdidos. O app atualizado terá acesso a:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Quer instalar uma atualização para este app existente? Seus dados existentes não serão perdidos. A atualização não requer qualquer acesso especial."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Quer instalar uma atualização para este app integrado? Seus dados existentes não serão perdidos. A atualização não requer qualquer acesso especial."</string>
-    <string name="install_failed" msgid="6579998651498970899">"O app não foi instalado."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"A instalação do pacote foi bloqueada."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Como o app não é compatível com seu tablet, ele não foi instalado."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Este app não é compatível com sua TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Como o app não é compatível com seu smartphone, ele não foi instalado."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Como o pacote parece ser inválido, o app não foi instalado."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> em seu tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> na sua TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g> em seu telefone."</string>
-    <string name="launch" msgid="4826921505917605463">"Abrir"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Seu administrador não permite a instalação de apps transferidos por download de fontes desconhecidas"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Apps desconhecidos não podem ser instalados por este usuário"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Este usuário não tem permissão para instalar apps"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Gerenciar apps"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Sem espaço"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libere um pouco de espaço e tente novamente."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"App não encontrado"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"O app não foi encontrado na lista de apps instalados."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Não permitido"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"O usuário atual não tem permissão para executar essa desinstalação."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Erro"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Não foi possível desinstalar o app."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Desinstalar app"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Desinstalar atualização"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> é parte do seguinte app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Quer desinstalar este app?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Quer desinstalar este app para "<b>"todos"</b>" os usuários? O app e seus dados serão removidos para "<b>"todos"</b>" os usuários do dispositivo."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Substituir este app pela versão de fábrica? Todos os dados serão removidos."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Substituir este app pela versão de fábrica? Todos os dados serão removidos. Isso afeta todos os usuários deste dispositivo, incluindo aqueles com perfis de trabalho."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Executando desinstalações"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Falha nas desinstalações"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Desinstalando..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Desinstalação concluída."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Desinstalação malsucedida."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Não é possível desinstalar o app para administrador ativo do dispositivo"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Não é possível desinstalar o app para administrador ativo do dispositivo de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"O app é necessário para alguns usuários ou perfis e foi desinstalado para outros"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Este app é necessário para seu perfil e não pode ser desinstalado."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"O app é exigido pelo administrador do dispositivo e não pode ser desinstalado."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gerenciar apps do administrador do dispositivo"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gerenciar usuários"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Não foi possível desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ocorreu um problema ao analisar o pacote."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Novas"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Todas"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacidade"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Acesso ao dispositivo"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Esta atualização não requer novas permissões."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Negar"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mais informações"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Negar mesmo assim"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> de <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Permitir que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Sempre permitir que &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Apenas ao usar o app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Sempre"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Negar e não perguntar novamente"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> desativada(s)"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"todas desativadas"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"nenhuma desativada"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permitir"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Apps"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Permissões do app"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Não perguntar novamente"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Sem permissões"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Outras permissões"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Abrir informações do app"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Mais <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Este app foi projetado para uma versão anterior do Android. Negar a permissão pode fazer com que ele deixe de funcionar conforme esperado."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"executar uma ação desconhecida"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> de <xliff:g id="COUNT_1">%2$d</xliff:g> apps permitidos"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Mostrar sistema"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ocultar sistema"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nenhum app"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Configurações de localização"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> é um provedor de serviços de localização para este dispositivo. O acesso local pode ser modificado nas configurações de localização."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Se você negar essa permissão, recursos básicos do seu dispositivo poderão não funcionar mais como deveriam."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicável por política"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acesso em segundo plano desativado pela política"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acesso em segundo plano ativado pela política"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acesso em primeiro plano ativado pela política"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlada pelo administrador"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Sempre"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Apenas ao usar o app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nunca"</string>
-    <string name="loading" msgid="7811651799620593731">"Carregando…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Todas as permissões"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Outros recursos do app"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Solicitação de permissão"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Sobreposição de tela detectada"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Para alterar a configuração dessa permissão, você deve primeiro desativar a sobreposição de tela em \"Config.\" &gt; \"Apps\""</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Abrir configurações"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Escolha o que o app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; terá permissão de acessar"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"O app &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; foi atualizado. Escolha o que esse app terá permissão de acessar."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Cancelar"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuar"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Novas permissões"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Permissões atuais"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Promovendo app…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Desconhecido"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Para sua segurança, seu tablet não tem permissão para instalar apps desconhecidos dessa fonte."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Para sua segurança, sua TV não tem permissão para instalar apps desconhecidos dessa fonte."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Para sua segurança, seu smartphone não tem permissão para instalar apps desconhecidos dessa fonte."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Seu smartphone e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu smartphone ou pela perda de dados que possa resultar do uso desse app."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Seu tablet e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu tablet ou pela perda de dados que possa resultar do uso desse app."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Sua TV e seus dados pessoais estão mais vulneráveis a ataques por apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano à sua TV ou pela perda de dados que possa resultar do uso dese app."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuar"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Configurações"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalando/desinstalando apps do Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Instalador do pacote"</string>
+    <string name="install" msgid="711829760615509273">"Instalar"</string>
+    <string name="done" msgid="6632441120016885253">"Concluído"</string>
+    <string name="cancel" msgid="1018267193425558088">"Cancelar"</string>
+    <string name="installing" msgid="4921993079741206516">"Instalando…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Instalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"App instalado."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Quer instalar este aplicativo?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Quer instalar uma atualização para este aplicativo? Seus dados existentes não serão perdidos."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Quer instalar uma atualização para este aplicativo integrado? Seus dados existentes não serão perdidos."</string>
+    <string name="install_failed" msgid="5777824004474125469">"O app não foi instalado."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"A instalação do pacote foi bloqueada."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Como o pacote tem um conflito com um pacote já existente, o app não foi instalado."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Como o app não é compatível com seu tablet, ele não foi instalado."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Este app não é compatível com sua TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Como o app não é compatível com seu smartphone, ele não foi instalado."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Como o pacote parece ser inválido, o app não foi instalado."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Não foi possível instalar o app <xliff:g id="APP_NAME">%1$s</xliff:g> no seu tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Não foi possível instalar o app <xliff:g id="APP_NAME">%1$s</xliff:g> na sua TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Não foi possível instalar o app <xliff:g id="APP_NAME">%1$s</xliff:g> no seu smartphone."</string>
+    <string name="launch" msgid="3952550563999890101">"Abrir"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Seu administrador não permite a instalação de apps transferidos por download de fontes desconhecidas"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Apps desconhecidos não podem ser instalados por este usuário"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Este usuário não tem permissão para instalar apps"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gerenciar apps"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Sem espaço"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Não foi possível instalar <xliff:g id="APP_NAME">%1$s</xliff:g>. Libere um pouco de espaço e tente novamente."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"App não encontrado"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"O app não foi encontrado na lista de apps instalados."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Não permitido"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"O usuário atual não tem permissão para executar essa desinstalação."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Erro"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Não foi possível desinstalar o app."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Desinstalar app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Desinstalar atualização"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> é parte do seguinte app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Quer desinstalar este app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Quer desinstalar este app para "<b>"todos"</b>" os usuários? O aplicativo e os dados dele serão removidos para "<b>"todos"</b>" os usuários do dispositivo."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Quer desinstalar este app para o usuário <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Substituir este app pela versão de fábrica? Todos os dados serão removidos."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Substituir este app pela versão de fábrica? Todos os dados serão removidos. Isso afeta todos os usuários deste dispositivo, incluindo aqueles com perfis de trabalho."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Executando desinstalações"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Falha nas desinstalações"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Desinstalando <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Desinstalação concluída."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalado"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Falha na desinstalação."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Falha na desinstalação de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Não é possível desinstalar o app de administração ativo do dispositivo"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Não é possível desinstalar o app de administração ativo do dispositivo de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"O app é necessário para alguns usuários ou perfis e foi desinstalado para outros"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Este app é necessário para seu perfil e não pode ser desinstalado."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"O app é exigido pelo administrador do dispositivo e não pode ser desinstalado."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gerenciar apps do administrador do dispositivo"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gerenciar usuários"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Não foi possível desinstalar <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Ocorreu um problema ao analisar o pacote."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"As ações de instalar/desinstalar não são compatíveis com o Android Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Testando app…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Desconhecido"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Para sua segurança, seu tablet não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Para sua segurança, sua TV não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Para sua segurança, seu smartphone não tem permissão para instalar apps desconhecidos dessa fonte."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Seu smartphone e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu smartphone ou pela perda de dados que possa resultar do uso do app."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Seu tablet e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano causado ao seu tablet ou pela perda de dados que possa resultar do uso do app."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Sua TV e seus dados pessoais estão mais vulneráveis a ataques de apps desconhecidos. Ao instalar esse app, você concorda que é responsável por qualquer dano à sua TV ou pela perda de dados que possa resultar do uso do app."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuar"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Configurações"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalando/desinstalando apps do Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ro/strings.xml b/packages/PackageInstaller/res/values-ro/strings.xml
index 3b13dab3..43b0dea 100644
--- a/packages/PackageInstaller/res/values-ro/strings.xml
+++ b/packages/PackageInstaller/res/values-ro/strings.xml
@@ -16,142 +16,76 @@
 
 <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="2738748390251381682">"Program de instalare a pachetelor"</string>
-    <string name="next" msgid="3057143178373252333">"Înainte"</string>
-    <string name="install" msgid="5896438203900042068">"Instalați"</string>
-    <string name="done" msgid="3889387558374211719">"Terminat"</string>
-    <string name="cancel" msgid="8360346460165114585">"Anulați"</string>
-    <string name="installing" msgid="8613631001631998372">"În curs de instalare..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Se instalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplicație instalată."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Doriți să instalați această aplicație? Aceasta va avea acces la:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Doriți să instalați această aplicație? Aplicația nu solicită un acces special."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Doriți să instalați o actualizare pentru această aplicație existentă? Datele existente nu vor fi pierdute. Aplicația actualizată va avea acces la:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Doriți să instalați o actualizare pentru această aplicație încorporată? Datele existente nu vor fi pierdute. Aplicația actualizată va avea acces la:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Doriți să instalați o actualizare pentru această aplicație existentă? Datele existente nu vor fi pierdute. Actualizarea nu are nevoie de acces special."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Doriți să instalați o actualizare pentru această aplicație încorporată? Datele existente nu vor fi pierdute. Actualizarea nu are nevoie de acces special."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplicația nu este instalată."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Instalarea pachetului a fost blocată."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplicația nu a fost instalată deoarece pachetul intră în conflict cu un pachet existent."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplicația nu a fost instalată deoarece nu este compatibilă cu tableta dvs."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Această aplicație nu este compatibilă cu televizorul dvs."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplicația nu a fost instalată deoarece nu este compatibilă cu telefonul dvs."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplicația nu a fost instalată deoarece se pare că pachetul este nevalid."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe tableta dvs."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe televizor."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe telefonul dvs."</string>
-    <string name="launch" msgid="4826921505917605463">"Deschideți"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratorul nu permite instalarea aplicațiilor obținute din surse necunoscute"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Aplicațiile necunoscute nu pot fi instalate de acest utilizator"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Acest utilizator nu are permisiunea să instaleze aplicații"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Gestionați aplicații"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Spațiu de stocare insuficient"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată. Eliberați spațiu și încercați din nou."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplicația nu a fost găsită"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplicația nu a fost găsită în lista de aplicații instalate."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nu are permisiune"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Utilizatorul actual nu are permisiune pentru a face această dezinstalare."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Eroare"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplicația nu a putut fi dezinstalată."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Dezinstalați aplicația"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Dezinstalați actualizarea"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">" <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> face parte din următoarea aplicație:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Doriți să dezinstalați această aplicație?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Doriți să dezinstalați această aplicație pentru "<b>"toți"</b>" utilizatorii? Aplicația și datele acesteia vor fi eliminate de la "<b>"toți"</b>" utilizatorii de pe acest dispozitiv."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Dezinstalați această aplicație pentru utilizatorul <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Înlocuiți această aplicație cu versiunea din fabrică? Toate datele vor fi eliminate."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Înlocuiți această aplicație cu versiunea din fabrică? Toate datele vor fi eliminate. Această acțiune va afecta toți utilizatorii dispozitivului, inclusiv pe cei cu profiluri de serviciu."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Dezinstalări în curs"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Dezinstalări nereușite"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"În curs de dezinstalare..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Se dezinstalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Dezinstalare finalizată."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> a fost dezinstalat"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Dezinstalare nefinalizată."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nu a putut fi dezinstalată."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nu se poate dezinstala aplicația activă de administrare a dispozitivului"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nu se poate dezinstala aplicația activă de administrare a dispozitivului pentru <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Aplicația este necesară unor utilizatori sau profiluri și a fost dezinstalată pentru alții"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Aplicația este necesară pentru profilul dvs. și nu poate fi dezinstalată."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Aplicație necesară administratorului dispozitivului. Nu poate fi dezinstalată."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Gestionați aplicațiile de administrare dispozitiv"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Gestionați utilizatorii"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi dezinstalată."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"A apărut o problemă la analizarea pachetului."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Noi"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Toate"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Confidențialitate"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Acces la dispozitiv"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Această actualizare nu necesită permisiuni noi."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Refuzați"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mai multe informații"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Nu permiteți oricum"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> din <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Permiteți &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Permiteți întotdeauna &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; să <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Doar în timp ce folosiți aplicația"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Întotdeauna"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Respingeți și nu se mai întreabă"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> dezactivate"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"toate dezactivate"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"niciuna dezactivată"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Permiteți"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplicații"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Permisiuni pentru aplicație"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Nu mai întreba"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Fără permisiuni"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Permisiuni suplimentare"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Deschideți informațiile despre aplicații"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="few">Încă <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Încă <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">Încă <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Această aplicație a fost creată pentru o versiune Android mai veche. Dacă nu acordați permisiunea, este posibil ca aceasta să nu mai funcționeze corespunzător."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"efectuează o acțiune necunoscută"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> din <xliff:g id="COUNT_1">%2$d</xliff:g> aplicații au această permisiune"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Afișați aplicațiile de sistem"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ascundeți aplicațiile de sistem"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Nicio aplicație"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Setări privind locația"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> este un furnizor de servicii de localizare pentru acest dispozitiv. Accesul la locație poate fi modificat din setările privind locația."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Dacă refuzați această permisiune, este posibil ca funcțiile de bază ale dispozitivului să nu mai funcționeze corespunzător."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Aplicată conform politicii"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Acces la fundal dezactivat de politică"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Acces la fundal activat de politică"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Acces la prim-plan activat de politică"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Controlat de administrator"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Întotdeauna"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Doar în timp ce folosiți aplicația"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Niciodată"</string>
-    <string name="loading" msgid="7811651799620593731">"Se încarcă..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Toate permisiunile"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Alte funcții ale aplicației"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Solicitare de permisiune"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"S-a detectat suprapunerea pe ecran"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Ca să schimbați această setare pentru permisiuni, mai întâi trebuie să dezactivați suprapunerea pe ecran din Setări &gt; Aplicații"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Deschideți setările"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Acțiunile Instalați/Dezinstalați nu sunt acceptate pe Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Alegeți ce va putea accesa &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplicația &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; a fost actualizată. Alegeți ce va putea accesa această aplicație."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Anulați"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Continuați"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Permisiuni noi"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Permisiuni actuale"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Se pregătește aplicația…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Necunoscut"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Din motive de securitate, tableta dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Din motive de securitate, televizorul dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Din motive de securitate, telefonul dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonul și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați aplicația, acceptați că sunteți singura persoană responsabilă pentru deteriorarea telefonului sau pentru pierderea datelor, care pot avea loc în urma utilizării acesteia."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tableta și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați aplicația, acceptați că sunteți singura persoană responsabilă pentru deteriorarea tabletei sau pentru pierderea datelor, care pot avea loc în urma utilizării acesteia."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Televizorul și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați această aplicație, acceptați că sunteți singura persoană responsabilă pentru deteriorarea televizorului sau pentru pierderea datelor, care pot avea loc în urma utilizării acesteia."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Continuați"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Setări"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Se (dez)instalează aplicațiile Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Program de instalare a pachetelor"</string>
+    <string name="install" msgid="711829760615509273">"Instalați"</string>
+    <string name="done" msgid="6632441120016885253">"Gata"</string>
+    <string name="cancel" msgid="1018267193425558088">"Anulați"</string>
+    <string name="installing" msgid="4921993079741206516">"Se instalează…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Se instalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplicație instalată."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Doriți să instalați această aplicație?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Doriți să instalați o actualizare pentru această aplicație? Datele existente nu se vor pierde."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Doriți să instalați o actualizare pentru această aplicație încorporată? Datele existente nu se vor pierde."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplicația nu a fost instalată."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Instalarea pachetului a fost blocată."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplicația nu a fost instalată deoarece pachetul intră în conflict cu un pachet existent."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplicația nu a fost instalată deoarece nu este compatibilă cu tableta dvs."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Aplicația nu este compatibilă cu televizorul dvs."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplicația nu a fost instalată deoarece nu este compatibilă cu telefonul dvs."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplicația nu a fost instalată deoarece pachetul este nevalid."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe tableta dvs."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe televizorul dvs."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată pe telefonul dvs."</string>
+    <string name="launch" msgid="3952550563999890101">"Deschideți"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administratorul nu permite instalarea aplicațiilor obținute din surse necunoscute"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aplicațiile necunoscute nu pot fi instalate de acest utilizator"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Acest utilizator nu are permisiunea să instaleze aplicații"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Gestionați aplicații"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Spațiu de stocare insuficient"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi instalată. Eliberați spațiu și încercați din nou."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplicația nu a fost găsită"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplicația nu a fost găsită în lista de aplicații instalate."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nepermis"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Utilizatorul actual nu are permisiune pentru a face această dezinstalare."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Eroare"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Aplicația nu a putut fi dezinstalată."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Dezinstalați aplicația"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Dezinstalați actualizarea"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> face parte din următoarea aplicație:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Doriți să dezinstalați această aplicație?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Doriți să dezinstalați această aplicație pentru "<b>"toți"</b>" utilizatorii? Aplicația și datele acesteia vor fi eliminate de la "<b>"toți"</b>" utilizatorii de pe acest dispozitiv."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Dezinstalați această aplicație pentru utilizatorul <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Înlocuiți această aplicație cu versiunea din fabrică? Toate datele vor fi eliminate."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Înlocuiți această aplicație cu versiunea din fabrică? Toate datele vor fi eliminate. Această acțiune va afecta toți utilizatorii dispozitivului, inclusiv pe cei cu profiluri de serviciu."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Dezinstalări în curs"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Dezinstalări nereușite"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Se dezinstalează…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Se dezinstalează <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Dezinstalare finalizată."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> s-a dezinstalat"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Dezinstalare nefinalizată."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nu s-a putut dezinstala."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Nu se poate dezinstala aplicația activă de administrare a dispozitivului"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Nu se poate dezinstala aplicația activă de administrare a dispozitivului pentru <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Aplicația este necesară unor utilizatori sau profiluri și a fost dezinstalată pentru alții"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Aplicația este necesară pentru profilul dvs. și nu poate fi dezinstalată."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Aplicația este necesară administratorului dispozitivului și nu poate fi dezinstalată."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Gestionați aplicațiile de administrare dispozitiv"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Gestionați utilizatorii"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Aplicația <xliff:g id="APP_NAME">%1$s</xliff:g> nu a putut fi dezinstalată."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"A apărut o problemă la analizarea pachetului."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Acțiunile de instalare și dezinstalare nu sunt acceptate pe Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Se pregătește aplicația…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Necunoscut"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Din motive de securitate, tableta dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Din motive de securitate, televizorul dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Din motive de securitate, telefonul dvs. nu are permisiunea să instaleze aplicații necunoscute din această sursă."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonul și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați această aplicație, acceptați că sunteți singura persoană responsabilă pentru deteriorarea telefonului sau pentru pierderea datelor, care pot avea loc în urma folosirii acesteia."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tableta și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați aplicația, acceptați că sunteți singura persoană responsabilă pentru deteriorarea tabletei sau pentru pierderea datelor, care pot avea loc în urma folosirii acesteia."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Televizorul și datele dvs. personale sunt mai vulnerabile la un atac din partea aplicațiilor necunoscute. Dacă instalați această aplicație, acceptați că sunteți singura persoană responsabilă pentru deteriorarea televizorului sau pentru pierderea datelor, care pot avea loc în urma folosirii acesteia."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Continuați"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Setări"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Se (dez)instalează aplicațiile Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml
index 9ffdf4a..63287f4 100644
--- a/packages/PackageInstaller/res/values-ru/strings.xml
+++ b/packages/PackageInstaller/res/values-ru/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"Установщик пакетов"</string>
-    <string name="next" msgid="3057143178373252333">"Далее"</string>
-    <string name="install" msgid="5896438203900042068">"Установить"</string>
-    <string name="done" msgid="3889387558374211719">"Готово"</string>
-    <string name="cancel" msgid="8360346460165114585">"Отмена"</string>
-    <string name="installing" msgid="8613631001631998372">"Установка..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Устанавливаем <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Приложение установлено."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Хотите ли вы установить это приложение? Оно получит следующие разрешения:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Это приложение не требует специальных разрешений. Установить его?"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Хотите установить обновление для этого приложения? После обновления оно сможет выполнять следующие действия:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Хотите установить обновление для этого приложения? После обновления оно сможет выполнять следующие действия:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Установить обновление этого приложения? На текущих данных это никак не отразится. Специальных прав доступа не требуется."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Установить обновление этого встроенного приложения? На текущих данных это никак не отразится. Специальных прав доступа не требуется."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Приложение не установлено."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Установка пакета заблокирована."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Приложение не установлено, так как оно конфликтует с другим пакетом."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Приложение не установлено, так как оно несовместимо с вашим планшетом."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Приложение несовместимо с вашим телевизором."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Приложение не установлено, так как оно несовместимо с вашим телефоном."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Приложение не установлено, так как его пакет недействителен (например, поврежден)."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" нельзя установить на ваш телевизор."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
-    <string name="launch" msgid="4826921505917605463">"Открыть"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ваш администратор запретил устанавливать приложения из неизвестных источников"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Этот пользователь не может устанавливать неизвестные приложения"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Этому пользователю не разрешено устанавливать приложения"</string>
-    <string name="ok" msgid="3468756155452870475">"ОК"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Управление приложениями"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Недостаточно места"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\". Освободите место и повторите попытку."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Приложение не найдено"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Приложения нет в списке установленных."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Действие запрещено"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Этот пользователь не может удалить приложение."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Ошибка"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Не удалось удалить приложение."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Удаление приложения"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Удаление обновления"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> – часть следующего приложения:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Удалить приложение?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Удалить это приложение для "<b>"всех"</b>" пользователей? После этого "<b>"ни один"</b>" пользователь устройства не будет иметь доступа к приложению и связанным с ним данным."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Удалить это приложение из профиля <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Установить исходную версию приложения? Все его данные будут удалены."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Установить исходную версию приложения? Его данные будут удалены из всех профилей устройства, в том числе рабочих."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Активные процессы удаления"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Ошибки удаления"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Удаление..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Удаление приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Удаление завершено."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" удалено"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Ошибка при удалении."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Не удалось удалить приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Невозможно удалить активное приложение для администрирования устройства"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Невозможно удалить активное приложение для администрирования устройства в профиле <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Это приложение обязательно для некоторых пользователей или профилей."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Это приложение обязательно для вашего профиля. Его нельзя удалить."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Это приложение указано администратором как обязательное. Его нельзя удалить."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Настроить приложения для администрир. устройства"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Управление пользователями"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Не удалось удалить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ошибка при синтаксическом анализе пакета."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Новые"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Все"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Личные данные"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Доступ к устройству"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Установка этого обновления не требует новых разрешений."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Отклонить"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Подробнее"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Все равно запретить"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> из <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Разрешить приложению &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Всегда разрешать приложению \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Когда открыто приложение"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Всегда"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Запретить и больше не спрашивать"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"отключено: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"все отключены"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"все включены"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Разрешить"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Приложения"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Разрешения приложений"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Больше не спрашивать"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Нет разрешений"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Ещё разрешения"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"О приложении"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Ещё <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="few">Ещё <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="many">Ещё <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Ещё <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Это приложение было разработано для более ранней версии Android. Отзыв разрешения может вызвать неполадки в работе."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"выполняет неизвестные действия"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Приложений с разрешением: <xliff:g id="COUNT_0">%1$d</xliff:g> из <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Показать системные процессы"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Скрыть системные процессы"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Нет приложений"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Настройки геоданных"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> является поставщиком услуг геолокации для этого устройства. Вы можете изменить параметры доступа в настройках геоданных."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Если вы отключите это разрешение, основные функции устройства могут работать неправильно."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"В соответствии с политикой"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Доступ в фоновом режиме отключен в соответствии с правилами."</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Доступ в фоновом режиме включен в соответствии с правилами."</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Активный режим включен в соответствии с правилами."</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Контролируется администратором"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Всегда"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Когда открыто приложение"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Никогда"</string>
-    <string name="loading" msgid="7811651799620593731">"Загрузка…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Все разрешения"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Что ещё может приложение"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Запрос разрешений"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Показ поверх других окон"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Чтобы предоставить или отменить разрешение, сначала отключите показ поверх других окон. Для этого нажмите \"Настройки &gt; Приложения\"."</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Открыть настройки"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Установка и удаление не поддерживаются на Android Wear"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Выберите разрешения для приложения &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Приложение &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; обновлено. Выберите разрешения для него."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Отмена"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Далее"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Новые разрешения"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Имеющиеся разрешения"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Подождите…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Неизвестное приложение"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"В целях безопасности ваш планшет блокирует установку приложений из неизвестных источников."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"В целях безопасности ваш телевизор блокирует установку приложений из неизвестных источников."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"В целях безопасности ваш телефон блокирует установку приложений из неизвестных источников."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Ваши личные данные и данные телефона более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы соглашаетесь с тем, что несете полную ответственность за любой ущерб, нанесенный телефону, и потерю данных, связанные с использованием этого приложения."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ваши личные данные и данные планшета более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы соглашаетесь с тем, что несете полную ответственность за любой ущерб, нанесенный планшету, и потерю данных, связанные с использованием этого приложения."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Ваши личные данные и данные телевизора более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы соглашаетесь с тем, что несете полную ответственность за любой ущерб, нанесенный телевизору, и потерю данных, связанные с использованием этого приложения."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Продолжить"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Настройки"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Установка/удаление приложений для Android Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Установщик пакетов"</string>
+    <string name="install" msgid="711829760615509273">"Установить"</string>
+    <string name="done" msgid="6632441120016885253">"Готово"</string>
+    <string name="cancel" msgid="1018267193425558088">"Отмена"</string>
+    <string name="installing" msgid="4921993079741206516">"Установка…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Установка приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Приложение установлено."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Установить это приложение?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Установить обновление для этого приложения? Вы не потеряете связанные с ним данные."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Установить обновление для этого встроенного приложения? Вы не потеряете связанные с ним данные."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Приложение не установлено."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Установка пакета заблокирована."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Приложение не установлено, так как оно конфликтует с другим пакетом."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Приложение не установлено, так как оно несовместимо с вашим планшетом."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Приложение несовместимо с вашим телевизором."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Приложение не установлено, так как оно несовместимо с вашим телефоном."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Приложение не установлено, так как его пакет недействителен (например, поврежден)."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" на планшет."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Этот пользователь не может устанавливать неизвестные приложения."</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Этому пользователю не разрешено устанавливать приложения."</string>
+    <string name="ok" msgid="7871959885003339302">"ОК"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Управление приложениями"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Недостаточно места"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Не удалось установить приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\". Освободите место на устройстве и повторите попытку."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Приложение не найдено"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Приложения нет в списке установленных."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Действие запрещено"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Этому пользователю запрещено удалять приложения."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Ошибка"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Не удалось удалить приложение."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Удалить приложение"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Удалить обновление"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> – часть следующего приложения:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Удалить приложение?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Удалить это приложение для "<b>"всех"</b>" пользователей устройства? Они потеряют доступ как к приложению, так и к связанным с ним данным."<b></b></string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Удалить это приложение из профиля <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Установить исходную версию приложения? Все его данные будут удалены."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Установить исходную версию приложения? Его данные будут удалены из всех профилей устройства, в том числе рабочих."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Активные процессы удаления"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ошибки удаления"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Удаление…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Удаление приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Удаление завершено."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Wear OS"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Установка и удаление не поддерживаются в Wear OS."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Подождите…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Неизвестное приложение"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"В целях безопасности ваш планшет блокирует установку приложений из неизвестных источников."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"В целях безопасности ваш телевизор блокирует установку приложений из неизвестных источников."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"В целях безопасности ваш телефон блокирует установку приложений из неизвестных источников."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Ваши персональные данные и данные телефона более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы берете на себя всю ответственность за последствия, связанные с его использованием, то есть за любой ущерб, нанесенный телефону, и возможную потерю данных."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Ваши персональные данные и данные планшета более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы берете на себя всю ответственность за последствия, связанные с его использованием, то есть за любой ущерб, нанесенный планшету, и возможную потерю данных."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Ваши персональные данные и данные телевизора более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы берете на себя всю ответственность за последствия, связанные с его использованием, то есть за любой ущерб, нанесенный телевизору, и возможную потерю данных."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Продолжить"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Настройки"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Установка/удаление прилож. для Wear OS"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-si/strings.xml b/packages/PackageInstaller/res/values-si/strings.xml
index 18fc840..2e926af 100644
--- a/packages/PackageInstaller/res/values-si/strings.xml
+++ b/packages/PackageInstaller/res/values-si/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"පැකේජ ස්ථාපනකරු"</string>
-    <string name="next" msgid="3057143178373252333">"මීලඟ"</string>
-    <string name="install" msgid="5896438203900042068">"ස්ථාපනය"</string>
-    <string name="done" msgid="3889387558374211719">"හරි"</string>
-    <string name="cancel" msgid="8360346460165114585">"අවලංගු කරන්න"</string>
-    <string name="installing" msgid="8613631001631998372">"ස්ථාපනය කරමින්…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ස්ථාපනය කරමින්…"</string>
-    <string name="install_done" msgid="3682715442154357097">"යෙදුම ස්ථාපනය කරන ලදි."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"ඔබට මෙම යෙදුම ස්ථාපනය කිරීමට අවශ්‍යද? පහත ඒවා වෙත එයට ප්‍රවේශය ලැබෙනු ඇත:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"මෙම යෙදුම ස්ථාපනය කිරීමට ඔබට අවශ්‍යද? වෙනත් විශේෂ ප්‍රවේශයක් එයට අවශ්‍ය නොවෙයි."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"දැනට පවතින මෙම යෙදුමට යාවත්කාලීනයක් ස්ථාපනය කිරීමට ඔබට අවශ්‍යද? ඔබගේ පවතින දත්ත නැති නොවේ. යාවත්කාලීන කළ යෙදුම පිවිසීම ලබා ගනී:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"ඔබට මෙම තිළැලි යෙදුමට යාවත්කාලීනය ස්ථාපනය කිරීමට අවශ්‍යද? ඔබගේ දැනට පවතින දත්ත නැති නොවේ. යාවත්කාලීන කරන ලද යෙදුම පහත සඳහා ප්‍රවේශය ලබාගනු ඇත:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"මෙම පවතින යෙදුමට යාවත්කාලීනයක් ස්ථාපනය කිරීමට ඔබට අවශ්‍යද? ඔබගේ පවතින දත්ත නැති නොවේ. එයට විශේෂ ප්‍රවේශයක් අවශ්‍ය නොවේ."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"පවතින මෙම යෙදුමට යාවත්කාලීනයක් ස්ථාපනය කිරීමට ඔබට අවශ්‍යද? ඔබගේ පවතින දත්ත නැති නොවේ. එයට විශේෂ ප්‍රවේශයක් අවශ්‍ය නොවේ."</string>
-    <string name="install_failed" msgid="6579998651498970899">"යෙදුම ස්ථාපනය කරේ නැත."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"මෙම පැකේජය ස්ථාපනය කිරීම අවහිර කරන ලදි."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"පැකේජය දැනට පවතින පැකේජයක් සමග ගැටෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"යෙදුම ඔබේ ටැබ්ලට් පරිගණකය සමග නොගැළපෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"මෙම යෙදුම ඔබගේ රූපවාහිනිය හා නොගැළපේ."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"යෙදුම ඔබේ දුරකථනය සමග නොගැළපෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"පැකේජය වලංගු නොවන බවක් පෙනෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"ඔබගේ ටැබ්ලටයේ <xliff:g id="APP_NAME">%1$s</xliff:g> ස්ථාපනය කළ නොහැක."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> මෙම රූපවාහිනියෙහි ස්ථාපනය කළ නොහැක."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> දුරකථනයට ස්ථාපිත කිරීමට නොහැකි විය."</string>
-    <string name="launch" msgid="4826921505917605463">"විවෘත කරන්න"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"නාඳුනන මූලයන් වෙතින් ලබාගත් යෙදුම් ස්ථාපනය කිරීමට ඔබගේ පරිපාලකයා ඉඩ නොදේ"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"මෙම පරිශීලකයා මඟින් නොදන්නා යෙදුම් ස්ථාපනය කළ නොහැක"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"මෙම පරිශීලකයාට යෙදුම් ස්ථාපනය කිරීමට අවසර නැත"</string>
-    <string name="ok" msgid="3468756155452870475">"හරි"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"යෙදුම් කළමනාකරණය කරන්න"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ඉඩ නොමැත"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> ස්ථාපිත කිරීමට නොහැකි විය. ඉඩ පොඩ්ඩක් නිදහස් කොට නැවත උත්සාහ කරන්න."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"යෙදුම හමුවී නැත"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ස්ථාපිත යෙදුම් ලැයිස්තුවේ යෙදුම සොයා ගත නොහැකි විය."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ඉඩ නොදෙයි"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"වත්මන් පරිශීලකයාට මෙම අස්ථාපනය සිදු කිරීමට ඉඩ නොදේ."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"දෝෂය"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"යෙදුම අස්ථාපනය කළ නොහැකි විය."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"යෙදුම අස්ථාපනය කරන්න"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"යාවත්කාලිනය අස්ථාපනය කරන්න"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> පහත යෙදුමේ කොටසකි:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"ඔබට මෙම යෙදුම අස්ථාපනය කිරීමට අවශ්‍යද?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222"><b>"සියලු"</b>" පරිශීලකයන්  සඳහා මෙම යෙදුම අස්ථාපනය කිරීමට ඔබට අවශ්‍යද? උපාංගයෙහි "<b>"සියලු"</b>" පරිශීලකයන් සඳහා යෙදුම සහ එහි දත්ත ඉවත්වනු ඇත."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> පරිශීලකයා සඳහා මෙම යෙදුම අස්ථාපනය කිරීමට ඔබට අවශ්‍යයද?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"මෙම යෙදුම කර්මාන්ත ශාලා අනුවාදයක් සමගින් ප්‍රතිස්ථාපනය කරන්නද? සියලු දත්ත ඉවත් කරනු ඇත."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"මෙම යෙදුම කර්මාන්ත ශාලා අනුවාදයක් සමගින් ප්‍රතිස්ථාපනය කරන්නද? සියලු දත්ත ඉවත් කරනු ඇත. මෙය කාර්යාල පැතිකඩවල් සහිත අය ඇතුළුව, මෙම උපාංගයෙහි සියලු පරිශීලකයන් වෙත බලපානු ඇත."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"අස්ථාපන ධාවනය කරමින්"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"අසාර්ථක වූ අස්ථාපන"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"අස්ථාපනය කරමින්…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරමින්…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"අස්ථාපනය අවසන්."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරන ලදී"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"අස්ථාපිත විම අසාර්ථකයි."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කිරීම සාර්ථකයි."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ක්‍රියාකාරී උපාංගය පරිපාලක යෙදුම අස්ථාපනය කිරීමට නොහැක"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> සඳහා ක්‍රියාකාරී උපාංගය පරිපාලක යෙදුම අස්ථාපනය කිරීමට නොහැක"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"මෙම යෙදුම සමහර පරිශීලකයන්ට සහ පැතිකඩවල්වලට අවශ්‍ය අතර අනෙක් අයට අස්ථාපනය කරන ලදී"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"ඔබේ කාර්ය පැතිකඩ සඳහා මෙම යෙදුම අවශ්‍ය වන අතර අස්ථාපනය කළ නොහැකිය."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ඔබගේ උපාංගයේ පාලකයාට මෙම යෙදුම අවශ්‍ය වේ එම නිසා අස්ථාපනය කළ නොහැක."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"උපාංග පරිපාලක යෙදුම් කළමනාකරණය කිරීම"</string>
-    <string name="manage_users" msgid="3125018886835668847">"පරිශීලකයන් කළමනාකරණය කරන්න"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> අස්ථාපනය කල නොහැක."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"පැකේජය විග්‍රහ කිරීමේදී ගැටළුවක් ඇති විය."</string>
-    <string name="newPerms" msgid="6039428254474104210">"අලුත්"</string>
-    <string name="allPerms" msgid="1024385515840703981">"සියල්ල"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"පෞද්ගලිකත්වය"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"උපාංගය ප්‍රවේශය"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"මෙම යාවත්කාලිනයට අලුත් අවසරයන් අවශ්‍ය නොවේ."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ප්‍රතික්ෂේප කරන්න"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"වැඩිදුර තොරතුරු"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"කෙසේ වෙතත් ප්‍රතික්ෂේප කරන්න"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> න් <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ට <xliff:g id="ACTION">%2$s</xliff:g> වෙත ඉඩ දෙන්නද?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"සැම විට &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; හට <xliff:g id="ACTION">%2$s</xliff:g> වෙත ඉඩ දෙන්නද?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"යෙදුම භාවිතා කරන විට පමණි"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"සැම විට"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ප්‍රතික්ෂේප කරන්න, නැවත අසන්න එපා"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> අබලයි"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"සියල්ල අබලයි"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"කිසිවක් අබල නැත"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"ඉඩ දෙන්න"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"යෙදුම්"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"යෙදුම් අවසර"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"නැවත අසන්න එපා"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"අවසර නොමැත"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"අතිරේක අවසර"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"යෙදුම් තොරතුරු විවෘත කරන්න"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">.තව <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">.තව <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"මෙම යෙදුම නිර්මාණය කර ඇත්තේ Android වල පැරණි අනුවාදයකට වේ. අවසර නොදීම මඟින් එය බලාපොරොත්තු වන ආකාරයට වැඩ නොකිරීමට හැක."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"නොදන්නා ක්‍රියාවක් සිදු කරන්න"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"යෙදුම් <xliff:g id="COUNT_1">%2$d</xliff:g> න් <xliff:g id="COUNT_0">%1$d</xliff:g> කට ඉඩ දෙන ලදි"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"පද්ධතිය පෙන්වන්න"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"පද්ධතිය සඟවන්න"</string>
-    <string name="no_apps" msgid="1965493419005012569">"යෙදුම් නොමැත"</string>
-    <string name="location_settings" msgid="1774875730854491297">"ස්ථාන සැකසීම්"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> මෙම උපාංගය සඳහා ස්ථාන සේවාවන් සපයන්නෙකු වේ. ස්ථාන ප්‍රවේශය ස්ථාන සැකසීම් වෙතින් වෙනස් කළ හැක."</string>
-    <string name="system_warning" msgid="7103819124542305179">"ඔබ මෙම අවසරය ප්‍රතික්ෂේප කරන්නේ නම්, සමහර යෙදුම් බලාපොරොත්තු පරිදි ක්‍රියා නොකරනු ඇත."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"ප්‍රතිපත්තිය මඟින් බලාත්මක කරයි"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"පසුබිම් ප්‍රවේශය ප්‍රතිපත්තිය මගින් අබල කර ඇත"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"පසුබිම් ප්‍රවේශය ප්‍රතිපත්තිය මගින් සබල කර ඇත"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"පෙරබිම් ප්‍රවේශය ප්‍රතිපත්තිය මගින් සබල කර ඇත"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"පරිපාලක විසින් පාලනය කෙරේ"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"සැම විට"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"යෙදුම භාවිතා කරන විට පමණි"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"කිසි විටක නැත"</string>
-    <string name="loading" msgid="7811651799620593731">"පූරණය කරමින්…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"සියලු අවසර"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"වෙනත් යෙදුම් හැකියාවන්"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"අවසර ඉල්ලීම"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"තිර උඩැතිරියක් අනාවරණය කරන ලදි"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"මෙම අවසර සැකසීම වෙනස් කිරීම සඳහා, ඔබට මුලින්ම සැකසීම් &gt; යෙදුම් වෙතින් තිර උඩැතිරිය අක්‍රිය කර යුතුයි"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"සැකසීම් විවෘත කරන්න"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear මත ස්ථාපන/අස්ථාපනය ක්‍රියා සහාය දක්වන්නේ නැත."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; හට පිවිසීමට ඉඩ දෙන දේ තෝරන්න"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; යාවත්කාලීන කර ඇත. මෙම යෙදුමට පිවිසීමට ඉඩ දෙන දේ තෝරන්න."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"අවලංගු කරන්න"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"දිගටම කර ගෙන යන්න"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"නව අවසර"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"වත්මන් අවසර"</string>
-    <string name="message_staging" msgid="6151794817691100003">"යෙදුම වේදිකාගත කරමින්..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"නොදනී"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"ආරක්ෂාව සඳහා, ඔබගේ ටැබ්ලටය මෙම මුලාශ්‍රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"ආරක්ෂාව සඳහා, ඔබගේ රූපවාහිනිය මෙම මුලාශ්‍රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"ආරක්ෂාව සඳහා, ඔබගේ දුරකථනය මෙම මුලාශ්‍රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"ඔබගේ දුරකථනය සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ දුරකථනය සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්‍රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"ඔබගේ ටැබ්ලට් පරිගණකය සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ ටැබ්ලට් පරිගණකය සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්‍රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ඔබගේ TV සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ TV සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්‍රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"දිගටම කරගෙන යන්න"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"සැකසීම්"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear යෙදුම් ස්ථාපනය/අස්ථාපනය කරමින්"</string>
+    <string name="app_name" msgid="7488448184431507488">"පැකේජ ස්ථාපනකරු"</string>
+    <string name="install" msgid="711829760615509273">"ස්ථාපනය කරන්න"</string>
+    <string name="done" msgid="6632441120016885253">"කළා"</string>
+    <string name="cancel" msgid="1018267193425558088">"අවලංගු කරන්න"</string>
+    <string name="installing" msgid="4921993079741206516">"ස්ථාපනය කරමින්…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ස්ථාපනය කරමින්…"</string>
+    <string name="install_done" msgid="5987363587661783896">"යෙදුම ස්ථාපනය කර ඇත."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"මෙම යෙදුම ස්ථාපනය කිරීමට ඔබට අවශ්‍යද?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"මෙම යෙදුම සඳහා යාවත්කාලීන ස්ථාපනය කිරීමට ඔබට අවශ්‍යද? ඔබගේ පවතින දත්ත නැති වනු ඇත."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"මෙම ඇමිණූ යෙදුමට යාවත්කාලීන ස්ථාපනය කිරීමට ඔබට අවශ්‍යද? ඔබගේ පවතින දත්ත නැති වනු ඇත."</string>
+    <string name="install_failed" msgid="5777824004474125469">"යෙදුම ස්ථාපනය කර නැත."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"මෙම පැකේජය ස්ථාපනය කිරීම අවහිර කරන ලදි."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"පැකේජය දැනට පවතින පැකේජයක් සමග ගැටෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"යෙදුම ඔබේ ටැබ්ලට් පරිගණකය සමග නොගැළපෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"මෙම යෙදුම ඔබගේ රූපවාහිනිය හා නොගැළපේ."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"යෙදුම ඔබේ දුරකථනය සමග නොගැළපෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"පැකේජය වලංගු නොවන බවක් පෙනෙන නිසා යෙදුම ස්ථාපනය නොකරන ලදී."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"ඔබගේ ටැබ්ලටයේ <xliff:g id="APP_NAME">%1$s</xliff:g> ස්ථාපනය කළ නොහැක."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"මෙම පරිශීලකයා මඟින් නොදන්නා යෙදුම් ස්ථාපනය කළ නොහැක"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"මෙම පරිශීලකයාට යෙදුම් ස්ථාපනය කිරීමට අවසර නැත"</string>
+    <string name="ok" msgid="7871959885003339302">"හරි"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"යෙදුම් කළමනාකරණය කරන්න"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"ඉඩ නොමැත"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ස්ථාපිත කිරීමට නොහැකි විය. ඉඩ පොඩ්ඩක් නිදහස් කොට නැවත උත්සාහ කරන්න."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"යෙදුම හමුවී නැත"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ස්ථාපිත යෙදුම් ලැයිස්තුවේ යෙදුම සොයා ගත නොහැකි විය."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"ඉඩ නොදේ"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"වත්මන් පරිශීලකයාට මෙම අස්ථාපනය සිදු කිරීමට ඉඩ නොදේ."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"දෝෂය"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"යෙදුම අස්ථාපනය කළ නොහැකි විය."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"යෙදුම අස්ථාපනය කරන්න"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"යාවත්කාලිනය අස්ථාපනය කරන්න"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> පහත යෙදුමේ කොටසකි:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"ඔබට මෙම යෙදුම අස්ථාපනය කිරීමට අවශ්‍යද?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119"><b>"සියලු"</b>" පරිශීලකයන් සඳහා මෙම යෙදුම අස්ථාපනය කිරීමට ඔබට අවශ්‍යද? උපාංගයෙහි "<b>"සියලු"</b>" පරිශීලකයන් සඳහා යෙදුම සහ එහි දත්ත ඉවත්වනු ඇත."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> පරිශීලකයා සඳහා මෙම යෙදුම අස්ථාපනය කිරීමට ඔබට අවශ්‍යයද?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"මෙම යෙදුම කර්මාන්ත ශාලා අනුවාදයක් සමගින් ප්‍රතිස්ථාපනය කරන්නද? සියලු දත්ත ඉවත් කරනු ඇත."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"මෙම යෙදුම කර්මාන්ත ශාලා අනුවාදයක් සමගින් ප්‍රතිස්ථාපනය කරන්නද? සියලු දත්ත ඉවත් කරනු ඇත. මෙය කාර්යාල පැතිකඩවල් සහිත අය ඇතුළුව, මෙම උපාංගයෙහි සියලු පරිශීලකයන් වෙත බලපානු ඇත."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"අස්ථාපන ධාවනය කරමින්"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"අසාර්ථක වූ අස්ථාපන"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"අස්ථාපනය කරමින්…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> අස්ථාපනය කරමින්…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"අස්ථාපනය කිරීම අවසානයි."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear මත ස්ථාපන/අස්ථාපනය ක්‍රියා සහාය දක්වන්නේ නැත."</string>
+    <string name="message_staging" msgid="8032722385658438567">"යෙදුම වේදිකාගත කරමින්..."</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"නොදනී"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"ආරක්ෂාව සඳහා, ඔබගේ ටැබ්ලටය මෙම මුලාශ්‍රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"ආරක්ෂාව සඳහා, ඔබගේ රූපවාහිනිය මෙම මුලාශ්‍රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"ආරක්ෂාව සඳහා, ඔබගේ දුරකථනය මෙම මුලාශ්‍රයෙන් ලබාගත් නොදන්නා යෙදුම් ස්ථාපනය කිරීමට අවසර නැත."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"ඔබගේ දුරකථනය සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ දුරකථනය සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්‍රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"ඔබගේ ටැබ්ලට් පරිගණකය සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ ටැබ්ලට් පරිගණකය සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්‍රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ඔබගේ TV සහ පුද්ගලික දත්තවලට නොදන්නා යෙදුම් මඟින් තර්ජන එල්ල කිරීමේ හැකියාව වැඩිය. මෙම යෙදුම් ස්ථාපනය කිරීමෙන් සහ භාවිත කිරීමෙන් ඔබ ඔබේ TV සඳහා සිදු වන යම් හානි හෝ එය භාවිත කිරීමේ ප්‍රතිඵලයක් ලෙස සිදු වන දත්ත හානි සඳහා ඔබ වගකිව යුතු බවට එකඟ වේ."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"ඉදිරියට යන්න"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"සැකසීම්"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear යෙදුම් ස්ථාපනය/අස්ථාපනය කරමින්"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml
index a27f650..f8e1e01 100644
--- a/packages/PackageInstaller/res/values-sk/strings.xml
+++ b/packages/PackageInstaller/res/values-sk/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"Nástroj na inštaláciu balíčkov"</string>
-    <string name="next" msgid="3057143178373252333">"Ďalej"</string>
-    <string name="install" msgid="5896438203900042068">"Inštalovať"</string>
-    <string name="done" msgid="3889387558374211719">"Hotovo"</string>
-    <string name="cancel" msgid="8360346460165114585">"Zrušiť"</string>
-    <string name="installing" msgid="8613631001631998372">"Inštaluje sa..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Inštaluje sa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikácia bola nainštalovaná."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Chcete nainštalovať túto aplikáciu? Získa nasledujúce povolenia:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Chcete nainštalovať túto aplikáciu? Nevyžaduje žiadny zvláštny prístup."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Chcete nainštalovať aktualizáciu existujúcej aplikácie? Existujúce údaje sa nestratia. Aktualizovaná aplikácia získa nasledujúce povolenia:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Chcete nainštalovať aktualizáciu tejto integrovanej aplikácie? Existujúce údaje sa nestratia. Aktualizovaná aplikácia získa nasledujúce povolenia:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Chcete nainštalovať aktualizáciu tejto existujúcej aplikácie? Vaše údaje nebudú stratené. Táto akcia nevyžaduje žiadny zvláštny prístup."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Chcete nainštalovať aktualizáciu tejto vstavanej aplikácie? Vaše údaje sa nestratia. Táto akcia nevyžaduje žiadny zvláštny prístup."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikácia nebola nainštalovaná."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Inštalácia balíka bola zablokovaná."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikácia sa nenainštalovala, pretože balík koliduje s existujúcim balíkom."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikácia sa nenainštalovala, pretože nie je kompatibilná s vaším tabletom."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Táto aplikácia nie je kompatibilná s vaším televízorom."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikácia sa nenainštalovala, pretože nie je kompatibilná s vaším telefónom."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikácia sa nenainštalovala, pretože je balík zrejme neplatný."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa do vášho tabletu nepodarilo nainštalovať."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo nainštalovať na vašom televízore."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa do vášho telefónu nepodarilo nainštalovať."</string>
-    <string name="launch" msgid="4826921505917605463">"Otvoriť"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Váš správca zakázal inštaláciu aplikácií z neznámych zdrojov"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Tento používateľ nemôže inštalovať neznáme aplikácie"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Tento používateľ nemá povolené inštalovať aplikácie"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Spravovať aplikácie"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nedostatok miesta"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo nainštalovať. Uvoľnite miesto v pamäti a skúste to znova."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikácia sa nenašla"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikáciu sa nepodarilo nájsť v zozname nainštalovaných aplikácií."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nie je povolené"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Aktuálny používateľ nemá na odinštalovanie povolenie."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Chyba"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikáciu nie je možné odinštalovať."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Odinštalovať aplikáciu"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Odinštalovať aktualizáciu"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"Aktivita <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je súčasťou nasledujúcej aplikácie:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Chcete túto aplikáciu odinštalovať?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Chcete odinštalovať túto aplikáciu pre "<b>"všetkých"</b>" používateľov? Aplikácia a jej údaje sa odstránia z tohto zariadenia pre "<b>"všetkých"</b>" používateľov."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Chcete túto aplikáciu odinštalovať pre používateľa <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Nahradiť túto aplikáciu továrenskou verziou? Všetky údaje sa odstránia."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Nahradiť túto aplikáciu továrenskou verziou? Všetky údaje sa odstránia. Ovplyvní to všetkých používateľov tohto zariadenia vrátane tých s pracovnými profilmi."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Prebiehajúce odinštalácie"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neúspešné odinštalácie"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Prebieha odinštalovanie..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Prebieha odinštalovanie balíčka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Odinštalovanie bolo dokončené."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Balíček <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odinštalovaný"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Odinštalovanie bolo neúspešné."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Odinštalovanie balíčka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa nepodarilo."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktívna aplikácia na správu zariadenia sa nedá odinštalovať"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Aktívna aplikácia na správu zariadenia sa v prípade používateľa <xliff:g id="USERNAME">%1$s</xliff:g> nedá odinštalovať"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Táto aplikácia sa vyžaduje v prípade niektorých používateľov či profilov a v prípade iných zase bola odinštalovaná"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Táto aplikácia sa vyžaduje pre váš profil a nemôžete ju odinštalovať."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Túto aplikáciu vyžaduje správca vášho zariadenia a nie je ju možné odinštalovať."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Spravovať aplikácie na ovládanie zariadenia"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Spravovať používateľov"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo odinštalovať."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Pri analýze balíka sa vyskytol problém."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nové"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Všetko"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Ochrana súkromia"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Prístup k zariadeniu"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Táto aktualizácia nevyžaduje žiadne nové povolenia."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Odmietnuť"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Ďalšie informácie"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Zamietnuť"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> z <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vždy povoliť aplikácii &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Iba počas používania aplikácie"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Vždy"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Zamietnuť a nabudúce sa nepýtať"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"deaktivované (<xliff:g id="COUNT">%1$d</xliff:g>)"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"všetky sú zakázané"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"žiadne nie sú zakázané"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Povoliť"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikácie"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Povolenia aplikácií"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Nabudúce sa nepýtať"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Žiadne povolenia"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Ďalšie povolenia"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Otvoriť informácie o aplikácii"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> ďalšie</item>
-      <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> ďalšieho</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ďalších</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ďalšie</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Táto aplikácia bola navrhnutá pre staršiu verziu systému Android. Odmietnutie povolenia môže spôsobiť, že nebude optimálne fungovať."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"umožňuje vykonať neznámu akciu"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Povolené <xliff:g id="COUNT_0">%1$d</xliff:g> z <xliff:g id="COUNT_1">%2$d</xliff:g> aplikácií"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Zobraziť systémové aplikácie"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Skryť systémové aplikácie"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Žiadne aplikácie"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Nastavenia polohy"</string>
-    <string name="location_warning" msgid="8778701356292735971">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je poskytovateľ služieb určovania polohy tohto zariadenia. Prístup k polohe môžete upraviť v nastaveniach polohy."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ak toto povolenie zamietnete, základné funkcie vášho zariadenia nemusia pracovať podľa očakávaní."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Vynútené pravidlom"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Prístup na pozadí je zakázaný pravidlom"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Prístup na pozadí je povolený pravidlom"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Prístup na popredí je povolený pravidlom"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Ovládané správcom"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Vždy"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Iba počas používania aplikácie"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nikdy"</string>
-    <string name="loading" msgid="7811651799620593731">"Načítava sa…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Všetky povolenia"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Ďalšie možnosti aplikácie"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Žiadosť o povolenie"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Bolo zistené prekrytie obrazovky"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Ak chcete zmeniť nastavenie tohto povolenia, musíte najprv v časti Nastavenia &gt; Aplikácie vypnúť prekrytie obrazovky"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Otvoriť nastavenia"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Systém Wear nepodporuje akciu inštalácie/odinštalovania."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Vyberte, k čomu môže pristupovať aplikácia &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikácia &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; bola aktualizovaná. Vyberte, k čomu môže pristupovať."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Zrušiť"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Pokračovať"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nové povolenia"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Aktuálne povolenia"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Aplikácia je zavádzaná po etapách…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Neznáma"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Váš tablet nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Váš televízor nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Váš telefón nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Váš telefón a osobné údaje sú náchylnejšie na útok z neznámych aplikácií. Inštalovaním tejto aplikácie súhlasíte, že zodpovedáte za akékoľvek poškodenie vášho telefónu či stratu údajov, ku ktorým môže dôjsť v dôsledku jej použitia."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Váš tablet a osobné údaje sú náchylnejšie na útok z neznámych aplikácií. Inštalovaním tejto aplikácie súhlasíte, že zodpovedáte za akékoľvek poškodenie vášho tabletu či stratu údajov, ku ktorým môže dôjsť v dôsledku jej použitia."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Váš televízor a osobné údaje sú náchylnejšie na útok z neznámych aplikácií. Inštalovaním tejto aplikácie súhlasíte, že zodpovedáte za akékoľvek poškodenie vášho televízora či stratu údajov, ku ktorým môže dôjsť v dôsledku jej použitia."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Pokračovať"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Nastavenia"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Inštalácia/odinštalácia aplikácií Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Nástroj na inštaláciu balíkov"</string>
+    <string name="install" msgid="711829760615509273">"Inštalovať"</string>
+    <string name="done" msgid="6632441120016885253">"Hotovo"</string>
+    <string name="cancel" msgid="1018267193425558088">"Zrušiť"</string>
+    <string name="installing" msgid="4921993079741206516">"Inštaluje sa…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Inštaluje sa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikácia bola nainštalovaná."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Chcete túto aplikáciu nainštalovať?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Chcete nainštalovať aktualizáciu tejto existujúcej aplikácie? Existujúce údaje sa nestratia."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Chcete nainštalovať aktualizáciu tejto integrovanej aplikácie? Existujúce údaje sa nestratia."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikácia nebola nainštalovaná."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Inštalácia balíka bola zablokovaná."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikácia sa nenainštalovala, pretože balík je v konflikte s existujúcim balíkom."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikácia sa nenainštalovala, pretože nie je kompatibilná s vaším tabletom."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Táto aplikácia nie je kompatibilná s vaším televízorom."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikácia sa nenainštalovala, pretože nie je kompatibilná s vaším telefónom."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikácia sa nenainštalovala, pretože balík je zrejme neplatný."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa vo vašom tablete nepodarilo nainštalovať."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa vo vašom televízore nepodarilo nainštalovať."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa vo vašom telefóne nepodarilo nainštalovať."</string>
+    <string name="launch" msgid="3952550563999890101">"Otvoriť"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Váš správca zakázal inštaláciu aplikácií z neznámych zdrojov"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Tento používateľ nemôže inštalovať neznáme aplikácie"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Tento používateľ nemá povolené inštalovať aplikácie"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Spravovať aplikácie"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nedostatok miesta"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo nainštalovať. Uvoľnite miesto v pamäti a skúste to znova."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikácia sa nenašla"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikáciu sa nepodarilo nájsť v zozname nainštalovaných aplikácií."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nepovolený"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Aktuálny používateľ nemá na odinštalovanie povolenie."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Chyba"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Aplikáciu nie je možné odinštalovať."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Odinštalovať aplikáciu"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Odinštalovať aktualizáciu"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"Aktivita <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je súčasťou nasledujúcej aplikácie:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Chcete túto aplikáciu odinštalovať?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Chcete odinštalovať túto aplikáciu pre "<b>"všetkých"</b>" používateľov? Aplikácia a jej údaje sa odstránia z tohto zariadenia pre "<b>"všetkých"</b>" používateľov."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Chcete túto aplikáciu odinštalovať pre používateľa <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Nahradiť túto aplikáciu výrobnou verziou? Všetky údaje sa odstránia."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Nahradiť túto aplikáciu výrobnou verziou? Všetky údaje sa odstránia. Ovplyvní to všetkých používateľov tohto zariadenia vrátane tých s pracovnými profilmi."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Prebiehajúce odinštalovania"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neúspešné odinštalácie"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Prebieha odinštalovanie..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Prebieha odinštalovanie balíka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Odinštalovanie bolo dokončené."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Balík <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odinštalovaný"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Nepodarilo sa odinštalovať."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Balík <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa nepodarilo odinštalovať."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktívna aplikácia na riadenie zariadenia sa nedá odinštalovať"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Aktívna aplikácia na riadenie zariadenia sa v prípade používateľa <xliff:g id="USERNAME">%1$s</xliff:g> nedá odinštalovať"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Táto aplikácia sa vyžaduje v prípade niektorých používateľov či profilov a v prípade iných zase bola odinštalovaná"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Táto aplikácia sa vyžaduje pre váš profil a nemôžete ju odinštalovať."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Túto aplikáciu vyžaduje správca vášho zariadenia a nie je ju možné odinštalovať."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Spravovať aplikácie na riadenie zariadenia"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Spravovať používateľov"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Aplikáciu <xliff:g id="APP_NAME">%1$s</xliff:g> sa nepodarilo odinštalovať."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Pri analýze balíka sa vyskytol problém."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear nepodporuje akciu inštalácie/odinštalovania."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Aplikácia je zavádzaná po etapách…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Neznáma"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Váš tablet nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Váš televízor nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Váš telefón nemôže z bezpečnostných dôvodov inštalovať neznáme aplikácie z tohto zdroja."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Váš telefón a osobné dáta sú náchylnejšie na útok z neznámych aplikácií. Inštaláciou tejto aplikácie vyjadrujete súhlas s tým, že nesiete zodpovednosť za akékoľvek poškodenie telefónu alebo stratu dát, ktoré by mohli nastať pri jej používaní."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Váš tablet a osobné dáta sú náchylnejšie na útok z neznámych aplikácií. Inštaláciou tejto aplikácie vyjadrujete súhlas s tým, že nesiete zodpovednosť za akékoľvek poškodenie tabletu alebo stratu dát, ktoré by mohli nastať pri jej používaní."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Váš televízor a osobné údaje sú náchylnejšie na útok z neznámych aplikácií. Inštaláciou tejto aplikácie vyjadrujete súhlas s tým, že nesiete zodpovednosť za akékoľvek poškodenie televízora alebo stratu údajov, ktoré by mohli nastať pri jej používaní."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Pokračovať"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Nastavenia"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Inštalácia/odinštalovanie aplikácií Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml
index 4075006..d67edd5 100644
--- a/packages/PackageInstaller/res/values-sl/strings.xml
+++ b/packages/PackageInstaller/res/values-sl/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"Namestitveno orodje za paket"</string>
-    <string name="next" msgid="3057143178373252333">"Naprej"</string>
-    <string name="install" msgid="5896438203900042068">"Namesti"</string>
-    <string name="done" msgid="3889387558374211719">"Dokončano"</string>
-    <string name="cancel" msgid="8360346460165114585">"Prekliči"</string>
-    <string name="installing" msgid="8613631001631998372">"Nameščanje …"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Nameščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikacija je nameščena."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Ali želite namestiti to aplikacijo? Imela bo dostop do:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ali želite namestiti to aplikacijo? Poseben dostop ni potreben."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Ali želite namestiti posodobitev te obstoječe aplikacije? Obstoječi podatki ne bodo izgubljeni. Posodobljena aplikacija bo imela dostop do:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ali želite namestiti posodobitev za to vgrajeno aplikacijo? Obstoječi podatki ne bodo izgubljeni. Posodobljena aplikacija bo imela dostop do:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ali želite namestiti posodobitev te obstoječe aplikacije? Obstoječi podatki ne bodo izgubljeni. Za namestitev ne potrebujete posebnega dostopa."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ali želite namestiti posodobitev te vgrajene aplikacije? Obstoječi podatki ne bodo izgubljeni. Za namestitev ne potrebujete posebnega dostopa."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikacija ni nameščena."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Namestitev paketa je bila blokirana."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacija ni bila nameščena, ker je paket v navzkrižju z obstoječim paketom."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacija ni bila nameščena, ker ni združljiva s tabličnim računalnikom."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ta aplikacija ni združljiva z vašim televizorjem."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacija ni bila nameščena, ker ni združljiva s telefonom."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacija ni bila nameščena, ker paket verjetno ni veljaven."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v tablični računalnik."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v vašem televizorju."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v telefon."</string>
-    <string name="launch" msgid="4826921505917605463">"Odpri"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Skrbnik ne dovoli nameščanja aplikacij iz neznanih virov."</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Ta uporabnik nima dovoljenja za nameščanje neznanih aplikacij"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ta uporabnik nima dovoljenja za nameščanje aplikacij"</string>
-    <string name="ok" msgid="3468756155452870475">"V redu"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Upravljaj aplikacije"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Zmanjkalo je prostora"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti. Sprostite prostor in poskusite znova."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacije ni bilo mogoče najti"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacije ni bilo mogoče najti na seznamu nameščenih aplikacij."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ni dovoljeno"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Trenutni uporabnik nima dovoljenja za izvedbo te odstranitve."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Napaka"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikacije ni bilo mogoče odstraniti."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Odstrani aplikacijo"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Odstrani posodobitev"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je del te aplikacije:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Ali želite odstraniti to aplikacijo?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ali želite odstraniti aplikacijo za "<b>"vse"</b>" uporabnike? Aplikacija in njeni podatki bodo odstranjeni iz "<b>"vseh"</b>" uporabnikov v napravi."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ali želite to aplikacijo odstraniti za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki. To vpliva na vse uporabnike te naprave, vključno s tistimi z delovnimi profili."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Odstranitve v teku"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Neuspele odstranitve"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Odstranjevanje ..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Odstranjevanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Odstranitev je končana."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je bila odstranjena"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Odstranitev ni uspela."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Odstranjevanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ni uspelo."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Aktivne skrbniške aplikacije naprave ni mogoče odstraniti"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Aktivne skrbniške aplikacije za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g> ni mogoče odstraniti"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Aplikacija je obvezna za nekatere uporabnike/profile in je odstranjena za druge."</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ta aplikacija je potrebna za profil in je ni mogoče odstraniti."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"To aplikacijo zahteva skrbnik naprave in je ni mogoče odstraniti."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Upravljanje skrbniških aplikacij naprave"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Upravljanje uporabnikov"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče odstraniti."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Težava pri razčlenjevanju paketa."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Novo"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Vse"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Zasebnost"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Dostop do naprave"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Za to posodobitev niso potrebna nova dovoljenja."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Zavrni"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Več informacij"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Vseeno zavrni"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> od <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Ali dovolite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; izvesti to dejanje: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Želite aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; vedno dovoliti to dejanje: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Samo med uporabo aplikacije"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Vedno"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Zavrni in ne sprašuj več"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"št. onemogočenih: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"vse onemogočeno"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"nič ni onemogočeno"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Dovoli"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacije"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Dovoljenja za aplikacije"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ne sprašuj več"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Ni dovoljenj"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Dodatna dovoljenja"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Odpri podatke o aplikaciji"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Še <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="two">Še <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="few">Še <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Še <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ta aplikacija je bila zasnovana za starejšo različico sistema Android. Če dovoljenje zavrnete, lahko preneha delovati, kot bi morala."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"izvedba neznanega dejanja"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Dovoljene aplikacije: <xliff:g id="COUNT_0">%1$d</xliff:g> od <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Prikaz sistemskih aplikacij"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Skrivanje sistemskih aplikacij"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Ni aplikacij"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Nastavitve lokacije"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> je ponudnik lokacijskih storitev za to napravo. Dostop do lokacije je mogoče spremeniti v nastavitvah lokacije."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Če zavrnete to dovoljenje, osnovne funkcije naprave morda ne bodo več delovale, kot bi morale."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Uveljavlja pravilnik"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Dostop iz ozadja je onemogočen s pravilnikom"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Dostop iz ozadja je omogočen s pravilnikom"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Dostop v ospredju je omogočen s pravilnikom"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Nadzira skrbnik"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Vedno"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Samo med uporabo aplikacije"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Nikoli"</string>
-    <string name="loading" msgid="7811651799620593731">"Nalaganje …"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Vsa dovoljenja"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Druge zmožnosti aplikacije"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Zahteva za dovoljenje"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Zaznano prekrivanje zaslona"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Če želite spremeniti nastavitev tega dovoljenja, morate najprej izklopiti prekrivanje zaslona v »Nastavitve &gt; Aplikacije«"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Odpri nastavitve"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Dejanja namestitve in odstranitve v sistemu Android Wear niso podprta."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Izberite, do česa aplikaciji &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; dovolite dostop"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Aplikacija &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; je posodobljena. Izberite, do česa tej aplikaciji dovolite dostop."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Prekliči"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Naprej"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nova dovoljenja"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Trenutna dovoljenja"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Priprava aplikacije …"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Neznano"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Vaš tablični računalnik zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Vaš televizor zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Vaš telefon zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Neznane aplikacije lahko resno ogrozijo varnost telefona in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v telefonu, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Neznane aplikacije lahko resno ogrozijo varnost tabličnega računalnika in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v tabličnem računalniku, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Neznane aplikacije lahko resno ogrozijo varnost televizorja in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v televizorju, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Nadaljuj"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Nastavitve"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Nameščanje/odstranjev. aplikacij za Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Namest. program za paket"</string>
+    <string name="install" msgid="711829760615509273">"Namesti"</string>
+    <string name="done" msgid="6632441120016885253">"Končano"</string>
+    <string name="cancel" msgid="1018267193425558088">"Prekliči"</string>
+    <string name="installing" msgid="4921993079741206516">"Nameščanje …"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Nameščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikacija je nameščena."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Ali želite namestiti to aplikacijo?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Ali želite namestiti posodobitev te obstoječe aplikacije? Obstoječi podatki ne bodo izgubljeni."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Ali želite namestiti posodobitev te vgrajene aplikacije? Obstoječi podatki ne bodo izgubljeni."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikacija ni nameščena."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Namestitev paketa je bila blokirana."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacija ni bila nameščena, ker je paket v navzkrižju z obstoječim paketom."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikacija ni bila nameščena, ker ni združljiva s tabličnim računalnikom."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ta aplikacija ni združljiva z vašim televizorjem."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikacija ni bila nameščena, ker ni združljiva s telefonom."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikacija ni bila nameščena, ker je paket poškodovan."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v tablični računalnik."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v televizor."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti v telefon."</string>
+    <string name="launch" msgid="3952550563999890101">"Odpri"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Skrbnik ne dovoli nameščanja aplikacij iz neznanih virov."</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Ta uporabnik nima dovoljenja za nameščanje neznanih aplikacij"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ta uporabnik nima dovoljenja za nameščanje aplikacij"</string>
+    <string name="ok" msgid="7871959885003339302">"V redu"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Upravlj. aplik."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Zmanjkalo je prostora"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče namestiti. Sprostite prostor in poskusite znova."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikacije ni mogoče najti"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikacije ni bilo mogoče najti na seznamu nameščenih aplikacij."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Ni dovoljeno"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Trenutni uporabnik nima dovoljenja za izvedbo te odstranitve."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Napaka"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Aplikacije ni bilo mogoče odstraniti."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Odstrani aplikacijo"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Odstrani posodobitev"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> je del te aplikacije:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Ali želite odstraniti to aplikacijo?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Ali želite odstraniti aplikacijo za "<b>"vse"</b>" uporabnike? Aplikacija in njeni podatki bodo odstranjeni iz "<b>"vseh"</b>" uporabnikov v napravi."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Ali želite to aplikacijo odstraniti za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki. To vpliva na vse uporabnike te naprave, vključno s tistimi z delovnimi profili."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Odstranitve v teku"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspele odstranitve"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Odstranjevanje …"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Odstranjevanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Odstranitev je končana."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je bila odstranjena"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Odstranitev ni uspela."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Odstranjevanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ni uspelo."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Aktivne skrbniške aplikacije naprave ni mogoče odstraniti"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Aktivne skrbniške aplikacije za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g> ni mogoče odstraniti"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Aplikacija je obvezna za nekatere uporabnike/profile in je odstranjena za druge."</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ta aplikacija je potrebna za profil in je ni mogoče odstraniti."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"To aplikacijo zahteva skrbnik naprave in je ni mogoče odstraniti."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Upravljanje skrbniških aplikacij naprave"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Upravljanje uporabnikov"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Aplikacije <xliff:g id="APP_NAME">%1$s</xliff:g> ni bilo mogoče odstraniti."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Težava pri razčlenjevanju paketa."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Dejanja namestitve in odstranitve v sistemu Android Wear niso podprta."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Priprava aplikacije …"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Neznano"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Vaš tablični računalnik zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Vaš televizor zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Vaš telefon zaradi varnosti nima dovoljenja za nameščanje neznanih aplikacij iz tega vira."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Neznane aplikacije lahko resno ogrozijo varnost telefona in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v telefonu, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Neznane aplikacije lahko resno ogrozijo varnost tabličnega računalnika in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v tabličnem računalniku, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Neznane aplikacije lahko resno ogrozijo varnost televizorja in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v televizorju, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Naprej"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Nastavitve"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Nameščanje/odstranjev. aplikacij za Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sq/strings.xml b/packages/PackageInstaller/res/values-sq/strings.xml
index 8f7e0fc..7c06656 100644
--- a/packages/PackageInstaller/res/values-sq/strings.xml
+++ b/packages/PackageInstaller/res/values-sq/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Instaluesi i paketës"</string>
-    <string name="next" msgid="3057143178373252333">"Përpara"</string>
-    <string name="install" msgid="5896438203900042068">"Instalo"</string>
-    <string name="done" msgid="3889387558374211719">"U krye!"</string>
-    <string name="cancel" msgid="8360346460165114585">"Anulo"</string>
-    <string name="installing" msgid="8613631001631998372">"Po instalon…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Po instalon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Aplikacioni u instalua."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Dëshiron ta instalosh këtë aplikacion? Ai do të ketë qasje në:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Dëshiron ta instalosh këtë aplikacion? Nuk kërkon ndonjë qasje të veçantë."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Dëshiron të instalosh një përditësim në këtë aplikacion ekzistues? Të dhënat e tua ekzistuese nuk do të humbin. Aplikacioni i përditësuar do të ketë qasje në:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Dëshiron të instalosh një përditësim në këtë aplikacion të integruar? Të dhënat e tua ekzistuese nuk do të humbin. Aplikacioni i përditësuar do të ketë qasje në:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Dëshiron të instalosh një përditësim të këtij aplikacioni ekzistues? Të dhënat e tua ekzistuese nuk do të humbasin. Aplikacioni nuk kërkon ndonjë qasje të veçantë."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Dëshiron të instalosh një përditësim të këtij aplikacioni ekzistues? Të dhënat e tua ekzistuese nuk do të humbasin. Aplikacioni nuk kërkon ndonjë qasje të veçantë."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Aplikacioni nuk u instalua."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Instalimi paketës u bllokua."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Aplikacioni nuk u instalua pasi paketa është në konflikt me një paketë ekzistuese."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Aplikacioni nuk u instalua pasi nuk është i përputhet me tabletin tënd."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ky aplikacion është i papërshtatshëm me televizorin tënd."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Aplikacioni nuk u instalua pasi nuk përputhet me telefonin tënd."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Aplikacioni nuk u instalua pasi paketa duket se nuk është e vlefshme."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej në tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej në televizor."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mundi të instalohej në telefon."</string>
-    <string name="launch" msgid="4826921505917605463">"Hap"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratori nuk lejon instalimin e aplikacioneve nga burime të panjohura."</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Aplikacionet e panjohura nuk mund të instalohen nga ky përdorues"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Ky përdorues nuk lejohet të instalojë aplikacione"</string>
-    <string name="ok" msgid="3468756155452870475">"Në rregull"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Menaxho aplikacionet"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nuk ka hapësirë"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej. Liro pak hapësirë dhe provo përsëri."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Aplikacioni nuk u gjet"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Aplikacioni nuk u gjet në listën e aplikacioneve të instaluara."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Nuk lejohet"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Përdoruesi aktual nuk lejohet të kryejë këtë çinstalim."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Gabim"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Aplikacioni nuk mund të instalohej."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Çinstalo aplikacionin"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Çinstalo përditësimin"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> është pjesë e aplikacionit të mëposhtëm:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Dëshiron ta çinstalosh këtë aplikacion?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Dëshiron ta çinstalosh këtë aplikacion për "<b>"të gjithë"</b>" përdoruesit? Aplikacioni dhe të dhënat e tij do të hiqen nga "<b>"të gjithë"</b>" përdoruesit e pajisjes."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Dëshiron ta çinstalosh këtë aplikacion për përdoruesin <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Të zëvendësohet ky aplikacion me versionin e fabrikës? Të gjitha të dhënat do të hiqen."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Të zëvendësohet ky aplikacion me versionin e fabrikës? Të gjitha të dhënat do të hiqen. Kjo ndikon te të gjithë përdoruesit e kësaj pajisjeje, duke përfshirë ata me profile të punës."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Çinstalimet në ekzekutim"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Çinstalimet e dështuara"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Po e çinstalon…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> po çinstalohet…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Çinstalimi përfundoi."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> u çinstalua"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Çinstalimi nuk pati sukses."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Çinstalimi i <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nuk u krye me sukses."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Nuk mund të çinstalohet aplikacioni aktiv i administratorit të pajisjes"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Nuk mund të çinstalohet aplikacioni aktiv i administratorit të pajisjes për <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ky aplikacion kërkohet për disa përdorues ose profile dhe është çinstaluar për të tjerët"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ky aplikacion nevojitet për profilin tënd dhe nuk mund të çinstalohet."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ky aplikacion kërkohet nga administratori i pajisjes dhe nuk mund të çinstalohet."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Menaxho aplikacionet e administratorit të pajisjes"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Menaxho përdoruesit"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mundi të çinstalohej."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Kishte një problem me analizimin e paketës."</string>
-    <string name="newPerms" msgid="6039428254474104210">"E re"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Të gjitha"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privatësia"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Qasja në pajisje"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Ky përditësim nuk kërkon leje të reja."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Refuzo"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Informacione të tjera"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Refuzo sidoqoftë"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> nga <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Të lejohet &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; që të <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Të lejohet gjithmonë &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; që <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Vetëm gjatë përdorimit të aplikacionit"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Gjithmonë"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Refuzo dhe mos pyet përsëri"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> të çaktivizuara"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"të gjitha të çaktivizuara"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"asnjë e çaktivizuar"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Lejo"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Aplikacionet"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Lejet e aplikacionit"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Mos pyet përsëri"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Nuk ka leje"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Lejet shtesë"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Hap informacionet e aplikacionit"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> të tjera</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> të tjera</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ky aplikacion është projektuar për një version më të vjetër të Android. Refuzimi i lejeve mund të shkaktojë që ai të mos funksionojë më siç duhet."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"kryej një veprim të panjohur"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> aplikacione nga <xliff:g id="COUNT_1">%2$d</xliff:g> të tilla u lejuan"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Shfaq sistemin"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Fshih sistemin"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Asnjë aplikacion"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Cilësimet e vendndodhjeve"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> është një ofrues i shërbimeve të vendndodhjes për këtë pajisje. Qasja e vendndodhjes mund të modifikohet nga cilësimet e vendndodhjes."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Nëse e refuzon këtë leje, funksionet bazë të pajisjes tënde mund të mos funksionojnë më siç pritet."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Zbatuar nga politika"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Qasja në sfond është e çaktivizuar sipas politikës"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Qasja në sfond është e aktivizuar sipas politikës"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Qasja në planin e parë është e aktivizuar sipas politikës"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kontrolluar nga administratori"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Gjithmonë"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Vetëm gjatë përdorimit të aplikacionit"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Asnjëherë"</string>
-    <string name="loading" msgid="7811651799620593731">"Po ngarkon..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Të gjitha lejet"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Kapacitete të tjera të aplikacionit"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Kërkesa e lejes"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Mbivendosja e ekranit u zbulua"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Për të ndryshuar këtë cilësim të lejes, në fillim duhet të çaktivizosh mbivendosjen e ekranit nga Cilësimet &gt; Aplikacionet"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Hap cilësimet"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Teknologjia \"Android\" që vishet"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Instalo/çinstalo veprimet që nuk mbështeten në teknologjinë që vishet."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Zgjidh se ku do të lejohet të ketë qasje &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; është përditësuar. Zgjidh se ku do të lejohet të ketë qasje ky aplikacion."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Anulo"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Vazhdo"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Lejet e reja"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Lejet aktuale"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Po vihet në përdorim aplikacioni..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"E panjohur"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Për sigurinë tënde, tableti yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Për sigurinë tënde, televizori yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Për sigurinë tënde, telefoni yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefoni dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj telefonit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tableti dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj tabletit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Televizori dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj televizorit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Vazhdo"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Cilësimet"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Instalimi/çinstalimi i aplikacioneve të \"Wear\""</string>
+    <string name="app_name" msgid="7488448184431507488">"Instaluesi i paketës"</string>
+    <string name="install" msgid="711829760615509273">"Instalo"</string>
+    <string name="done" msgid="6632441120016885253">"U krye"</string>
+    <string name="cancel" msgid="1018267193425558088">"Anulo"</string>
+    <string name="installing" msgid="4921993079741206516">"Po instalohet…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Po instalohet <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Aplikacioni u instalua."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Dëshiron ta instalosh këtë aplikacion?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Dëshiron të instalosh një përditësim të këtij aplikacioni ekzistues? Të dhënat e tua ekzistuese nuk do të humbasin."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Dëshiron të instalosh një përditësim të këtij aplikacioni ekzistues? Të dhënat e tua ekzistuese nuk do të humbasin."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Aplikacioni nuk u instalua."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Instalimi paketës u bllokua."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Aplikacioni nuk u instalua pasi paketa është në konflikt me një paketë ekzistuese."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Aplikacioni nuk u instalua pasi nuk është i përputhet me tabletin tënd."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ky aplikacion është i papërshtatshëm me televizorin tënd."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Aplikacioni nuk u instalua pasi nuk përputhet me telefonin tënd."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Aplikacioni nuk u instalua pasi paketa duket se nuk është e vlefshme."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej në tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej në televizor."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej në telefon."</string>
+    <string name="launch" msgid="3952550563999890101">"Hap"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administratori nuk lejon instalimin e aplikacioneve nga burime të panjohura."</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Aplikacionet e panjohura nuk mund të instalohen nga ky përdorues"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Ky përdorues nuk lejohet të instalojë aplikacione"</string>
+    <string name="ok" msgid="7871959885003339302">"Në rregull"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Menaxho aplikacionet"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nuk ka hapësirë"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të instalohej. Liro pak hapësirë dhe provo përsëri."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Aplikacioni nuk u gjet"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Aplikacioni nuk u gjet në listën e aplikacioneve të instaluara."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Nuk lejohet"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Përdoruesi aktual nuk lejohet të kryejë këtë çinstalim."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Gabim"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Aplikacioni nuk mund të instalohej."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Çinstalo aplikacionin"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Çinstalo përditësimin"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> është pjesë e aplikacionit të mëposhtëm:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Dëshiron ta çinstalosh këtë aplikacion?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Dëshiron ta çinstalosh këtë aplikacion për "<b>"të gjithë"</b>" përdoruesit? Aplikacioni dhe të dhënat e tij do të hiqen nga "<b>"të gjithë"</b>" përdoruesit e pajisjes."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Dëshiron ta çinstalosh këtë aplikacion për përdoruesin <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Të zëvendësohet ky aplikacion me versionin e fabrikës? Të gjitha të dhënat do të hiqen."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Të zëvendësohet ky aplikacion me versionin e fabrikës? Të gjitha të dhënat do të hiqen. Kjo ndikon te të gjithë përdoruesit e kësaj pajisjeje, duke përfshirë ata me profile të punës."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Çinstalimet në ekzekutim"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Çinstalimet e dështuara"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Po çinstalohet…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> po çinstalohet…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Çinstalimi përfundoi."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> u çinstalua"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Çinstalimi nuk pati sukses."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Çinstalimi i <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> nuk u krye me sukses."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Nuk mund të çinstalohet aplikacioni aktiv i administratorit të pajisjes"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Nuk mund të çinstalohet aplikacioni aktiv i administratorit të pajisjes për <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ky aplikacion kërkohet për disa përdorues ose profile dhe është çinstaluar për të tjerët"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ky aplikacion nevojitet për profilin tënd dhe nuk mund të çinstalohet."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ky aplikacion kërkohet nga administratori i pajisjes dhe nuk mund të çinstalohet."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Menaxho aplikacionet e administratorit të pajisjes"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Menaxho përdoruesit"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk mund të çinstalohej."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Kishte një problem me analizimin e paketës."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Instalo/çinstalo veprimet që nuk mbështeten në Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Po vihet në përdorim aplikacioni..."</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"I panjohur"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Për sigurinë tënde, tableti yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Për sigurinë tënde, televizori yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Për sigurinë tënde, telefoni yt nuk lejohet të instalojë aplikacione të panjohura nga ky burim."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefoni dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj telefonit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tableti dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj tabletit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Televizori dhe të dhënat e tua personale janë më të cenueshme për t\'u sulmuar nga aplikacione të panjohura. Duke instaluar këtë aplikacion, ti pranon se je përgjegjës për çdo dëm ndaj televizorit tënd ose çdo humbje të dhënash që mund të rezultojë nga përdorimi i tij."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Vazhdo"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Cilësimet"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Instalimi/çinstalimi i aplikacioneve të Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml
index 494b0d4..9ff859a 100644
--- a/packages/PackageInstaller/res/values-sr/strings.xml
+++ b/packages/PackageInstaller/res/values-sr/strings.xml
@@ -16,142 +16,76 @@
 
 <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="2738748390251381682">"Упаковани програм за инсталацију"</string>
-    <string name="next" msgid="3057143178373252333">"Даље"</string>
-    <string name="install" msgid="5896438203900042068">"Инсталирај"</string>
-    <string name="done" msgid="3889387558374211719">"Готово"</string>
-    <string name="cancel" msgid="8360346460165114585">"Откажи"</string>
-    <string name="installing" msgid="8613631001631998372">"Инсталирање..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Инсталира се <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Апликација је инсталирана."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Желите ли да инсталирате ову апликацију? Имаће приступ следећем:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Желите ли да инсталирате ову апликацију? Не захтева посебан приступ."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Желите ли да инсталирате ажурирање за ову постојећу апликацију? Постојећи подаци неће бити изгубљени. Ажурирана апликација имаће приступ следећем:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Желите ли да инсталирате ажурирање за ову уграђену апликацију? Постојећи подаци неће бити изгубљени. Ажурирана апликација ће имати приступ следећем:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Да ли желите да инсталирате ажурирање ове постојеће апликације? Постојећи подаци неће бити изгубљени. Није потребан посебан приступ."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Да ли желите да инсталирате ажурирање ове уграђене апликације? Постојећи подаци неће бити изгубљени. Није потребан посебан приступ."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Апликација није инсталирана."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Инсталирање пакета је блокирано."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Апликација није инсталирана јер је пакет неусаглашен са постојећим пакетом."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Апликација није инсталирана јер није компатибилна са таблетом."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ова апликација није компатибилна са ТВ-ом."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Апликација није инсталирана јер није компатибилна са телефоном."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Апликација није инсталирана јер је пакет неважећи."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Није могуће инсталирати апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на таблет."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Нисмо успели да инсталирамо <xliff:g id="APP_NAME">%1$s</xliff:g> на ТВ."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Није могуће инсталирати апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на телефон."</string>
-    <string name="launch" msgid="4826921505917605463">"Отвори"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Администратор не дозвољава инсталирање апликација добијених из непознатих извора"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Овај корисник не може да инсталира непознате апликације"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Овом кориснику није дозвољено да инсталира апликације"</string>
-    <string name="ok" msgid="3468756155452870475">"Потврди"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Управљање апликацијама"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Нема више места"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Није могуће инсталирати апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>. Ослободите додатни простор и покушајте поново."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Апликација није пронађена"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Апликација није пронађена на листи инсталираних апликација."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Није дозвољено"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Актуелном кориснику није дозвољено да обави ово деинсталирање."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Грешка"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Деинсталирање апликације није успело."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Деинсталирање апликације"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Деинсталирање ажурирања"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> је део следеће апликације:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Да ли желите да деинсталирате ову апликацију?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Да ли желите да деинсталирате ову апликацију за "<b>"све"</b>" кориснике? Апликација и подаци који се на њу односе биће уклоњени за "<b>"све"</b>" кориснике овог уређаја."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Желите ли да деинсталирате ову апликацију за корисника <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени. Ово утиче на све кориснике овог уређаја, укључујући и оне са профилима за Work."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Активна деинсталирања"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Неуспела деинсталирања"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Деинсталирање..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Деинсталирање је завршено."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Апликација <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> је деинсталирана"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Деинсталирање није успело."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Деинсталирање апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> није успело."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Не можете да деинсталирате апликацију за активног администратора уређаја"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Не можете да деинсталирате апликацију за активног администратора уређаја за <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ова апликација је потребна за неке кориснике или профиле, а деинсталирана је за друге"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ова апликација је потребна за ваш профил и не може да се деинсталира."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ова апликација је потребна администратору уређаја и не може да се деинсталира."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Управљај апликацијама за администраторе уређаја"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Управљаj корисницима"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Није могуће деинсталирати апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Дошло је до проблема при рашчлањивању пакета."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Ново"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Све"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Приватност"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Приступ уређају"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Ово ажурирање не захтева нове дозволе."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Одбаци"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Више информација"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Ипак одбиј"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>. од <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Желите ли да дозволите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Желите ли увек да дозволите да &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Само док се апликација користи"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Увек"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Одбиј и не питај поново"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Онемогућених: <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"све су онемогућене"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ниједна није онемогућена"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Дозволи"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Апликације"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Дозволе за апликације"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Не питај поново"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Нема дозвола"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Додатне дозволе"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Отвори информације о апликацији"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">још <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="few">још <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">још <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ова апликација је дизајнирана за старију верзију Android-а. Ако одбијете дозволу, она можда више неће правилно да функционише."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"обавља непознату радњу"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> од <xliff:g id="COUNT_1">%2$d</xliff:g> апликација има дозволу"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Прикажи системске"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Сакриј системске"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Нема апликација"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Подешавања локације"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> пружа услуге локације за овај уређај. Приступ локацији можете да измените у подешавањима локације."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Ако одбијете ову дозволу, основне функције уређаја можда неће више функционисати исправно."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Примењује се у складу са смерницама"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Приступ у позадини је онемогућен смерницама"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Приступ у позадини је омогућен смерницама"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Приступ у првом плану је омогућен смерницама"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Контролише администратор"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Увек"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Само док се апликација користи"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Никада"</string>
-    <string name="loading" msgid="7811651799620593731">"Учитава се…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Све дозволе"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Остале могућности апликације"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Захтев за дозволу"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Откривен је елемент који прекрива садржај екрана"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Да бисте променили подешавање ове дозволе, прво треба да искључите елемент који прекрива садржај екрана у одељку Подешавања &gt; Апликације"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Отвори подешавања"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Радње Инсталирај/Деинсталирај нису подржане у Wear-у."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Изаберите чему &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; може да приступа"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Апликација &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; је ажурирана. Изаберите чему ова апликација може да приступа."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Откажи"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Настави"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Нове дозволе"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Актуелне дозволе"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Апликација се припрема…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Непознато"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Таблету из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Телевизору из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Телефону из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Телефон и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења телефона или губитак података до којих може да дође због њеног коришћења."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Таблет и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења таблета или губитак података до којих може да дође због њеног коришћења."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ТВ и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења ТВ-а или губитак података до којих може да дође због њеног коришћења."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Настави"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Подешавања"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Инсталирање/деинсталирање Wear апликација"</string>
+    <string name="app_name" msgid="7488448184431507488">"Програм за инстал. пакета"</string>
+    <string name="install" msgid="711829760615509273">"Инсталирај"</string>
+    <string name="done" msgid="6632441120016885253">"Готово"</string>
+    <string name="cancel" msgid="1018267193425558088">"Откажи"</string>
+    <string name="installing" msgid="4921993079741206516">"Инсталира се..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"Инсталира се <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Апликација је инсталирана."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Желите ли да инсталирате ову апликацију?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Желите ли да инсталирате ажурирање за ову постојећу апликацију? Постојећи подаци се неће изгубити."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Желите ли да инсталирате ажурирање за ову уграђену апликацију? Постојећи подаци се неће изгубити."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Апликација није инсталирана."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Инсталирање пакета је блокирано."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Апликација није инсталирана јер је пакет неусаглашен са постојећим пакетом."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Апликација није инсталирана јер није компатибилна са таблетом."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ова апликација није компатибилна са ТВ-ом."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Апликација није инсталирана јер није компатибилна са телефоном."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Апликација није инсталирана јер је пакет неважећи."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g> на таблет."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Овај корисник не може да инсталира непознате апликације"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Овом кориснику није дозвољено да инсталира апликације"</string>
+    <string name="ok" msgid="7871959885003339302">"Потврди"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Управљајте апл."</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Нема више простора"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Нисмо успели да инсталирамо апликацију <xliff:g id="APP_NAME">%1$s</xliff:g>. Ослободите простор и пробајте поново."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Апликација није пронађена"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Апликација није пронађена на листи инсталираних апликација."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Није дозвољено"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Актуелном кориснику није дозвољено да обави ово деинсталирање."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Грешка"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Деинсталирање апликације није успело."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Деинсталирај апликацију"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Деинсталирај ажурирање"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> је део следеће апликације:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Желите ли да деинсталирате ову апликацију?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Да ли желите да деинсталирате ову апликацију за "<b>"све"</b>" кориснике? Апликација и подаци уз ње биће уклоњени за "<b>"све"</b>" кориснике овог уређаја."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Желите ли да деинсталирате ову апликацију за корисника <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Желите ли да замените ову апликацију фабричком верзијом? Сви подаци ће бити уклоњени. Ово утиче на све кориснике овог уређаја, укључујући и оне са профилима за Work."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Активна деинсталирања"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Неуспела деинсталирања"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Деинсталира се…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталира…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Деинсталирање је завршено."</string>
+    <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_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_users" msgid="1243995386982560813">"Управљаjте корисницима"</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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Радње Инсталирај/Деинсталирај нису подржане у Wear-у."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Апликација се припрема…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Непознато"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Таблету из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Телевизору из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Телефону из безбедносних разлога није дозвољено да инсталира непознате апликације из овог извора."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефон и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења телефона или губитак података до којих може да дође због њеног коришћења."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблет и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења таблета или губитак података до којих може да дође због њеног коришћења."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ТВ и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења ТВ-а или губитак података до којих може да дође због њеног коришћења."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Настави"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Подешавања"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Инсталирање/деинсталирање Wear апликац."</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sv/strings.xml b/packages/PackageInstaller/res/values-sv/strings.xml
index ff4f4c1..43c2aad 100644
--- a/packages/PackageInstaller/res/values-sv/strings.xml
+++ b/packages/PackageInstaller/res/values-sv/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Installationsprogram för paket"</string>
-    <string name="next" msgid="3057143178373252333">"Nästa"</string>
-    <string name="install" msgid="5896438203900042068">"Installera"</string>
-    <string name="done" msgid="3889387558374211719">"Färdig"</string>
-    <string name="cancel" msgid="8360346460165114585">"Avbryt"</string>
-    <string name="installing" msgid="8613631001631998372">"Installerar…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeras …"</string>
-    <string name="install_done" msgid="3682715442154357097">"Appen har installerats."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Vill du installera den här appen? Den får åtkomst till:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Vill du installera den här appen? Den kräver ingen särskild åtkomst."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Vill du installera en uppdatering till den här befintliga appen? Dina befintliga data försvinner inte. Den uppdaterade appen får åtkomst till:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Vill du installera en uppdatering till den här befintliga förinstallerade appen? Dina befintliga data försvinner inte. Den uppdaterade appen får åtkomst till:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Vill du installera en uppdatering av den befintliga appen? Dina befintliga data försvinner inte. Ingen särskild åtkomst krävs."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Vill du installera en uppdatering av den inbyggda appen? Dina befintliga data försvinner inte. Ingen särskild åtkomst krävs."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Appen har inte installerats."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Paketet har blockerats för installation."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Appen har inte installerats på grund av en konflikt mellan detta paket och ett befintligt paket."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Appen har inte installerats eftersom den inte är kompatibel med surfplattan."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Appen är inte kompatibel med din TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Appen har inte installerats eftersom den inte är kompatibel med mobilen."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Appen har inte installerats eftersom paketet verkar vara ogiltigt."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Det gick inte att installera <xliff:g id="APP_NAME">%1$s</xliff:g> på surfplattan."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunde inte installeras på TV:n."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Det gick inte att installera <xliff:g id="APP_NAME">%1$s</xliff:g> på mobilen."</string>
-    <string name="launch" msgid="4826921505917605463">"Öppna"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratören tillåter inte installation av appar från okända källor"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Denna användare får inte installera okända appar"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Användaren har inte behörighet att installera appar"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Hantera appar"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Slut på utrymme"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Det gick inte att installera <xliff:g id="APP_NAME">%1$s</xliff:g>. Frigör minne och försök igen."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Appen hittades inte"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Appen fanns inte i listan över installerade appar."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ingen behörighet"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Den aktuella användaren har inte behörighet att utföra avinstallationen."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Fel"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Det gick inte att installera appen."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Avinstallera appen"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Avinstallera uppdateringen"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> är en del av följande app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Vill du avinstallera appen?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Vill du avinstallera den här appen för "<b>"alla"</b>" användare? Appen och alla data i den tas bort från "<b>"alla"</b>" användare på enheten."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Vill du avinstallera appen för användaren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Vill du ersätta den här appen med den version som var installerad när enheten var ny? All information tas bort."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Vill du ersätta den här appen med den version som var installerad när enheten var ny? All information tas bort. Detta påverkar alla som använder enheten, även dem med jobbprofiler."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Avinstallationer som pågår"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Avinstallationer som misslyckats"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Avinstallerar…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> avinstalleras …"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Avinstallationen har slutförts."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> har avinstallerats"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Det gick inte att avinstallera."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Det gick inte att avinstallera <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Det går inte att avinstallera den aktiva appen för enhetsadministratör"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Det går inte att avinstallera den aktiva appen för enhetsadministratör för <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Den här appen är obligatorisk för vissa användare och profiler och har avinstallerats för andra"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Appen behövs i profilen och det går inte att avinstallera den"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Appen krävs av enhetsadministratören och kan därför inte avinstalleras."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Hantera appar för enhetsadministratör"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Hantera användare"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Det gick inte att avinstallera <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Ett problem uppstod när paketet analyserades."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Nytt"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Alla"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Sekretess"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Enhetsåtkomst"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Det krävs inga nya behörigheter för den här uppdateringen."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Neka"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Mer information"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Neka ändå"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> av <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Tillåter du &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; att <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Vill du alltid tillåta att &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Bara när appen används"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Alltid"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Neka och fråga inte igen"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> har inaktiverats"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"alla har inaktiverats"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"inga har inaktiverats"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Tillåt"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Appar"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Appens behörigheter"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Fråga inte igen"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Inga behörigheter"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Ytterligare behörigheter"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Öppna appinformation"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> till</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> till</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Den här appen utformades för en äldre version av Android. Om du nekar appen behörighet kan det hända att den inte längre fungerar som den ska."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"utför en okänd åtgärd"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> av <xliff:g id="COUNT_1">%2$d</xliff:g> appar tillåts"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Visa systemet"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Dölj systemet"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Inga appar"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Platsinställningar"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> är en platstjänstleverantör för enheten. Platsåtkomsten kan redigeras i platsinställningarna."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Om du nekar appen behörighet kan det hända att grundläggande funktioner på enheten inte fungerar som de ska."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Enligt policyn"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Åtkomst i bakgrunden har inaktiverats av en princip"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Åtkomst i bakgrunden har aktiverats av en princip"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Åtkomst i förgrunden har aktiverats av en princip"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Styrs av administratören"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Alltid"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Bara när appen används"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Aldrig"</string>
-    <string name="loading" msgid="7811651799620593731">"Läser in …"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Alla behörigheter"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Andra appbehörigheter"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Begäran om behörighet"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Skärmöverlagring har upptäckts"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Innan du kan ändra den här behörighetsinställningen måste du inaktivera skärmöverlagring under Inställningar &gt; Appar"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Öppna inställningarna"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Åtgärder för att installera/avinstallera stöds inte på Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Välj vad du vill ge &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; åtkomst till"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; har uppdaterats. Välj vad du vill ge appen åtkomst till."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Avbryt"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Fortsätt"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Nya behörigheter"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Nuvarande behörighet"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Provkör appen …"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Okänd"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Av säkerhetsskäl får okända appar från den här källan inte installeras av surfplattan."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Av säkerhetsskäl får okända appar från den här källan inte installeras av TV:n."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Av säkerhetsskäl får okända appar från den här källan inte installeras av mobilen."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Din mobil och personliga data är mer sårbara för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på mobilen och för dataförlust som kan uppstå vid användning av denna app."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Din surfplatta och personliga data är mer sårbara för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på surfplattan och för dataförlust som kan uppstå vid användning av denna app."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Din TV och personliga data är mer sårbara för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på TV:n och för dataförlust som kan uppstå vid användning av denna app."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Fortsätt"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Inställningar"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear-appar installeras/avinstalleras"</string>
+    <string name="app_name" msgid="7488448184431507488">"Paketinstallationsprogram"</string>
+    <string name="install" msgid="711829760615509273">"Installera"</string>
+    <string name="done" msgid="6632441120016885253">"Klar"</string>
+    <string name="cancel" msgid="1018267193425558088">"Avbryt"</string>
+    <string name="installing" msgid="4921993079741206516">"Installerar …"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> installeras …"</string>
+    <string name="install_done" msgid="5987363587661783896">"Appen har installerats."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Vill du installera det här programmet?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Vill du installera en uppdatering till den här befintliga appen? Dina befintliga data försvinner inte."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Vill du installera en uppdatering av den inbyggda appen? Dina befintliga data försvinner inte."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Appen har inte installerats."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paketet har blockerats för installation."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Appen har inte installerats på grund av en konflikt mellan detta paket och ett befintligt paket."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Appen har inte installerats eftersom den inte är kompatibel med surfplattan."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Appen är inte kompatibel med din tv."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Appen har inte installerats eftersom den inte är kompatibel med mobilen."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Appen har inte installerats eftersom paketet verkar vara ogiltigt."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Det gick inte att installera <xliff:g id="APP_NAME">%1$s</xliff:g> på pekdatorn."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> kunde inte installeras på tv:n."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Det gick inte att installera <xliff:g id="APP_NAME">%1$s</xliff:g> på mobilen."</string>
+    <string name="launch" msgid="3952550563999890101">"Öppna"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administratören tillåter inte installation av appar från okända källor"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Denna användare får inte installera okända appar"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Användaren har inte behörighet att installera appar"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Hantera appar"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Slut på utrymme"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Det gick inte att avinstallera <xliff:g id="APP_NAME">%1$s</xliff:g>. Frigör minne och försök igen."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Appen hittades inte"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Appen fanns inte i listan över installerade appar."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Tillåts inte"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Den aktuella användaren har inte behörighet att utföra avinstallationen."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Fel"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Det gick inte att installera appen."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Avinstallera appen"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Avinstallera uppdatering"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> är en del av följande app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Vill du avinstallera appen?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Vill du avinstallera den här appen för "<b>"alla"</b>" användare? Appen och alla data i den tas bort från "<b>"alla"</b>" användare på enheten."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Vill du avinstallera appen för användaren <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Vill du ersätta den här appen med den version som var installerad när enheten var ny? All information tas bort."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Vill du ersätta den här appen med den version som var installerad när enheten var ny? All information tas bort. Detta påverkar alla som använder enheten, även dem med jobbprofiler."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Avinstallationer som pågår"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Avinstallationer som misslyckats"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Avinstallerar …"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> avinstalleras …"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Avinstallationen har slutförts."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> har avinstallerats"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Det gick inte att avinstallera."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Det gick inte att avinstallera <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Det går inte att avinstallera den aktiva appen för enhetsadministratör"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Det går inte att avinstallera den aktiva appen för enhetsadministratör för <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Den här appen är obligatorisk för vissa användare och profiler och har avinstallerats för andra"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Appen behövs i profilen och det går inte att avinstallera den"</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Appen krävs av enhetsadministratören och kan därför inte avinstalleras."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Hantera appar för enhetsadministratör"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Hantera användare"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Det gick inte att avinstallera <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Ett problem uppstod när paketet analyserades."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Åtgärder för att installera/avinstallera stöds inte på Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Provkör appen …"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Okänd"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Av säkerhetsskäl får okända appar från den här källan inte installeras av surfplattan."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Av säkerhetsskäl får okända appar från den här källan inte installeras av TV:n."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Av säkerhetsskäl får okända appar från den här källan inte installeras av mobilen."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Din mobil och personliga data är mer sårbara för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på mobilen och för dataförlust som kan uppstå vid användning av denna app."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Din surfplatta och personliga data är mer sårbara för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på surfplattan och för dataförlust som kan uppstå vid användning av denna app."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Din tv och personliga data är mer sårbar för attacker från okända appar. Genom att installera denna app bekräftar du att du är ansvarig för eventuella skador på tv:n och för dataförlust som kan uppstå vid användning av denna app."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Fortsätt"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Inställningar"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear-appar installeras/avinstalleras"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-sw/strings.xml b/packages/PackageInstaller/res/values-sw/strings.xml
index c431983..1c07291 100644
--- a/packages/PackageInstaller/res/values-sw/strings.xml
+++ b/packages/PackageInstaller/res/values-sw/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Kisakinishaji cha furushi"</string>
-    <string name="next" msgid="3057143178373252333">"Inayofuata"</string>
-    <string name="install" msgid="5896438203900042068">"Sakinisha"</string>
-    <string name="done" msgid="3889387558374211719">"Nimemaliza"</string>
-    <string name="cancel" msgid="8360346460165114585">"Ghairi"</string>
-    <string name="installing" msgid="8613631001631998372">"inawekwa..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Inasakinisha <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Programu imewekwa."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Je, ungependa kuiweka programu hii? Itaweza:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Je, ungependa kuiweka programu hii? Haihitaji idhini ya kufikia kitu chochote."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Je, unataka kuweka sasisho katika programu hii? Data yako iliyopo haitapotea. Programu iliyosasishwa itaweza:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Je, unataka kuweka sasisho la programu hii iliyojengewa ndani? Data yako iliyopo haitapotea. Programu iliyosasishwa itaweza:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Je, unataka kuweka sasisho la programu hii? Data yako iliyopo haitapotea. Haihitaji idhini yoyote maalum ya kufikia."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Je, unataka kuweka sasisho la programu hii? Data yako iliyopo haitapotea. Haihitaji idhini yoyote maalum ya kufikia."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Programu haikusakinishwa."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Kifurushi kimezuiwa kisisakinishwe."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Programu haikusakinishwa kwa sababu haiafikiani na kifurushi kingine kilichopo."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Programu haikusakinishwa kwa sababu haioani na kompyuta kibao yako."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Programu hii haioani na runinga yako."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Programu haikusakinishwa kwa sababu haioani na simu yako."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Programu haikusakinishwa kwa sababu inaonekana kuwa kifurushi si sahihi."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> haikuweza kusakinishwa kwenye kompyuta yako kibao."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> haikuweza kusakinishwa kwenye runinga yako."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> haikuweza kusakinishwa kwenye simu yako."</string>
-    <string name="launch" msgid="4826921505917605463">"Fungua"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Msimamizi wako haruhusu usakinishaji wa programu zinazopatikana kutoka vyanzo visivyojulikana"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Mtumiaji huyu hana idhini ya kusakinisha programu ambazo hazijulikani"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Mtumiaji huyu haruhusiwi kusakinisha programu"</string>
-    <string name="ok" msgid="3468756155452870475">"Sawa"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Dhibiti programu"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Nafasi imeisha"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> haingeweza kusakinishwa. Wezesha nafasi kiasi na ujaribu tena."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Programu haikupatikana"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Programu haikupatikana katika orodha ya programu zilizosakinishwa."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Hairuhusiwi"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Mtumiaji wa sasa hana ruhusa ya kuondoa kipengee hiki."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Hitilafu"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Imeshindwa kuondoa programu."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Sanidua programu"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Sanidua kisasisho"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ni sehemu ya programu ifuatayo:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Unataka kusanidua programu hii?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Je, unataka kusanidua programu hii kwa "<b>"watumiaji"</b>" wote? Programu na data yake zitaondolewa kutoka kwa "<b>"watumiaji"</b>" kwenye kifaa."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Je, unataka kuondoa programu hii kwa mtumiaji <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Ungependa kubadilisha programu hii na toleo la kiwanda? Data yote itaondolewa."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Ungependa kubadilisha programu hii na toleo la kiwanda? Data yote itaondolewa. Hatua hii itaathiri watumiaji wote wa kifaa hiki, ikiwa ni pamoja na wale walio na wasifu za kazini."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Mara ambazo programu inaondolewa sasa"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mara ambazo programu haikuondolewa"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Inasanidua..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Inaondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Imesaniduliwa."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Imeondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Kusanidua hakukufaulu."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Imeshindwa kuondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Imeshindwa kuondoa programu inayotumika ya msimamizi wa kifaa"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Imeshindwa kuondoa programu inayotumika ya msimamizi wa kifaa cha <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Baadhi ya wasifu au watumiaji wanahitaji programu, kwa hivyo haijaondolewa kwa wengine"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Programu hii inahitajika kwa wasifu wako kwa hivyo haiwezi kuondolewa."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Programu hii inahitajika na msimamizi wako wa kifaa na haiwezi kuondolewa."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Dhibiti programu za msimamizi wa kifaa"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Dhibiti watumiaji"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> haingeweza kusaniduliwa."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Kulikuwa na tatizo la kuchanganua furushi."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Mpya"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Zote"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Faragha"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Kufikia Kifaa"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Sasisho hili halihitaji vibali vipya."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Hapana"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Maelezo zaidi"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Kataa"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> kati ya <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Ungependa kuruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Ungependa kuruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; itekeleze <xliff:g id="ACTION">%2$s</xliff:g> kila wakati?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Wakati unatumia programu tu"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Kila wakati"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Kataa na usiulize tena"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> zimezimwa"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"zimezimwa zote"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"hakuna zilizozimwa"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Ndiyo"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Programu"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Ruhusa za programu"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Usiulize tena"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Hakuna ruhusa"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Ruhusa za ziada"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Fungua maelezo ya programu"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> zaidi</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> zaidi</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Programu hii iliundwa kwa ajili ya toleo la zamani la Android. Kuinyima ruhusa kunaweza kusababisha iache kutenda kazi kama ilivyokusudiwa."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"kutekeleza kitendo kisichojulikana"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Inaruhusu programu <xliff:g id="COUNT_0">%1$d</xliff:g> kati ya <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Onyesha mfumo"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ficha mfumo"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Hakuna programu"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Mipangilio ya Mahali"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> hutoa huduma za mahali kwenye kifaa hiki. Idhini ya kufikia mahali inaweza kurekebishwa katika mipangilio ya mahali."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Usipokubali ruhusa hii, huenda vipengele vya msingi vya kifaa chako havitafanya kazi kama ilivyokusudiwa."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Hutekelezwa na sera"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Ufikiaji wa chinichini umezimwa na sera"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Ufikiaji wa chinichini umewashwa na sera"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Ufikiaji wa hadharani umewashwa na sera"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Imedhibitiwa na msimamizi"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Kila wakati"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Wakati unatumia programu tu"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Kamwe"</string>
-    <string name="loading" msgid="7811651799620593731">"Inapakia…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Ruhusa zote"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Uwezo mwingine wa programu"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Ombi la idhini"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Imetambua tangazo lililowekelewa juu ya skrini"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Ili kubadilisha mpangilio huu wa ruhusa, ni lazima kwanza uzime tangazo lililowekelewa juu ya skrini kwenye Mipangilio na Programu"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Fungua mipangilio"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Huduma ya Android Wear haiwezi kutekeleza vitendo vya Kusakinisha au Kuondoa vipengee."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Chagua vipengee ambavyo unaruhusu &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifikie"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; imesasishwa. Chagua vipengee unavyoruhusu programu hii ifikie."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Ghairi"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Endelea"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Ruhusa mpya"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Ruhusa zilizopo"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Inatayarisha programu..."</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Isiyojulikana"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Kwa sababu ya usalama wako, kompyuta yako kibao haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Kwa sababu ya usalama wako, TV yako haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Kwa sababu ya usalama wako, simu yako haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Data yako ya binafsi na ya simu yako inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibika kutokana na uharibifu wowote kwenye simu yako au kupotea kwa data kutokana na matumizi yake."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Data yako ya binafsi na ya kompyuta yako kibao inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibika kutokana na uharibifu wowote kwenye kompyuta yako kibao au kupotea kwa data kutokana na matumizi yake."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Data yako ya binafsi na ya televisheni yako inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibika kutokana na uharibifu wowote kwenye televisheni yako au kupotea kwa data kutokana na matumizi yake."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Endelea"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Mipangilio"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Inasakinisha/inaondoa programu za Android Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Kisakinishaji cha kifurushi"</string>
+    <string name="install" msgid="711829760615509273">"Sakinisha"</string>
+    <string name="done" msgid="6632441120016885253">"Nimemaliza"</string>
+    <string name="cancel" msgid="1018267193425558088">"Ghairi"</string>
+    <string name="installing" msgid="4921993079741206516">"Inasakinisha…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Inasakinisha <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Imesakinisha programu."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Je, ungependa kusakinisha programu hii?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Je, ungependa kusakinisha sasisho la programu iliyopo? Data yako iliyopo haitapotea."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Je, ungependa kusakinisha sasisho la programu hii iliyopakiwa ndani? Data yako iliyopo haitapotea."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Imeshindwa kusakinisha programu."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Kifurushi kimezuiwa kisisakinishwe."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Programu haikusakinishwa kwa sababu kifurushi kinakinzana na kifurushi kingine kilichopo."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Programu haikusakinishwa kwa sababu haioani na kompyuta yako kibao."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Programu hii haioani na runinga yako."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Programu haikusakinishwa kwa sababu haioani na simu yako."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Programu haikusakinishwa kwa sababu inaonekana kuwa kifurushi si sahihi."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Imeshindwa kusakinisha <xliff:g id="APP_NAME">%1$s</xliff:g> kwenye kompyuta yako kibao."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Imeshindwa kusakinisha <xliff:g id="APP_NAME">%1$s</xliff:g> kwenye TV yako."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Imeshindwa kusakinisha <xliff:g id="APP_NAME">%1$s</xliff:g> kwenye simu yako."</string>
+    <string name="launch" msgid="3952550563999890101">"Fungua"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Msimamizi wako haruhusu usakinishaji wa programu zinazopatikana kutoka vyanzo visivyojulikana"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Mtumiaji huyu hana idhini ya kusakinisha programu ambazo hazijulikani"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Mtumiaji huyu haruhusiwi kusakinisha programu"</string>
+    <string name="ok" msgid="7871959885003339302">"Sawa"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Dhibiti programu"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Nafasi imejaa"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Imeshindwa kusakinisha <xliff:g id="APP_NAME">%1$s</xliff:g>. Futa baadhi ya maudhui ili upate nafasi kisha ujaribu tena."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Programu haikupatikana"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Programu haijapatikana katika orodha ya programu zilizosakinishwa."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Hairuhusiwi"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Mtumiaji wa sasa hana ruhusa ya kuondoa kipengee hiki."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Hitilafu"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Imeshindwa kuondoa programu."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Ondoa programu"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Ondoa sasisho"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ni sehemu ya programu ifuatayo:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Ungependa kuondoa programu hii?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Je, ungependa kuondoa programu hii kwa watumiaji "<b>"wote"</b>"? Programu na data yake zitaondolewa kutoka kwa watumiaji "<b>"wote"</b>" kwenye kifaa."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Je, ungependa kuondoa programu hii kwa mtumiaji <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Ungependa kubadilisha programu hii na toleo la kiwandani? Data yote itaondolewa."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Ungependa kubadilisha programu hii na toleo la kiwandani? Data yote itaondolewa. Hatua hii itaathiri watumiaji wote wa kifaa hiki, ikiwa ni pamoja na wale walio na wasifu za kazini."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Programu zinazoondolewa"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mara ambazo programu haikuondolewa"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Inaondoa…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Inaondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Imeondolewa."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Imeondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Imeshindwa kuondoa."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Imeshindwa kuondoa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Imeshindwa kuondoa programu inayotumika ya msimamizi wa kifaa"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Imeshindwa kuondoa programu inayotumika ya msimamizi wa kifaa cha <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Baadhi ya wasifu au watumiaji wanahitaji programu, kwa hivyo haijaondolewa kwa wengine"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Programu hii inahitajika kwa wasifu wako na haiwezi kuondolewa."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Programu hii inahitajika na msimamizi wako wa kifaa na haiwezi kuondolewa."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Dhibiti programu za msimamizi wa kifaa"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Dhibiti watumiaji"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Imeshindwa kuondoa <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Kumekuwa na tatizo la kuchanganua kifurushi."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Huduma ya Android Wear haiwezi kutekeleza vitendo vya Kusakinisha au Kuondoa vipengee."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Inatayarisha programu…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Haijulikani"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Kwa sababu ya usalama wako, kompyuta yako kibao haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Kwa sababu ya usalama wako, TV yako haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Kwa sababu ya usalama wako, simu yako haina ruhusa ya kusakinisha programu ambazo hazijulikani, kutoka kwenye chanzo hiki."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Data yako ya binafsi na ya simu yako inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibikia uharibifu wowote kwenye simu yako au kupotea kwa data kutokana na matumizi yake."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Data yako ya binafsi na ya kompyuta yako kibao inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibikia uharibifu wowote kwenye kompyuta yako kibao au kupotea kwa data kutokana na matumizi yake."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Data yako ya binafsi na ya televisheni yako inaweza kuathiriwa na programu ambazo hazijulikani. Kwa kusakinisha programu hii, unakubali kuwajibikia uharibifu wowote kwenye televisheni yako au kupotea kwa data kutokana na matumizi yake."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Endelea"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Mipangilio"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Inasakinisha/inaondoa programu za Android Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ta/strings.xml b/packages/PackageInstaller/res/values-ta/strings.xml
index 366f6d9..c067bd2 100644
--- a/packages/PackageInstaller/res/values-ta/strings.xml
+++ b/packages/PackageInstaller/res/values-ta/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"பேக்கேஜ் இன்ஸ்டாலர்"</string>
-    <string name="next" msgid="3057143178373252333">"அடுத்து"</string>
-    <string name="install" msgid="5896438203900042068">"நிறுவு"</string>
-    <string name="done" msgid="3889387558374211719">"முடிந்தது"</string>
-    <string name="cancel" msgid="8360346460165114585">"ரத்துசெய்"</string>
-    <string name="installing" msgid="8613631001631998372">"நிறுவுகிறது…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவுகிறது…"</string>
-    <string name="install_done" msgid="3682715442154357097">"பயன்பாடு நிறுவப்பட்டது."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"இந்தப் பயன்பாட்டை நிறுவ விரும்புகிறீர்களா? அது இதற்கான அணுகலைப் பெறும்:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"இந்தப் பயன்பாட்டை நிறுவ விரும்புகிறீர்களா? இதற்கு எந்தத் தனிப்பட்ட அணுகலும் தேவையில்லை."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"முன்பே உள்ள இந்தப் பயன்பாட்டில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்க மாட்டீர்கள். புதுப்பிக்கப்பட்ட பயன்பாடு இதற்கான அணுகலைப் பெறும்:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"உள்ளமைக்கப்பட்ட பயன்பாட்டில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்க மாட்டீர்கள். புதுப்பிக்கப்பட்ட பயன்பாடு இதற்கான அணுகலைப் பெறும்:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"முன்பே உள்ள இந்தப் பயன்பாட்டில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்கமாட்டீர்கள். இதற்குத் தனிப்பட்ட அணுகல் எதுவும் தேவையில்லை."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"உள்ளமைக்கப்பட்ட பயன்பாட்டில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்க மாட்டீர்கள். இதற்குத் தனிப்பட்ட அணுகல் எதுவும் தேவையில்லை."</string>
-    <string name="install_failed" msgid="6579998651498970899">"பயன்பாடு நிறுவப்படவில்லை."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"இந்தத் தொகுப்பு நிறுவுவதிலிருந்து தடுக்கப்பட்டது."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"தொகுப்பானது தற்போதுள்ள தொகுப்புடன் இணக்கமற்றதாக உள்ளதால், பயன்பாடு நிறுவப்படவில்லை."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"உங்கள் டேப்லெட்டுடன் இணக்கமற்றதாக உள்ளதால், பயன்பாடு நிறுவப்படவில்லை."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"உங்கள் டிவியுடன் இந்தப் பயன்பாடு இணங்கவில்லை."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"உங்கள் மொபைலுடன் இணக்கமற்றதாக உள்ளதால், பயன்பாடு நிறுவப்படவில்லை."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"தொகுப்பு தவறானது போல் உள்ளதால், பயன்பாடு நிறுவப்படவில்லை."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாட்டை உங்கள் டேப்லெட்டில் நிறுவ முடியாது."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"உங்கள் டிவியில் <xliff:g id="APP_NAME">%1$s</xliff:g>ஐ நிறுவ முடியவில்லை."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாட்டை உங்கள் மொபைலில் நிறுவ முடியாது."</string>
-    <string name="launch" msgid="4826921505917605463">"திற"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"அறியப்படாத மூலங்களிலிருந்து பெற்ற பயன்பாடுகளை நிறுவ, உங்கள் நிர்வாகி அனுமதிக்கவில்லை"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"அறியப்படாத பயன்பாடுகளை, இந்தப் பயனர் நிறுவ முடியாது"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"பயன்பாடுகளை நிறுவ, இந்தப் பயனருக்கு அனுமதியில்லை"</string>
-    <string name="ok" msgid="3468756155452870475">"சரி"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"பயன்பாடுகளை நிர்வகிக்கவும்"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"இடம் இல்லை"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாட்டை நிறுவ முடியாது. சில இடத்தைக் காலி செய்து மீண்டும் முயற்சிக்கவும்."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"பயன்பாடு கண்டறியப்படவில்லை"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"நிறுவிய பயன்பாடுகளின் பட்டியலில் பயன்பாடு இல்லை."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"அனுமதிக்கப்படவில்லை"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"இதை நிறுவல் நீக்குவதற்கு, தற்போதைய பயனர் அனுமதிக்கப்படவில்லை."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"பிழை"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"பயன்பாட்டை நிறுவல் நீக்க முடியவில்லை."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"பயன்பாட்டை நிறுவல் நீக்கு"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"புதுப்பிப்பை நிறுவல் நீக்கு"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ஆனது பின்வரும் பயன்பாட்டின் பகுதியாகும்:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"இந்தப் பயன்பாட்டை நிறுவல் நீக்க விரும்புகிறீர்களா?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"இந்தப் பயன்பாட்டை "<b>"எல்லா"</b>" பயனர்களுக்கும் நிறுவல் நீக்க விரும்புகிறீர்களா? பயன்பாடும், அதன் தரவும் சாதனத்தில் உள்ள "<b>"எல்லா"</b>" பயனர்களிடமிருந்தும் அகற்றப்படும்."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> பயனருக்கான இந்தப் பயன்பாட்டை நிறுவல்நீக்க விரும்புகிறீர்களா?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ஆரம்பநிலைப் பதிப்பாக இந்தப் பயன்பாட்டை மாற்றியமைக்கவா? எல்லா தரவும் அகற்றப்படும்."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ஆரம்பநிலைப் பதிப்பாக இந்தப் பயன்பாட்டை மாற்றியமைக்கவா? எல்லா தரவும் அகற்றப்படும். பணிச் சுயவிவரங்களுடன் உள்ளவர்கள் உட்பட இந்தச் சாதனத்தின் எல்லா பயனர்களையும் இது பாதிக்கும்."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"இயக்கத்திலுள்ள நிறுவல் நீக்கங்கள்"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"தோல்வியடைந்த நிறுவல் நீக்கங்கள்"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"நிறுவலை நீக்குகிறது…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்குகிறது…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"நிறுவல் நீக்குவது முடிந்தது."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> நிறுவல் நீக்கப்பட்டது"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"நிறுவல் நீக்குவதில் தோல்வி."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்க முடியவில்லை."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"செயலில் உள்ள சாதன நிர்வாகிப் பயன்பாட்டை நிறுவல் நீக்க முடியாது"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g>க்கான செயலில் உள்ள சாதன நிர்வாகிப் பயன்பாட்டை நிறுவல் நீக்க முடியாது"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"இது சில பயனர்கள்/சுயவிவரங்களுக்குத் தேவைப்படுவதால், நிறுவல்நீக்க முடியாது, பிறருக்கு நிறுவல் நீக்கப்பட்டது"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"உங்கள் சுயவிவரத்திற்கு இந்தப் பயன்பாடு தேவைப்படுவதால், அதை நிறுவல்நீக்க முடியாது, பிறருக்கு நிறுவல் நீக்கப்பட்டது."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"சாதன நிர்வாகிக்கு இந்தப் பயன்பாடு தேவைப்படுவதால், நிறுவல்நீக்க முடியாது."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"சாதன நிர்வாகிப் பயன்பாடுகளை நிர்வகி"</string>
-    <string name="manage_users" msgid="3125018886835668847">"பயனர்களை நிர்வகி"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> பயன்பாட்டை நிறுவல் நீக்க முடியாது."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"தொகுப்பைக் குறியீட்டு ஆய்வு செய்வதில் சிக்கல் ஏற்பட்டது."</string>
-    <string name="newPerms" msgid="6039428254474104210">"புதிது"</string>
-    <string name="allPerms" msgid="1024385515840703981">"எல்லாம்"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"தனியுரிமை"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"சாதன அணுகல்"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"இந்தப் புதுப்பிப்பிற்குப் புதிய அனுமதிகள் எதுவும் தேவையில்லை."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"நிராகரி"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"மேலும் தகவல்"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"பரவாயில்லை, நிராகரி"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"செயலைச் செய்ய <xliff:g id="ACTION">%2$s</xliff:g>, &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ஐ அனுமதிக்கவா?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<xliff:g id="ACTION">%2$s</xliff:g>ஐச் செய்ய &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ஆப்ஸை எப்போதும் அனுமதிக்கவா?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ஆப்ஸைப் பயன்படுத்தும்போது மட்டும் அனுமதி"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"எப்போதும் அனுமதி"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"நிராகரி, மீண்டும் கேட்காதே"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> முடக்கப்பட்டன"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"எல்லாம் முடக்கப்பட்டன"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"எதுவும் முடக்கப்படவில்லை"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"அனுமதி"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ஆப்ஸ்"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"பயன்பாட்டு அனுமதிகள்"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"மீண்டும் கேட்காதே"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"அனுமதிகள் இல்லை"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"கூடுதல் அனுமதிகள்"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"பயன்பாட்டுத் தகவலைத் திற"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">மேலும் <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">மேலும் <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"இந்தப் பயன்பாடு Android இன் பழைய பதிப்புக்காக வடிவமைக்கப்பட்டது. அனுமதியை மறுத்தால் அது சரியாக செயல்படாமல் போகலாம்."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"அறியாத செயலைச் செயல்படுத்தும்"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"அனுமதிக்கப்பட்ட ஆப்ஸ்: <xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"எல்லாம் காட்டு"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"முறைமையை மறை"</string>
-    <string name="no_apps" msgid="1965493419005012569">"பயன்பாடுகள் இல்லை"</string>
-    <string name="location_settings" msgid="1774875730854491297">"இருப்பிட அமைப்புகள்"</string>
-    <string name="location_warning" msgid="8778701356292735971">"இந்தச் சாதனத்திற்கான இருப்பிடச் சேவைகளின் வழங்குநர் <xliff:g id="APP_NAME">%1$s</xliff:g> ஆகும். இருப்பிட அமைப்புகளிலிருந்து இருப்பிட அணுகலை மாற்றலாம்."</string>
-    <string name="system_warning" msgid="7103819124542305179">"இந்த அனுமதியை நிராகரித்தால், உங்கள் சாதனத்தின் அடிப்படை அம்சங்கள் சரியாகச் செயல்படாமல் போகலாம்."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"கொள்கையின் படி செயல்படுத்தப்பட்டது"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"கொள்கையின்படி பின்புல அணுகல் முடக்கப்பட்டது"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"கொள்கையின்படி பின்புல அணுகல் இயக்கப்பட்டது"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"கொள்கையின்படி முன்புல அணுகல் இயக்கப்பட்டது"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"நிர்வாகி கட்டுப்படுத்துகிறார்"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"எப்போதும்"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"ஆப்ஸை உபயோகிக்கும்போது மட்டும்"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ஒருபோதும் வேண்டாம்"</string>
-    <string name="loading" msgid="7811651799620593731">"ஏற்றுகிறது..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"எல்லா அனுமதிகளும்"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"பயன்பாட்டின் பிற திறன்கள்"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"அனுமதி கோரிக்கை"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"திரையின் மேலே செயல்படும் பயன்பாடுகள் கண்டறியப்பட்டன"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"இந்த அனுமதியை மாற்ற, அமைப்புகள் &gt; பயன்பாடுகள் என்பதற்குச் சென்று, திரையின் மேலே செயல்படும் பயன்பாடுகளை முதலில் முடக்கவும்"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"அமைப்புகளைத் திற"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear இல் நிறுவுதல்/நிறுவல் நீக்குதலுக்கு ஆதரவில்லை."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; எவற்றை அணுகலாம் என்பதைத் தேர்வுசெய்யவும்"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; புதுப்பிக்கப்பட்டது. இந்தப் பயன்பாடு எவற்றை அணுகலாம் என்பதைத் தேர்வுசெய்யவும்."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"ரத்துசெய்"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"தொடர்க"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"புதிய அனுமதிகள்"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"தற்போதைய அனுமதிகள்"</string>
-    <string name="message_staging" msgid="6151794817691100003">"பயன்பாடு தயாராகிறது…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"தெரியாதது"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"உங்கள் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து அறியப்படாத பயன்பாடுகளை உங்கள் டேப்லெட்டில் நிறுவ முடியாது."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"உங்கள் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து அறியப்படாத பயன்பாடுகளை உங்கள் டிவியில் நிறுவ முடியாது."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"உங்கள் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து அறியப்படாத பயன்பாடுகளை உங்கள் மொபைலில் நிறுவ முடியாது."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"அறியப்படாத பயன்பாடுகள், உங்கள் மொபைலையும் தனிப்பட்ட தரவையும் அதிகம் பாதிக்கக்கூடும். இந்தப் பயன்பாட்டை நிறுவுவதால், அவற்றைப் பயன்படுத்தும் போது உங்கள் மொபைலுக்கு ஏதேனும் சேதம் ஏற்பட்டாலோ அல்லது தரவை இழந்தாலோ, அதற்கு நீங்கள்தான் பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"அறியப்படாத பயன்பாடுகள், உங்கள் டேப்லெட்டையும் தனிப்பட்ட தரவையும் அதிகம் பாதிக்கக்கூடும். இந்தப் பயன்பாட்டை நிறுவுவதால், அவற்றைப் பயன்படுத்தும் போது உங்கள் டேப்லெட்டுக்கு ஏதேனும் சேதம் ஏற்பட்டாலோ அல்லது தரவை இழந்தாலோ, அதற்கு நீங்கள்தான் பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"அறியப்படாத பயன்பாடுகள், உங்கள் டிவியையும் தனிப்பட்ட தரவையும் அதிகம் பாதிக்கக்கூடும். இந்தப் பயன்பாட்டை நிறுவுவதால், அவற்றைப் பயன்படுத்தும் போது உங்கள் டிவிக்கு ஏதேனும் சேதம் ஏற்பட்டாலோ அல்லது தரவை இழந்தாலோ, அதற்கு நீங்கள்தான் பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"தொடர்க"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"அமைப்புகள்"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"வியர் ஆப்ஸை நிறுவுதல்/நிறுவல் நீக்குதல்"</string>
+    <string name="app_name" msgid="7488448184431507488">"தொகுப்பு நிறுவி"</string>
+    <string name="install" msgid="711829760615509273">"நிறுவு"</string>
+    <string name="done" msgid="6632441120016885253">"முடிந்தது"</string>
+    <string name="cancel" msgid="1018267193425558088">"ரத்துசெய்"</string>
+    <string name="installing" msgid="4921993079741206516">"நிறுவுகிறது…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவுகிறது…"</string>
+    <string name="install_done" msgid="5987363587661783896">"ஆப்ஸ் நிறுவப்பட்டது."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"இந்த ஆப்ஸை நிறுவ விரும்புகிறீர்களா?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"ஏற்கனவே உள்ள ஆப்ஸில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்கமாட்டீர்கள்."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"உள்ளமைக்கப்பட்ட ஆப்ஸில் புதுப்பிப்பை நிறுவ விரும்புகிறீர்களா? ஏற்கனவே உள்ள உங்கள் தரவை இழக்கமாட்டீர்கள்."</string>
+    <string name="install_failed" msgid="5777824004474125469">"ஆப்ஸ் நிறுவப்படவில்லை."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"இந்தத் தொகுப்பு நிறுவப்படுவதிலிருந்து தடுக்கப்பட்டது."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"இந்தத் தொகுப்பு ஏற்கனவே உள்ள தொகுப்புடன் முரண்படுவதால் ஆப்ஸ் நிறுவப்படவில்லை."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"ஆப்ஸ் உங்கள் டேப்லெட்டுடன் இணக்கமற்றதாக உள்ளதால் நிறுவப்படவில்லை."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"இந்த ஆப்ஸ் உங்கள் டிவியுடன் இணக்கமற்றதாக உள்ளது."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"ஆப்ஸ் உங்கள் மொபைலுடன் இணக்கமற்றதாக உள்ளதால் நிறுவப்படவில்லை."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"இந்தத் தொகுப்பு செல்லாததுபோல் இருப்பதால் ஆப்ஸ் நிறுவப்படவில்லை."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸை உங்கள் டேப்லெட்டில் நிறுவ இயலவில்லை."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"அறியப்படாத ஆப்ஸை இந்தப் பயனரால் நிறுவ இயலாது"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ஆப்ஸை நிறுவ இந்தப் பயனருக்கு அனுமதியில்லை"</string>
+    <string name="ok" msgid="7871959885003339302">"சரி"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"ஆப்ஸை நிர்வகி"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"போதுமான சேமிப்பிடம் இல்லை"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸை நிறுவ இயலவில்லை. சிறிது சேமிப்பிடத்தைக் காலிசெய்து மீண்டும் முயலவும்."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"ஆப்ஸ் இல்லை"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"நிறுவப்பட்ட ஆப்ஸின் பட்டியலில் இந்த ஆப்ஸ் இல்லை."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"அனுமதிக்கப்படாதவர்"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"இந்த நிறுவல் நீக்கத்தைச் செய்ய தற்போதைய பயனருக்கு அனுமதியில்லை."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"பிழை"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"ஆப்ஸை நிறுவல் நீக்க இயலவில்லை."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"ஆப்ஸை நிறுவல் நீக்குதல்"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"புதுப்பிப்பை நிறுவல் நீக்கு"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> என்பது பின்வரும் ஆப்ஸின் பகுதியாகும்:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"இந்த ஆப்ஸை நிறுவல் நீக்க விரும்புகிறீர்களா?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"இந்த ஆப்ஸை "<b>"அனைத்துப்"</b>" பயனர்களுக்கும் நிறுவல் நீக்க விரும்புகிறீர்களா? ஆப்ஸும் அதன் தரவும் சாதனத்திலுள்ள "<b>"அனைத்துப்"</b>" பயனர்களிடமிருந்தும் அகற்றப்படும்."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> என்ற பயனருக்கு இந்த ஆப்ஸை நிறுவல் நீக்க விரும்புகிறீர்களா?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ஆரம்பநிலைப் பதிப்புக்கு இந்த ஆப்ஸை மாற்றியமைக்கவா? அனைத்துத் தரவும் அகற்றப்படும்."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ஆரம்பநிலைப் பதிப்புக்கு இந்த ஆப்ஸை மாற்றியமைக்கவா? அனைத்துத் தரவும் அகற்றப்படும். பணிக் கணக்குகளுடன் உள்ளவர்கள் உட்பட இந்தச் சாதனத்தின் அனைத்துப் பயனர்களையும் இது பாதிக்கும்."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"இயக்கத்திலுள்ள நிறுவல் நீக்கங்கள்"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"தோல்வியுற்ற நிறுவல் நீக்கங்கள்"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"நிறுவல் நீக்குகிறது…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ஐ நிறுவல் நீக்குகிறது…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"நிறுவல் நீக்கம் முடிந்தது."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"நிறுவல்கள்/நிறுவல் நீக்கங்கள் Wearரில் செய்ய இயலாது"</string>
+    <string name="message_staging" msgid="8032722385658438567">"ஆப்ஸ் தயாராகிறது…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"அறியப்படாதது"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"உங்கள் சாதனத்தின் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து பெற்ற அறியப்படாத ஆப்ஸை டேப்லெட்டில் நிறுவ அனுமதியில்லை."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"உங்கள் சாதனத்தின் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து பெற்ற அறியப்படாத ஆப்ஸை டிவியில் நிறுவ அனுமதியில்லை."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"உங்கள் சாதனத்தின் பாதுகாப்பிற்காக, இந்த மூலத்திலிருந்து பெற்ற அறியப்படாத ஆப்ஸை மொபைலில் நிறுவ அனுமதியில்லை."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"அறியப்படாத ஆப்ஸால் உங்கள் மொபைலும் தனிப்பட்ட தரவும் மிக எளிதாகப் பாதிப்புக்குள்ளாகும். இந்த ஆப்ஸை நிறுவுவதன் மூலம், இதைப் பயன்படுத்தும்போது மொபைலில் ஏதேனும் சிக்கல் ஏற்பட்டாலோ உங்களது தரவை இழந்தாலோ அதற்கு நீங்களே பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"அறியப்படாத ஆப்ஸால் உங்கள் டேப்லெட்டும் தனிப்பட்ட தரவும் மிக எளிதாகப் பாதிப்புக்குள்ளாகும். இந்த ஆப்ஸை நிறுவுவதன் மூலம், இதைப் பயன்படுத்தும்போது டேப்லெட்டில் ஏதேனும் சிக்கல் ஏற்பட்டாலோ உங்களது தரவை இழந்தாலோ அதற்கு நீங்களே பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"அறியப்படாத ஆப்ஸால் உங்கள் டிவியும் தனிப்பட்ட தரவும் மிக எளிதாகப் பாதிப்புக்குள்ளாகும். இந்த ஆப்ஸை நிறுவுவதன் மூலம், இதைப் பயன்படுத்தும்போது டிவியில் ஏதேனும் சிக்கல் ஏற்பட்டாலோ உங்களது தரவை இழந்தாலோ அதற்கு நீங்களே பொறுப்பாவீர்கள் என்பதை ஏற்கிறீர்கள்."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"தொடர்க"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"அமைப்புகள்"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear ஆப்ஸை நிறுவுதல்/நிறுவல் நீக்குதல்"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-te/strings.xml b/packages/PackageInstaller/res/values-te/strings.xml
index b612385..fd0a63f 100644
--- a/packages/PackageInstaller/res/values-te/strings.xml
+++ b/packages/PackageInstaller/res/values-te/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"ప్యాకేజీ ఇన్‌స్టాలర్"</string>
-    <string name="next" msgid="3057143178373252333">"తర్వాత"</string>
-    <string name="install" msgid="5896438203900042068">"ఇన్‌స్టాల్ చేయండి"</string>
-    <string name="done" msgid="3889387558374211719">"పూర్తయింది"</string>
-    <string name="cancel" msgid="8360346460165114585">"రద్దు చేయి"</string>
-    <string name="installing" msgid="8613631001631998372">"ఇన్‌స్టాల్ చేస్తోంది…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ని ఇన్‌స్టాల్ చేస్తోంది…"</string>
-    <string name="install_done" msgid="3682715442154357097">"యాప్ ఇన్‌స్టాల్ చేయబడింది."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"మీరు ఈ అనువర్తనాన్ని ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? ఇది వీటికి ప్రాప్యతను పొందుతుంది:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"మీరు ఈ యాప్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? దీనికి ఎటువంటి ప్రత్యేక యాక్సెస్ అవసరం లేదు."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"మీరు ఈ ప్రస్తుత యాప్‌నకు అప్‌డేట్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? మీ ప్రస్తుత డేటాను కోల్పోవడం సంభవించదు. అప్‌డేట్ చేసిన యాప్ వీటికి యాక్సెస్‌ను పొందుతుంది:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"మీరు ఈ అంతర్నిర్మిత యాప్‌నకు అప్‌డేట్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? మీ ప్రస్తుత డేటాను కోల్పోవడం సంభవించదు. అప్‌డేట్ చేసిన యాప్ వీటికి యాక్సెస్  పొందుతుంది:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"మీరు ఈ ప్రస్తుత యాప్‌కు అప్‌డేట్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? మీ ప్రస్తుత డేటాను కోల్పోవడం సంభవించదు. దీనికి ఎటువంటి ప్రత్యేక యాక్సెస్ అవసరం లేదు."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"మీరు ఈ అంతర్నిర్మిత యాప్‌కు అప్‌డేట్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? మీ ప్రస్తుత డేటాను కోల్పోవడం సంభవించదు. దీనికి ఎటువంటి ప్రత్యేక యాక్సెస్ అవసరం లేదు."</string>
-    <string name="install_failed" msgid="6579998651498970899">"యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"ప్యాకేజీ ఇన్‌స్టాల్ కాకుండా బ్లాక్ చేయబడింది."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"ప్యాకేజీ ఇప్పటికే ఉన్న ప్యాకేజీకి వైరుధ్యంగా ఉన్నందున యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"యాప్ మీ టాబ్లెట్‌కు అనుకూలంగా లేని కారణంగా ఇన్‌స్టాల్ చేయబడలేదు."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"ఈ యాప్ మీ టీవీకి అనుకూలంగా లేదు."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"యాప్ మీ ఫోన్‌కు అనుకూలంగా లేని కారణంగా ఇన్‌స్టాల్ చేయబడలేదు."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"ప్యాకేజీ చెల్లుబాటు కాని విధంగా ఉన్నందున యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g>ను మీ టాబ్లెట్‌లో ఇన్‌స్టాల్ చేయడం సాధ్యపడలేదు."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని మీ టీవీలో ఇన్‌స్టాల్ చేయడం సాధ్యపడలేదు."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ను మీ ఫోన్‌లో ఇన్‌స్టాల్ చేయడం సాధ్యపడలేదు."</string>
-    <string name="launch" msgid="4826921505917605463">"తెరవండి"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"మీ నిర్వాహకులు తెలియని మూలాల నుండి పొందిన అనువర్తనాల ఇన్‌స్టాలేషన్‌ను అనుమతించరు"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"తెలియని అనువర్తనాలను ఈ వినియోగదారు ఇన్‌స్టాల్ చేయలేరు"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"యాప్‌లను ఇన్‌స్టాల్ చేయడానికి ఈ వినియోగదారుకు అనుమతి లేదు"</string>
-    <string name="ok" msgid="3468756155452870475">"సరే"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"అనువర్తనాలను నిర్వహించండి"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ఖాళీ లేదు"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని ఇన్‌స్టాల్ చేయడం సాధ్యపడలేదు. కొంత స్థలాన్ని ఖాళీ చేసి మళ్లీ ప్రయత్నించండి."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"యాప్ కనుగొనబడలేదు"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ఇన్‌స్టాల్ చేసిన యాప్‌ల జాబితాలో యాప్‌ కనుగొనబడలేదు."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"అనుమతించబడలేదు"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ప్రస్తుత వినియోగదారు ఈ అన్ఇన్‌స్టాలేషన్ చేసేందుకు అనుమతి లేదు."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"ఎర్రర్"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"అనువర్తనాన్ని అన్ఇన్‌స్టాల్ చేయడం సాధ్యపడదు."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"యాప్‌ను అన్‌ఇన్‌స్టాల్ చేయండి"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"నవీకరణను అన్‌ఇన్‌స్టాల్ చేయండి"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> అనేది క్రింది యాప్‌లో ఒక భాగం:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"మీరు ఈ యాప్‌ను అన్‌ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"మీరు ఈ యాప్‌ను "<b>"మొత్తం"</b>" వినియోగదారులకు అన్‌ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? యాప్ మరియు దీని డేటా డివైజ్‌లోని "<b>"మొత్తం"</b>" వినియోగదారుల నుండి తీసివేయబడుతుంది."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"మీరు వినియోగదారు <xliff:g id="USERNAME">%1$s</xliff:g> కోసం ఈ అనువర్తనాన్ని అన్‌ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"ఈ అనువర్తనాన్ని ఫ్యాక్టరీ సంస్కరణతో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"ఈ అనువర్తనాన్ని ఫ్యాక్టరీ సంస్కరణతో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది. దీని ప్రభావం కార్యాలయ ప్రొఫైల్‌లు కలిగి ఉన్నవారితో సహా ఈ పరికర వినియోగదారులందరిపై ఉంటుంది."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"అమల్లో ఉన్న అన్‌ఇన్‌స్టాల్‌లు"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"విఫలమైన అన్‌ఇన్‌స్టాల్‌లు"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"అన్‌ఇన్‌స్టాల్ చేస్తోంది…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ని అన్ఇన్‌స్టాల్ చేస్తోంది…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"అన్‌ఇన్‌స్టాల్ చేయడం ముగిసింది."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"అన్ఇన్‌స్టాల్ చేసిన <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"అన్‌ఇన్‌స్టాల్ చేయడం విజయవంతం కాలేదు."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> అన్ఇన్‌స్టాల్ చేయడంలో విఫలమైంది."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"సక్రియ పరికర నిర్వాహక అనువర్తనాన్ని అన్ఇన్‌స్టాల్ చేయడం సాధ్యపడదు"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> కోసం సక్రియ పరికర నిర్వాహక అనువర్తనాన్ని అన్ఇన్‌స్టాల్ చేయడం సాధ్యపడదు"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"ఈ యాప్ కొందరు వినియోగదారులకు లేదా కొన్ని ప్రొఫైల్‌లకు అవసరం, ఇతరులకు అన్‌ఇన్‌స్టాల్ చేయబడింది"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"మీ ప్రొఫైల్ కోసం ఈ యాప్ అవసరం మరియు దీన్ని అన్ఇన్‌స్టాల్ చేయలేరు."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"మీ డివైజ్ నిర్వాహకుడికి ఈ యాప్ అవసరం, అందువల్ల దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం కుదరదు."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"పరికర నిర్వాహక అనువర్తనాలను నిర్వహించు"</string>
-    <string name="manage_users" msgid="3125018886835668847">"వినియోగదారులను నిర్వహించు"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడలేదు."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"ప్యాకేజీని అన్వయించడంలో సమస్య ఏర్పడింది."</string>
-    <string name="newPerms" msgid="6039428254474104210">"కొత్తవి"</string>
-    <string name="allPerms" msgid="1024385515840703981">"అన్నీ"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"గోప్యత"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"పరికరం యాక్సెస్"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"ఈ నవీకరణకు కొత్త అనుమతులు అవసరం లేదు."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"తిరస్కరించు"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"మరింత సమాచారం"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ఏదేమైనా నిరాకరించు"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>లో <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ని <xliff:g id="ACTION">%2$s</xliff:g> అనుమతించాలా?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"<xliff:g id="ACTION">%2$s</xliff:g> చేయడానికి &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;ను ఎల్లప్పుడూ అనుమతించాలా?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ఎల్లప్పుడూ"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"నిరాకరించు, మళ్లీ అడగవద్దు"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> నిలిపివేయబడ్డాయి"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"అన్నీ నిలిపివేయబడ్డాయి"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ఏవీ నిలిపివేయబడలేదు"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"అనుమతించు"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"యాప్‌లు"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"యాప్ అనుమతులు"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"మళ్లీ అడగవద్దు"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"అనుమతులు లేవు"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"అదనపు అనుమతులు"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"యాప్ సమాచారాన్ని తెరుస్తుంది"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">మరో <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="one">మరో <xliff:g id="COUNT_0">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"ఈ యాప్ పాత Android వెర్షన్ కోసం రూపొందించబడింది. అనుమతిని నిరాకరించినట్లయితే ఇది ఇకపై ఉద్దేశించిన రీతిలో పని చేయకపోవచ్చు."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"తెలియని చర్యను చేస్తుంది"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g>లో <xliff:g id="COUNT_0">%1$d</xliff:g> యాప్‌లు అనుమతించబడ్డాయి"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"సిస్టమ్‌ను చూపు"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"సిస్టమ్‌ను దాచు"</string>
-    <string name="no_apps" msgid="1965493419005012569">"అనువర్తనాలు లేవు"</string>
-    <string name="location_settings" msgid="1774875730854491297">"స్థాన సెట్టింగ్‌లు"</string>
-    <string name="location_warning" msgid="8778701356292735971">"ఈ పరికరం కోసం స్థాన సేవల ప్రదాత <xliff:g id="APP_NAME">%1$s</xliff:g>. స్థాన సెట్టింగ్‌ల నుండి స్థాన ప్రాప్యతను సవరించవచ్చు."</string>
-    <string name="system_warning" msgid="7103819124542305179">"మీరు ఈ అనుమతిని నిరాకరిస్తే, మీ పరికర ప్రాథమిక లక్షణాలు ఇకపై ఉద్దేశించిన రీతిలో పని చేయకపోవచ్చు."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"విధానం ద్వారా అమలు చేయబడింది"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"విధానం ద్వారా నేపథ్య యాక్సెస్ నిలిపివేయబడింది"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"విధానం ద్వారా నేపథ్య యాక్సెస్ ప్రారంభించబడింది"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"విధానం ద్వారా ముందుభాగం యాక్సెస్ ప్రారంభించబడింది"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"నిర్వాహకుల నియంత్రణలో ఉంటాయి"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ఎల్లప్పుడూ"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"యాప్‌ను ఉపయోగిస్తున్నప్పుడు మాత్రమే"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ఎన్నడూ వద్దు"</string>
-    <string name="loading" msgid="7811651799620593731">"లోడ్ అవుతోంది..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"అన్ని అనుమతులు"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"ఇతర అనువర్తన సామర్థ్యాలు"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"అనుమతి అభ్యర్థన"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"స్క్రీన్ అతివ్యాప్తి గుర్తించబడింది"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ఈ అనుమతి సెట్టింగ్‌ను మార్చడానికి, మీరు ముందుగా సెట్టింగ్‌లు &gt; అనువర్తనాల నుండి స్క్రీన్ అతివ్యాప్తిని ఆఫ్ చేయాలి"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"సెట్టింగ్‌లను తెరువు"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android వేర్"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wearలో ఇన్‌స్టాల్/అన్ఇన్‌స్టాల్ చర్యలకు మద్దతు లేదు."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; యాక్సెస్ చేయడానికి అనుమతించాల్సిన వాటిని ఎంచుకోండి"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; అప్‌డేట్ చేయబడింది. ఈ యాప్ యాక్సెస్ చేయడానికి అనుమతించాల్సిన వాటిని ఎంచుకోండి."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"రద్దు చేయి"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"కొనసాగించు"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"కొత్త అనుమతులు"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"ప్రస్తుత అనుమతులు"</string>
-    <string name="message_staging" msgid="6151794817691100003">"అనువర్తనాన్ని అందిస్తోంది…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"తెలియదు"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"మీకు భద్రతను అందించడం కోసం, ఈ మూలం నుండి తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయడానికి మీ టాబ్లెట్ అనుమతించబడదు."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"మీకు భద్రతను అందించడం కోసం, ఈ మూలం నుండి తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయడానికి మీ TV అనుమతించబడదు."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"మీకు భద్రతను అందించడం కోసం, ఈ మూలం నుండి తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయడానికి మీ ఫోన్ అనుమతించబడదు."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"మీ ఫోన్ మరియు వ్యక్తిగత డేటా తెలియని మూలాల్లోని అనువర్తనాల ద్వారా దాడికి గురి కావడానికి ఎక్కువ అవకాశం ఉంటుంది. ఈ అనువర్తనాన్ని ఇన్‌స్టాల్ చేయడం ద్వారా, ఈ అనువర్తనాన్ని ఉపయోగించడం వలన మీ ఫోన్‌కు సంభవించే ఏదైనా నష్టానికి లేదా కోల్పోయే డేటాకి బాధ్యత వహించడానికి మీరు అంగీకరిస్తున్నారు."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"మీ టాబ్లెట్ మరియు వ్యక్తిగత డేటా తెలియని మూలాల్లోని అనువర్తనాల ద్వారా దాడికి గురి కావడానికి ఎక్కువ అవకాశం ఉంటుంది. ఈ అనువర్తనాన్ని ఇన్‌స్టాల్ చేయడం ద్వారా, ఈ అనువర్తనాన్ని ఉపయోగించడం ద్వారా మీ టాబ్లెట్‌కు సంభవించే ఏదైనా నష్టానికి లేదా కోల్పోయే డేటాకి బాధ్యత వహించడానికి మీరు అంగీకరిస్తున్నారు."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"మీ TV మరియు వ్యక్తిగత డేటా తెలియని మూలాల్లోని అనువర్తనాల ద్వారా దాడికి గురి కావడానికి ఎక్కువ అవకాశం ఉంటుంది. ఈ అనువర్తనాన్ని ఇన్‌స్టాల్ చేయడం ద్వారా, ఈ అనువర్తనాన్ని ఉపయోగించడం ద్వారా మీ TVకి సంభవించే ఏదైనా నష్టానికి లేదా కోల్పోయే డేటాకి బాధ్యత వహించడానికి మీరు అంగీకరిస్తున్నారు."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"కొనసాగించు"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"సెట్టింగ్‌లు"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"వేర్ ఆప్‌లను ఇన్‌స్టాల్/అన్‌ఇన్‌స్టాల్ చేస్తోంది"</string>
+    <string name="app_name" msgid="7488448184431507488">"ప్యాకేజీ ఇన్‌స్టాలర్"</string>
+    <string name="install" msgid="711829760615509273">"ఇన్‌స్టాల్ చేయి"</string>
+    <string name="done" msgid="6632441120016885253">"పూర్తయింది"</string>
+    <string name="cancel" msgid="1018267193425558088">"రద్దు చేయి"</string>
+    <string name="installing" msgid="4921993079741206516">"ఇన్‌స్టాల్ చేస్తోంది…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ని ఇన్‌స్టాల్ చేస్తోంది…"</string>
+    <string name="install_done" msgid="5987363587661783896">"యాప్ ఇన్‌స్టాల్ చేయబడింది."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"మీరు ఈ అప్లికేషన్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"మీరు ఇప్పటికే ఉన్న ఈ అప్లికేషన్‌కు అప్‌డేట్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? ఇప్పటికే ఉన్న మీ డేటాను కోల్పోవడం సంభవించదు."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"మీరు ఈ అంతర్నిర్మిత అప్లికేషన్‌కు అప్‌డేట్‌ను ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? ఇప్పటికే ఉన్న మీ డేటాను కోల్పోవడం సంభవించదు."</string>
+    <string name="install_failed" msgid="5777824004474125469">"యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"ప్యాకేజీ ఇన్‌స్టాల్ కాకుండా బ్లాక్ చేయబడింది."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"ప్యాకేజీ, అలాగే ఇప్పటికే ఉన్న ప్యాకేజీ మధ్య వైరుధ్యం ఉన్నందున యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"యాప్ మీ టాబ్లెట్‌కు అనుకూలంగా లేని కారణంగా ఇన్‌స్టాల్ చేయబడలేదు."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"ఈ యాప్ మీ టీవీకి అనుకూలంగా లేదు."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"యాప్ మీ ఫోన్‌కు అనుకూలంగా లేని కారణంగా ఇన్‌స్టాల్ చేయబడలేదు."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"ప్యాకేజీ చెల్లుబాటు కానట్లు ఉన్నందున యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"మీ టాబ్లెట్‌లో <xliff:g id="APP_NAME">%1$s</xliff:g>ని ఇన్‌స్టాల్ చేయడం సాధ్యపడలేదు."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"ఈ వినియోగదారు తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయలేరు"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"యాప్‌లను ఇన్‌స్టాల్ చేయడానికి ఈ వినియోగదారుకు అనుమతి లేదు"</string>
+    <string name="ok" msgid="7871959885003339302">"సరే"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"యాప్‌లను నిర్వహించండి"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"ఖాళీ లేదు"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g>ని ఇన్‌స్టాల్ చేయడం సాధ్యపడలేదు. కొంత స్థలాన్ని ఖాళీ చేసి మళ్లీ ప్రయత్నించండి."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"యాప్ కనుగొనబడలేదు"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ఇన్‌స్టాల్ చేసిన యాప్‌ల జాబితాలో యాప్ కనుగొనబడలేదు."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"అనుమతించబడలేదు"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"ప్రస్తుత వినియోగదారు ఈ అన్ఇన్‌స్టాలేషన్ చేసేందుకు అనుమతించబడరు."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"లోపం"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"యాప్‌ను అన్ఇన్‌స్టాల్ చేయడం సాధ్యపడలేదు."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"యాప్‌ను అన్‌ఇన్‌స్టాల్ చేయి"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"అప్‌డేట్ అన్‌ఇన్‌స్టాల్ చేయి"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> అనేది క్రింది యాప్‌లో ఒక భాగం:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"మీరు ఈ యాప్‌ను అన్‌ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"మీరు ఈ యాప్‌ను "<b>"అందరు"</b>" వినియోగదారులకు అన్‌ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా? అప్లికేషన్, దాని డేటా పరికరంలోని "<b>"అందరు"</b>" వినియోగదారుల నుండి తీసివేయబడుతుంది."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"మీరు వినియోగదారు <xliff:g id="USERNAME">%1$s</xliff:g> కోసం ఈ యాప్‌ను అన్‌ఇన్‌స్టాల్ చేయాలనుకుంటున్నారా?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"ఈ యాప్‌ను ఫ్యాక్టరీ వెర్షన్‌తో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"ఈ యాప్‌ను ఫ్యాక్టరీ వెర్షన్‌తో భర్తీ చేయాలా? మొత్తం డేటా తీసివేయబడుతుంది. దీని ప్రభావం కార్యాలయ ప్రొఫైల్‌లు కలిగి ఉన్నవారితో సహా ఈ పరికర వినియోగదారులందరిపై ఉంటుంది."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"అన్ఇన్‌స్టాల్ చేయబడుతున్నవి"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"విఫలమైన అన్‌ఇన్‌స్టాల్‌లు"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"అన్ఇన్‌స్టాల్ చేస్తోంది…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>ని అన్ఇన్‌స్టాల్ చేస్తోంది…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"అన్‌ఇన్‌స్టాల్ చేయడం ముగిసింది."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wearలో ఇన్‌స్టాల్/అన్ఇన్‌స్టాల్ చర్యలకు మద్దతు లేదు."</string>
+    <string name="message_staging" msgid="8032722385658438567">"యాప్‌ను సిద్ధం చేస్తుంది…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"తెలియదు"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"మీ భద్రత దృష్ట్యా, ఈ మూలం నుండి తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయడానికి మీ టాబ్లెట్ అనుమతించబడదు."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"మీ భద్రత దృష్ట్యా, ఈ మూలం నుండి తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయడానికి మీ టీవీ అనుమతించబడదు."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"మీ భద్రత దృష్ట్యా, ఈ మూలం నుండి తెలియని యాప్‌లను ఇన్‌స్టాల్ చేయడానికి మీ ఫోన్ అనుమతించబడదు."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"మీ ఫోన్ మరియు వ్యక్తిగత డేటాపై తెలియని యాప్‌లు దాడి చేయడానికి ఎక్కువ అవకాశం ఉంది. మీరు ఈ యాప్‌ను ఇన్‌స్టాల్ చేయడం ద్వారా, దీనిని ఉపయోగించడం వలన మీ ఫోన్‌కు ఏదైనా హాని జరిగినా లేదా డేటా కోల్పోయినా బాధ్యత మీదేనని అంగీకరిస్తున్నారు."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"మీ టాబ్లెట్ మరియు వ్యక్తిగత డేటాపై తెలియని యాప్‌లు దాడి చేయడానికి ఎక్కువ అవకాశం ఉంది. మీరు ఈ యాప్‌ను ఇన్‌స్టాల్ చేయడం ద్వారా, దీనిని ఉపయోగించడం వలన మీ టాబ్లెట్‌కు ఏదైనా హాని జరిగినా లేదా డేటా కోల్పోయినా బాధ్యత మీదేనని అంగీకరిస్తున్నారు."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"మీ టీవీ మరియు వ్యక్తిగత డేటాపై తెలియని యాప్‌లు దాడి చేయడానికి ఎక్కువ అవకాశం ఉంది. మీరు ఈ యాప్‌ను ఇన్‌స్టాల్ చేయడం ద్వారా, దీనిని ఉపయోగించడం వలన మీ టీవీకి ఏదైనా హాని జరిగినా లేదా డేటా కోల్పోయినా బాధ్యత మీదేనని అంగీకరిస్తున్నారు."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"కొనసాగించు"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"సెట్టింగ్‌లు"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear యాప్‌లను ఇన్‌స్టాల్/అన్‌ఇన్‌స్టాల్ చేస్తోంది"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-th/strings.xml b/packages/PackageInstaller/res/values-th/strings.xml
index b7735a7..a1f537f 100644
--- a/packages/PackageInstaller/res/values-th/strings.xml
+++ b/packages/PackageInstaller/res/values-th/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"โปรแกรมติดตั้งแพ็กเกจ"</string>
-    <string name="next" msgid="3057143178373252333">"ถัดไป"</string>
-    <string name="install" msgid="5896438203900042068">"ติดตั้ง"</string>
-    <string name="done" msgid="3889387558374211719">"เสร็จสิ้น"</string>
-    <string name="cancel" msgid="8360346460165114585">"ยกเลิก"</string>
-    <string name="installing" msgid="8613631001631998372">"กำลังติดตั้ง..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"กำลังติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"ติดตั้งแอปพลิเคชันแล้ว"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"คุณต้องการติดตั้งแอปพลิเคชันนี้หรือไม่ แอปพลิเคชันจะเข้าถึง:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"คุณต้องการจะติดตั้งแอปพลิเคชันนี้หรือไม่ แอปพลิเคชันไม่ต้องมีการเข้าถึงพิเศษใดๆ"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"คุณต้องการติดตั้งการอัปเดตของแอปพลิเคชันที่มีอยู่นี้หรือไม่ ข้อมูลที่มีอยู่ของคุณจะไม่สูญหายไป แอปพลิเคชันที่อัปเดตแล้วจะเข้าถึง:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"คุณต้องการจะติดตั้งการอัปเดตของแอปพลิเคชันในระบบนี้หรือไม่ ข้อมูลที่มีอยู่ของคุณจะไม่สูญหาย แอปพลิเคชันที่อัปเดตแล้วจะเข้าถึง:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"คุณต้องการติดตั้งการอัปเดตไปยังแอปพลิเคชันที่มีอยู่นี้หรือไม่ ข้อมูลที่มีอยู่ของคุณจะไม่สูญหาย การอัปเดตนี้ไม่จำเป็นต้องใช้การเข้าถึงใดๆ เป็นพิเศษ"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"คุณต้องการติดตั้งการอัปเดตไปยังแอปพลิเคชันในตัวนี้หรือไม่ ข้อมูลที่มีอยู่ของคุณจะไม่สูญหาย การอัปเดตนี้ไม่จำเป็นต้องใช้การเข้าถึงใดๆ เป็นพิเศษ"</string>
-    <string name="install_failed" msgid="6579998651498970899">"ไม่ได้ติดตั้งแอปพลิเคชัน"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"มีการบล็อกแพ็กเกจไม่ให้ติดตั้ง"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"ไม่ได้ติดตั้งแอปเพราะแพ็กเกจขัดแย้งกับแพ็กเกจที่มีอยู่"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ไม่ได้ติดตั้งแอปเพราะแอปใช้งานไม่ได้กับแท็บเล็ตของคุณ"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"แอปนี้ไม่สามารถใช้งานกับทีวีของคุณ"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ไม่ได้ติดตั้งแอปเพราะแอปใช้งานไม่ได้กับโทรศัพท์ของคุณ"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"ไม่ได้ติดตั้งแอปเพราะดูเหมือนว่าแพ็กเกจจะไม่ถูกต้อง"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"ไม่สามารถติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> บนแท็บเล็ตของคุณ"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ไม่สามารถติดตั้งบนทีวีได้"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"ไม่สามารถติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> บนโทรศัพท์ของคุณ"</string>
-    <string name="launch" msgid="4826921505917605463">"เปิด"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"ผู้ดูแลระบบของคุณไม่อนุญาตให้ติดตั้งแอปที่ได้มาจากแหล่งที่มาที่ไม่รู้จัก"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"ผู้ใช้รายนี้ไม่สามารถติดตั้งแอปที่ไม่รู้จัก"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"ผู้ใช้รายนี้ไม่ได้รับอนุญาตให้ติดตั้งแอป"</string>
-    <string name="ok" msgid="3468756155452870475">"ตกลง"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"จัดการแอปพลิเคชัน"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"ไม่มีพื้นที่"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"ติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> ไม่ได้ เพิ่มพื้นที่ว่างแล้วลองอีกครั้ง"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ไม่พบแอปพลิเคชัน"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ไม่พบแอปพลิเคชันนี้ในรายการแอปพลิเคชันที่ติดตั้งไว้"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"ไม่ได้รับอนุญาต"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"ผู้ใช้ปัจจุบันไม่ได้รับอนุญาตให้ทำการถอนการติดตั้งนี้"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"พบข้อผิดพลาด"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ไม่สามารถถอนการติดตั้งแอป"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ถอนการติดตั้งแอปพลิเคชัน"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"ถอนการติดตั้งการอัปเดต"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> เป็นส่วนหนึ่งของแอปพลิเคชันต่อไปนี้:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"คุณต้องการถอนการติดตั้งแอปพลิเคชันนี้หรือไม่"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"คุณต้องการถอนการติดตั้งแอปพลิเคชันนี้สำหรับผู้ใช้"<b>"ทั้งหมด"</b>"หรือไม่ แอปพลิเคชันนี้และข้อมูลในแอปพลิเคชันจะถูกลบจากผู้ใช้"<b>"ทั้งหมด"</b>"ในอุปกรณ์"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"คุณต้องการถอนการติดตั้งแอปนี้สำหรับผู้ใช้ <xliff:g id="USERNAME">%1$s</xliff:g> ไหม"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"แทนที่แอปนี้ด้วยเวอร์ชันเริ่มต้นไหม ระบบจะนำข้อมูลทั้งหมดออก"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"แทนที่แอปนี้ด้วยเวอร์ชันเริ่มต้นไหม ระบบจะนำข้อมูลทั้งหมดออก วิธีนี้ส่งผลต่อผู้ใช้ทุกคนที่ใช้อุปกรณ์เครื่องนี้ รวมทั้งผู้ที่มีโปรไฟล์งาน"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"กำลังเรียกใช้การถอนการติดตั้ง"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"การถอนการติดตั้งที่ล้มเหลว"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"กำลังถอนการติดตั้ง..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"กำลังถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"ถอนการติดตั้งเสร็จแล้ว"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"ถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> แล้ว"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"ถอนการติดตั้งไม่สำเร็จ"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"การถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ไม่สำเร็จ"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"ไม่สามารถถอนการติดตั้งแอปผู้ดูแลระบบอุปกรณ์ที่มีการใช้งาน"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"ไม่สามารถถอนการติดตั้งแอปผู้ดูแลระบบอุปกรณ์ที่มีการใช้งานสำหรับ <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"แอปนี้จำเป็นสำหรับผู้ใช้หรือโปรไฟล์บางส่วน และถอนการติดตั้งไปแล้วสำหรับส่วนอื่น"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"แอปนี้จำเป็นสำหรับโปรไฟล์ของคุณและไม่สามารถถอนการติดตั้งได้"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"ผู้ดูแลระบบอุปกรณ์กำหนดให้ใช้แอปนี้ และไม่สามารถถอนการติดตั้งได้"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"จัดการแอปผู้ดูแลระบบอุปกรณ์"</string>
-    <string name="manage_users" msgid="3125018886835668847">"จัดการผู้ใช้"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"ไม่สามารถถอดการติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"พบปัญหาในการแยกวิเคราะห์แพ็กเกจ"</string>
-    <string name="newPerms" msgid="6039428254474104210">"ใหม่"</string>
-    <string name="allPerms" msgid="1024385515840703981">"ทั้งหมด"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"ข้อมูลส่วนบุคคล"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"การเข้าถึงอุปกรณ์"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"การอัปเดตนี้ไม่จำเป็นต้องมีการอนุญาตใหม่"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"ปฏิเสธ"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"ข้อมูลเพิ่มเติม"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"ยืนยันการปฏิเสธ"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> จาก <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> รายการ"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>ไหม"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>ทุกครั้งใช่ไหม"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"ขณะใช้แอปเท่านั้น"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ตลอดเวลา"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"ปฏิเสธและไม่ต้องถามอีก"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"ปิดใช้ <xliff:g id="COUNT">%1$d</xliff:g> สิทธิ์"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"ปิดใช้สิทธิ์ทั้งหมด"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"ไม่มีการปิดใช้สิทธิ์"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"อนุญาต"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"แอป"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"สิทธิ์ของแอป"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"ไม่ต้องถามอีก"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"ไม่มีสิทธิ์"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"สิทธิ์เพิ่มเติม"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"เปิดข้อมูลแอป"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">อีก <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item>
-      <item quantity="one">อีก <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"แอปนี้ออกแบบมาเพื่อ Android เวอร์ชันเก่า การปฏิเสธสิทธิ์อาจทำให้แอปไม่ทำงานตามที่ต้องการอีกต่อไป"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ดำเนินการทำงานที่ไม่รู้จัก"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"อนุญาตแล้ว <xliff:g id="COUNT_0">%1$d</xliff:g> จาก <xliff:g id="COUNT_1">%2$d</xliff:g> แอป"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"แสดงระบบ"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"ซ่อนระบบ"</string>
-    <string name="no_apps" msgid="1965493419005012569">"ไม่มีแอป"</string>
-    <string name="location_settings" msgid="1774875730854491297">"การตั้งค่าตำแหน่ง"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> เป็นผู้ให้บริการตำแหน่งสำหรับอุปกรณ์นี้ คุณสามารถแก้ไขสิทธิ์เข้าถึงตำแหน่งได้จากการตั้งค่าตำแหน่ง"</string>
-    <string name="system_warning" msgid="7103819124542305179">"หากคุณปฏิเสธสิทธิ์นี้ ฟีเจอร์พื้นฐานของอุปกรณ์อาจไม่ทำงานตามที่ควรจะเป็นอีกต่อไป"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"บังคับใช้โดยนโยบาย"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"ปิดใช้การเข้าถึงในเบื้องหลังโดยนโยบาย"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"เปิดใช้การเข้าถึงในเบื้องหลังโดยนโยบาย"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"เปิดใช้การเข้าถึงในเบื้องหน้าโดยนโยบาย"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"ผู้ดูแลระบบเป็นผู้ควบคุม"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ตลอดเวลา"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"ขณะใช้แอปเท่านั้น"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"ไม่เลย"</string>
-    <string name="loading" msgid="7811651799620593731">"กำลังโหลด…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"สิทธิ์ทั้งหมด"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"ความสามารถอื่นๆ ของแอป"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"คำขอสิทธิ์"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"ตรวจพบการวางซ้อนหน้าจอ"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"ในการเปลี่ยนแปลงการตั้งค่าสิทธิ์นี้ ก่อนอื่น คุณต้องปิดการวางซ้อนหน้าจอที่การตั้งค่า &gt; แอป"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"เปิดการตั้งค่า"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"ไม่สามารถติดตั้ง/ถอนการติดตั้งบน Wear"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"โปรดเลือกข้อมูลที่อนุญาตให้ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; เข้าถึง"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"อัปเดต &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; แล้ว โปรดเลือกข้อมูลที่อนุญาตให้แอปนี้เข้าถึง"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"ยกเลิก"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"ต่อไป"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"สิทธิ์ใหม่"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"สิทธิ์ปัจจุบัน"</string>
-    <string name="message_staging" msgid="6151794817691100003">"กำลังปรับสภาพแวดล้อมของแอป…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"ไม่ทราบ"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในแท็บเล็ต"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในทีวี"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในโทรศัพท์"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"โทรศัพท์และข้อมูลส่วนบุคคลของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้เป็นการยอมรับว่าคุณจะรับผิดชอบความเสียหายต่อเครื่องโทรศัพท์หรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"แท็บเล็ตและข้อมูลส่วนบุคคลของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้เป็นการยอมรับว่าคุณจะรับผิดชอบความเสียหายต่อเครื่องแท็บเล็ตหรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"ทีวีและข้อมูลส่วนบุคคลของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้เป็นการยอมรับว่าคุณจะรับผิดชอบความเสียหายต่อเครื่องทีวีหรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"ต่อไป"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"การตั้งค่า"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"กำลังติดตั้ง/ถอนการติดตั้งแอป Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"โปรแกรมติดตั้งแพ็กเกจ"</string>
+    <string name="install" msgid="711829760615509273">"ติดตั้ง"</string>
+    <string name="done" msgid="6632441120016885253">"เสร็จ"</string>
+    <string name="cancel" msgid="1018267193425558088">"ยกเลิก"</string>
+    <string name="installing" msgid="4921993079741206516">"กำลังติดตั้ง…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"กำลังติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"ติดตั้งแอปแล้ว"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"ต้องการติดตั้งแอปพลิเคชันนี้ไหม"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"ต้องการติดตั้งการอัปเดตของแอปพลิเคชันที่มีอยู่นี้ไหม ข้อมูลของคุณที่มีอยู่จะไม่สูญหาย"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"ต้องการติดตั้งการอัปเดตของแอปพลิเคชันที่มีอยู่ในตัวนี้ไหม ข้อมูลของคุณที่มีอยู่จะไม่สูญหาย"</string>
+    <string name="install_failed" msgid="5777824004474125469">"ไม่ได้ติดตั้งแอป"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"มีการบล็อกแพ็กเกจไม่ให้ติดตั้ง"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"ไม่ได้ติดตั้งแอปเพราะแพ็กเกจขัดแย้งกับแพ็กเกจที่มีอยู่"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"ไม่ได้ติดตั้งแอปเพราะแอปใช้งานไม่ได้กับแท็บเล็ตของคุณ"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"แอปนี้ใช้งานกับทีวีของคุณไม่ได้"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"ไม่ได้ติดตั้งแอปเพราะแอปใช้งานไม่ได้กับโทรศัพท์ของคุณ"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"ไม่ได้ติดตั้งแอปเพราะดูเหมือนว่าแพ็กเกจจะไม่ถูกต้อง"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"ติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> ในแท็บเล็ตของคุณไม่ได้"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"ผู้ใช้รายนี้ไม่สามารถติดตั้งแอปที่ไม่รู้จัก"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"ผู้ใช้รายนี้ไม่ได้รับอนุญาตให้ติดตั้งแอป"</string>
+    <string name="ok" msgid="7871959885003339302">"ตกลง"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"จัดการแอป"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"ไม่มีพื้นที่"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"ติดตั้ง <xliff:g id="APP_NAME">%1$s</xliff:g> ไม่ได้ เพิ่มพื้นที่ว่างแล้วลองอีกครั้ง"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"ไม่พบแอป"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"ไม่พบแอปนี้ในรายการแอปที่ติดตั้ง"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"ไม่อนุญาต"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"ผู้ใช้ปัจจุบันไม่ได้รับอนุญาตให้ทำการถอนการติดตั้งนี้"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"ข้อผิดพลาด"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"ถอนการติดตั้งแอปไม่ได้"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"ถอนการติดตั้งแอป"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"ถอนการติดตั้งการอัปเดต"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> เป็นส่วนหนึ่งของแอปต่อไปนี้"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"ต้องการถอนการติดตั้งแอปนี้ไหม"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"ต้องการถอนการติดตั้งแอปนี้สำหรับผู้ใช้"<b>"ทั้งหมด"</b>"ไหม ระบบจะนำแอปและข้อมูลในแอปออกจากผู้ใช้"<b>"ทั้งหมด"</b>"ที่อยู่ในอุปกรณ์"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"ต้องการถอนการติดตั้งแอปนี้สำหรับผู้ใช้ <xliff:g id="USERNAME">%1$s</xliff:g> ไหม"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"แทนที่แอปนี้ด้วยเวอร์ชันเริ่มต้นไหม ระบบจะนำข้อมูลทั้งหมดออก"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"แทนที่แอปนี้ด้วยเวอร์ชันเริ่มต้นไหม ระบบจะนำข้อมูลทั้งหมดออก วิธีนี้จะส่งผลต่อผู้ใช้ทุกคนที่ใช้อุปกรณ์เครื่องนี้ รวมทั้งผู้ที่มีโปรไฟล์งาน"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"กำลังเรียกใช้การถอนการติดตั้ง"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"ถอนการติดตั้งไม่สำเร็จ"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"กำลังถอนการติดตั้ง…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"กำลังถอนการติดตั้ง <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"ถอนการติดตั้งเสร็จแล้ว"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"ติดตั้ง/ถอนการติดตั้งใน Wear ไม่ได้"</string>
+    <string name="message_staging" msgid="8032722385658438567">"กำลังปรับสภาพแวดล้อมของแอป…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"ไม่ทราบ"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในแท็บเล็ต"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในทีวี"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"เพื่อความปลอดภัย ไม่อนุญาตให้ติดตั้งแอปที่ไม่รู้จักจากแหล่งที่มานี้ในโทรศัพท์"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"โทรศัพท์และข้อมูลส่วนตัวของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้แสดงว่าคุณยอมรับว่าจะรับผิดชอบต่อความเสียหายใดๆ ที่จะเกิดขึ้นกับโทรศัพท์หรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"แท็บเล็ตและข้อมูลส่วนตัวของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้แสดงว่าคุณยอมรับว่าจะรับผิดชอบต่อความเสียหายใดๆ ที่จะเกิดขึ้นกับแท็บเล็ตหรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ทีวีและข้อมูลส่วนตัวของคุณมีความเสี่ยงมากขึ้นที่จะถูกโจมตีจากแอปที่ไม่รู้จัก การติดตั้งแอปนี้แสดงว่าคุณยอมรับว่าจะรับผิดชอบต่อความเสียหายใดๆ ที่จะเกิดขึ้นกับทีวีหรือการสูญเสียข้อมูลที่อาจเกิดจากการใช้งานแอปดังกล่าว"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"ดำเนินการต่อ"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"การตั้งค่า"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"กำลังติดตั้ง/ถอนการติดตั้งแอป Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-tl/strings.xml b/packages/PackageInstaller/res/values-tl/strings.xml
index 05eba98..eace11e 100644
--- a/packages/PackageInstaller/res/values-tl/strings.xml
+++ b/packages/PackageInstaller/res/values-tl/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Installer ng package"</string>
-    <string name="next" msgid="3057143178373252333">"Susunod"</string>
-    <string name="install" msgid="5896438203900042068">"Mag-install"</string>
-    <string name="done" msgid="3889387558374211719">"Tapos na"</string>
-    <string name="cancel" msgid="8360346460165114585">"Kanselahin"</string>
-    <string name="installing" msgid="8613631001631998372">"Nag-i-install…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Ini-install ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Na-install ang app."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Nais mo bang i-install ang application na ito? Magkakaroon ito ng access sa:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Nais mo bang i-install ang application na ito? Hindi ito nangangailangan ng anumang espesyal na access."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Nais mo bang mag-install ng update sa umiiral nang application na ito? Hindi mawawala ang iyong umiiral nang data. Magkakaroon ng access ang na-update na application sa:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Nais mo bang mag-install ng update sa built-in na application na ito? Hindi mawawala ang iyong umiiral na data. Magkakaroon ng access ang na-update na application sa:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Nais mo bang mag-install ng update sa umiiral na application na ito? Hindi mawawala ang iyong umiiral na data. Hindi ito nangangailangan ng anumang espesyal na access."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Nais mo bang mag-install ng update sa built-in na application na ito? Hindi mawawala ang iyong umiiral na data. Hindi ito nangangailangan ng anumang espesyal na access."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Hindi na-install ang app."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Na-block ang pag-install sa package."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Hindi na-install ang app dahil nagkakaproblema ang package sa isang dati nang package."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Hindi na-install ang app dahil hindi tugma ang app sa iyong tablet."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Hindi compatible ang app na ito sa iyong TV."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Hindi na-install ang app dahil hindi tugma ang app sa iyong telepono."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Hindi na-install ang app dahil lumalabas na di-wasto ang package."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa iyong tablet."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay hindi ma-install sa iyong TV."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa iyong telepono."</string>
-    <string name="launch" msgid="4826921505917605463">"Buksan"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Hindi pinapayagan ng iyong admin ang pag-install ng mga app na nakuha mula sa mga hindi kilalang pinagmulan"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Hindi maaaring mag-install ang user na ito ng mga hindi kilalang app"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Hindi pinapayagan ang user na mag-install ng mga app"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Pamahalaan ang apps"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Wala ng espasyo"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g>. Magbakante ng ilang espasyo at subukang muli."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Hindi makita ang app"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Hindi makita ang app sa listahan ng naka-install na apps."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Hindi pinapayagan"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Hindi pinapayagan ang kasalukuyang user na gawin ang pag-uninstall na ito."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Error"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Hindi ma-uninstall ang app."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"I-uninstall ang app"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"I-uninstall ang update"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"Bahagi ang <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ng sumusunod na app:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Gusto mo bang i-uninstall ang app na ito?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Nais mo bang i-uninstall ang app na ito para sa "<b>"lahat"</b>" ng user? Aalisin ang application at ang data nito mula sa "<b>"lahat"</b>" ng user sa device."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Gusto mo bang i-uninstall ang app na ito para sa user na si <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Gusto mo bang palitan ang app na ito ng factory na bersyon? Maaalis ang lahat ng data."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Gusto mo bang palitan ang app na ito ng factory na bersyon? Maaalis ang lahat ng data. Nakakaapekto ito sa lahat ng user ng device na ito, kasama ang mga may profile sa trabaho."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Mga nasa proseso ng pag-uninstall"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Mga hindi na-uninstall"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Ina-uninstall…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Ina-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Natapos ang pag-uninstall."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Na-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Di-matagumpay ang pag-uninstall."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Hindi na-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Hindi ma-uninstall ang aktibong app ng admin ng device"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Hindi ma-uninstall ang aktibong app ng admin ng device para kay  <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ang app na ito ay kailangan ng ilang user o profile at na-uninstall na ito sa iba pa"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ang app na ito ay kailangan para sa iyong profile at hindi maaaring i-uninstall."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Kinakailangan app na ito ng administrator ng device mo at di maaari i-uninstall."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Pamahalaan ang mga app ng admin ng device"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Pamahalaan ang mga user"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Nagkaroon ng problema sa pag-parse sa package."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Bago"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Lahat"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Privacy"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Access sa Device"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Walang kinakailangang mga bagong pagpapahintulot ang update na ito."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Tanggihan"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Higit pang impormasyon"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Tanggihan pa rin"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> ng <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Palaging payagan ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; na <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Habang ginagamit lang ang app"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Palagi"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Tanggihan at huwag nang itanong muli"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> ang naka-disable"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"naka-disable lahat"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"walang naka-disable"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Payagan"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Mga App"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Mga pahintulot sa app"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Huwag nang tatanunging muli"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Walang pahintulot"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Mga karagdagang pahintulot"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Buksan ang impormasyon ng app"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> pa</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> pa</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ang app na ito ay idinisenyo para sa mas lumang bersyon ng Android. Kapag tinanggihan ang pahintulot, maaaring hindi na ito gumana ayon sa inaasahan."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"gumawa ng hindi kilalang pagkilos"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Pinapayagan ang <xliff:g id="COUNT_0">%1$d</xliff:g> sa <xliff:g id="COUNT_1">%2$d</xliff:g> (na) app"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Ipakita ang system"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Itago ang system"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Walang mga app"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Mga Setting ng Lokasyon"</string>
-    <string name="location_warning" msgid="8778701356292735971">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay isang provider ng mga serbisyo sa lokasyon para sa device na ito. Mababago ang access sa lokasyon mula sa mga setting ng lokasyon."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Kung tatanggihan mo ang pahintulot na ito, maaaring hindi na gumana ang mga pangunahing feature ng iyong device gaya ng inaasahan."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Ipinapatupad sa pamamagitan ng patakaran"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Na-disable ayon sa patakaran ang pag-access sa background"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Na-enable ayon sa patakaran ang pag-access sa background"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Na-enable ayon sa patakaran ang pag-access sa foreground"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kinokontrol ng admin"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Palagi"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Habang ginagamit lang ang app"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Huwag Kailanman"</string>
-    <string name="loading" msgid="7811651799620593731">"Naglo-load..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Lahat ng pahintulot"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Iba pang mga kakayahan ng app"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Kahilingan sa pagpapahintulot"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Natukoy ang overlay ng screen"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Upang baguhin ang setting ng pahintulot na ito, kailangan mo munang i-off ang overlay ng screen mula sa Mga Setting &gt; Mga App"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Buksan ang mga setting"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Ang mga pagkilos na I-install/I-uninstall ay hindi sinusuportahan sa Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Piliin kung ano ang papayagang i-access ng &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Na-update na ang &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;. Piliin kung ano ang papayagang i-access ng app na ito."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Kanselahin"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Magpatuloy"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Mga bagong pahintulot"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Mga kasalukuyang pahintulot"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Inihahanda ang app…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Hindi Alam"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Para sa iyong seguridad, hindi pinapayagan ang tablet mo na mag-install ng mga hindi alam na app mula sa pinagmulang ito."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Para sa iyong seguridad, hindi pinapayagan ang TV mo na mag-install ng mga hindi alam na app mula sa pinagmulang ito."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Para sa iyong seguridad, hindi pinapayagan ang telepono mo na mag-install ng mga hindi alam na app mula sa pinagmulang ito."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Mas nanganganib ang iyong telepono at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon ka na ikaw ang responsable sa anumang pinsala sa telepono mo o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Mas nanganganib ang iyong tablet at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon ka na ikaw ang responsable sa anumang pinsala sa tablet mo o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Mas nanganganib ang iyong TV at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon ka na ikaw ang responsable sa anumang pinsala sa TV mo o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Magpatuloy"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Mga Setting"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Ini-install/ina-uninstall ang wear apps"</string>
+    <string name="app_name" msgid="7488448184431507488">"Installer ng package"</string>
+    <string name="install" msgid="711829760615509273">"I-install"</string>
+    <string name="done" msgid="6632441120016885253">"Tapos na"</string>
+    <string name="cancel" msgid="1018267193425558088">"Kanselahin"</string>
+    <string name="installing" msgid="4921993079741206516">"Nag-i-install…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Ini-install ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Na-install na ang app."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Gusto mo bang i-install ang application na ito?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Gusto mo bang mag-install ng update sa dati nang application na ito? Hindi mawawala ang iyong dati nang data."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Gusto mo bang mag-install ng update sa built-in na application na ito? Hindi mawawala ang iyong dati nang data."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Hindi na-install ang app."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Na-block ang pag-install sa package."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Hindi na-install ang app dahil nagkakaproblema ang package sa isang dati nang package."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Hindi na-install ang app dahil hindi tugma ang app sa iyong tablet."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Hindi tugma ang app na ito sa iyong TV."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Hindi na-install ang app dahil hindi tugma ang app sa iyong telepono."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Hindi na-install ang app dahil mukhang invalid ang package."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa iyong tablet."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa iyong TV."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g> sa iyong telepono."</string>
+    <string name="launch" msgid="3952550563999890101">"Buksan"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Hindi pinapayagan ng iyong admin ang pag-install ng mga app na nakuha mula sa mga hindi kilalang source"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Hindi maaaring mag-install ang user na ito ng mga hindi kilalang app"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Hindi pinapayagan ang user na ito na mag-install ng mga app"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Pamahalaan ang app"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Wala nang espasyo"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Hindi ma-install ang <xliff:g id="APP_NAME">%1$s</xliff:g>. Magbakante ng ilang espasyo at subukang muli."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Hindi nakita ang app"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Hindi nakita ang app sa listahan ng mga naka-install na app."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Hindi pinapayagan"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Hindi pinapayagan ang kasalukuyang user na isagawa ang pag-uninstall na ito."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Error"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Hindi ma-uninstall ang app."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"I-uninstall ang app"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"I-uninstall ang update"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"Bahagi ang <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ng sumusunod na app:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Gusto mo bang i-uninstall ang app na ito?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Gusto mo bang i-uninstall ang app na ito para sa "<b>"lahat"</b>" ng user? Aalisin ang application at ang data nito sa "<b>"lahat"</b>" ng user sa device."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Gusto mo bang i-uninstall ang app na ito para sa user na si <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Gusto mo bang palitan ang app na ito ng factory na bersyon? Maaalis ang lahat ng data."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Gusto mo bang palitan ang app na ito ng factory na bersyon? Maaalis ang lahat ng data. Nakakaapekto ito sa lahat ng user ng device na ito, kabilang ang mga may profile sa trabaho."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Mga kasalukuyang pag-uninstall"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Mga hindi na-uninstall"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Ina-uninstall…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Ina-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Tapos na ang pag-uninstall."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Na-uninstall ang <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Hindi matagumpay ang pag-uninstall."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Hindi matagumpay ang pag-uninstall sa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Hindi ma-uninstall ang aktibong app ng admin ng device"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Hindi ma-uninstall ang aktibong app ng admin ng device para kay <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Kailangan ng ilang user o profile ang app na ito at na-uninstall ito para sa iba pa"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Kailangan ang app na ito para sa iyong profile at hindi ito maaaring i-uninstall."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Kinakailangan ang app ng administrator ng device at hindi ito maa-uninstall."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Pamahalaan ang mga app ng admin ng device"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Pamahalaan ang mga user"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Hindi ma-uninstall ang <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Nagkaroon ng problema sa pag-parse sa package."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Ang mga pagkilos na I-install/I-uninstall ay hindi sinusuportahan sa Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Inihahanda ang app…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Hindi Kilala"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Para sa iyong seguridad, hindi pinapayagan ang iyong tablet na mag-install ng mga hindi kilalang app mula sa source na ito."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Para sa iyong seguridad, hindi pinapayagan ang iyong TV na mag-install ng mga hindi kilalang app mula sa source na ito."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Para sa iyong seguridad, hindi pinapayagan ang iyong telepono na mag-install ng mga hindi kilalang app mula sa source na ito."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Mas nanganganib ang iyong telepono at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon kang ikaw ang responsable sa anumang pinsala sa iyong telepono o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Mas nanganganib ang iyong tablet at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon kang ikaw ang responsable sa anumang pinsala sa iyong tablet o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Mas nanganganib ang iyong TV at personal na data sa mga pag-atake mula sa mga hindi kilalang app. Sa pamamagitan ng pag-install ng app na ito, sumasang-ayon kang ikaw ang responsable sa anumang pinsala sa iyong TV o pagkawala ng data na maaaring magresulta mula sa paggamit nito."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Magpatuloy"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Mga Setting"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Ini-install/ina-uninstall ang wear app"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-tr/strings.xml b/packages/PackageInstaller/res/values-tr/strings.xml
index ef7882d..99575e0 100644
--- a/packages/PackageInstaller/res/values-tr/strings.xml
+++ b/packages/PackageInstaller/res/values-tr/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Paket yükleyici"</string>
-    <string name="next" msgid="3057143178373252333">"Sonraki"</string>
-    <string name="install" msgid="5896438203900042068">"Yükle"</string>
-    <string name="done" msgid="3889387558374211719">"Bitti"</string>
-    <string name="cancel" msgid="8360346460165114585">"İptal"</string>
-    <string name="installing" msgid="8613631001631998372">"Yükleniyor…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> yükleniyor…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Uygulama yüklendi."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Bu uygulamayı yüklemek istiyor musunuz? Uygulama şunlara erişebilecektir:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Bu uygulamayı yüklemek istiyor musunuz? Herhangi bir özel erişim gerektirmez."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Bu mevcut uygulamaya ait bir güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz silinmeyecektir. Güncellenen uygulama şunlara erişebilecektir:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Bu yerleşik uygulamaya ait bir güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz silinmeyecektir. Güncellenen uygulama şunlara erişebilecektir:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Bu mevcut uygulamaya ait bir güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz kaybolacaktır. Herhangi bir özel erişim gerektirmez."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Bu yerleşik uygulamaya ait bir güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz kaybolacaktır. Herhangi bir özel erişim gerektirmez."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Uygulama yüklenmedi."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Paketin yüklemesi engellendi."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Paket, mevcut bir paketle çakıştığından uygulama yüklenemedi."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Tabletinizle uyumlu olmadığından uygulama yüklenemedi."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Bu uygulama TV\'niz ile uyumlu değil."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Telefonunuzla uyumlu olmadığından uygulama yüklenemedi."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Paket geçersiz göründüğünden uygulama yüklenemedi."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu tabletinize yüklenemedi."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> TV\'nize yüklenemedi."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu telefonunuza yüklenemedi."</string>
-    <string name="launch" msgid="4826921505917605463">"Aç"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Yöneticiniz, bilinmeyen kaynaklardan edinilen uygulamaların yüklenmesine izin vermiyor"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Bilinmeyen uygulamalar bu kullanıcı tarafından yüklenemez"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Bu kullanıcının uygulama yüklemesine izin verilmiyor"</string>
-    <string name="ok" msgid="3468756155452870475">"Tamam"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Uygulamaları yönet"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Yer kalmadı"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> yüklenemedi. Boş alan açın ve yeniden deneyin."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Uygulama bulunamadı"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Uygulama, yüklü uygulamalar listesinde bulunamadı."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"İzin verilmiyor"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Geçerli kullanıcının bu yüklemeyi kaldırma izni yok."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Hata"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Uygulamanın yüklemesi kaldırılamadı."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Uygulamayı kaldır"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Güncelleme kaldırılsın mı?"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>, şu uygulamanın bir parçasıdır:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Bu uygulamanın yüklemesini kaldırmak istiyor musunuz?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Bu uygulamanın yüklemesini "<b>"tüm"</b>" kullanıcılar için kaldırmak istiyor musunuz? Uygulama ve verileri cihazdan "<b>"tüm"</b>" kullanıcılar için kaldırılacaktır."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı kullanıcı için bu uygulamanın yüklemesini kaldırmak istiyor musunuz?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Bu uygulamayı fabrika sürümüyle değiştirmek istiyor musunuz? Tüm veriler silinecektir."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Bu uygulamayı fabrika sürümüyle değiştirmek istiyor musunuz? Tüm veriler silinecektir. Bu, çalışma profilleri olan kullanıcılar da dahil olmak üzere cihazı kullanan tüm kullanıcıları etkiler."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Devam eden yükleme kaldırma işlemleri"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Başarısız yükleme kaldırma işlemleri"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Kaldırılıyor…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılıyor…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Kaldırma işlemi tamamlandı."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırıldı"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Yükleme kaldırılamadı."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılamadı."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Etkin cihaz yönetimi uygulamasının yüklemesi kaldırılamıyor"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı kullanıcı için etkin cihaz yönetimi uygulamasının yüklemesi kaldırılamıyor"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Bu uygulama bazı kullanıcılar veya profiller için gerekli ve diğerleri için uygulamanın yüklemesi kaldırıldı"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Profiliniz için bu uygulama gerekli ve yüklemesi kaldırılamaz."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Bu uygulama, cihazınızın yöneticisi için gereklidir ve yüklemesi kaldırılamaz."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Cihaz yönetimi uygulamalarını yönet"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Kullanıcıları yönetme"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> kaldırılamadı."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Paketin ayrıştırılmasında bir sorun oluştu."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Yeni"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Tümü"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Gizlilik"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Cihaz Erişimi"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Bu güncelleme yeni izin gerektirmiyor."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Reddet"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Daha fazla bilgi"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Yine de reddet"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasına <xliff:g id="ACTION">%2$s</xliff:g> izni verilsin mi?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasına <xliff:g id="ACTION">%2$s</xliff:g> için izin verilsin m?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Sadece uygulama kullanılırken"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Her zaman"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Reddet ve bir daha sorma"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> izin devre dışı"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"tümü devre dışı"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"hiçbiri devre dışı değil"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"İzin ver"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Uygulamalar"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Uygulama izinleri"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Tekrar sorma"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"İzin yok"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Ek izinler"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Uygulama bilgilerini aç"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> tane daha</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> tane daha</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Bu uygulama, Android\'in daha eski bir sürümü için tasarlandı. İznin reddedilmesi, uygulamanın bundan sonra amaçlandığı gibi çalışmamasına neden olabilir."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"bilinmeyen bir işlem gerçekleştirme"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> / <xliff:g id="COUNT_1">%2$d</xliff:g> uygulamaya izin veriliyor"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Sistemi göster"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Sistemi gizle"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Uygulama yok"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Konum Ayarları"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g>, bu cihaz için konum hizmetlerinin bir sağlayıcısıdır. Konum erişimi, konum ayarlarından değiştirilebilir."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Bu izni reddederseniz cihazınızın temel özellikleri artık beklendiği gibi çalışmayabilir."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Politika tarafından zorunlu tutuldu"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Arka plan erişimi politika tarafından devre dışı bırakıldı"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Arka plan erişimi politika tarafından etkinleştirildi"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Ön plan erişimi politika tarafından etkinleştirildi"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Yönetici tarafından kontrol ediliyor"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Her zaman"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Sadece uygulama kullanılırken"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Hiçbir zaman"</string>
-    <string name="loading" msgid="7811651799620593731">"Yükleniyor..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Tüm izinler"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Diğer uygulama özellikleri"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"İzin isteği"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Ekran yer paylaşımı tespit edildi"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Bu izin ayarını değiştirmek için ilk olarak Ayarlar &gt; Uygulamalar\'dan ekran yer paylaşımını kapatmanız gerekir"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Ayarları aç"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Yükleme/Yüklemeyi Kaldırma işlemleri Wear\'da desteklenmiyor."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uygulamasının nelere erişmesine izin vereceğinizi seçin"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; güncellendi. Bu uygulamanın nelere erişmesine izin verileceğini seçin."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"İptal"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Devam"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Yeni izinler"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Geçerli izinler"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Uygulama hazırlanıyor…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Bilinmiyor"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Güvenlik nedeniyle tabletinizin bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Güvenlik nedeniyle TV\'nizin bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Güvenlik nedeniyle telefonunuzun bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefonunuz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı telefonunuzda oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Tabletiniz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı tabletinizde oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV\'niz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı TV\'nizde oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Devam"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Ayarlar"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear uyg. yükleme/yüklemesini kaldırma"</string>
+    <string name="app_name" msgid="7488448184431507488">"Paket yükleyici"</string>
+    <string name="install" msgid="711829760615509273">"Yükle"</string>
+    <string name="done" msgid="6632441120016885253">"Bitti"</string>
+    <string name="cancel" msgid="1018267193425558088">"İptal"</string>
+    <string name="installing" msgid="4921993079741206516">"Yükleniyor…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> yükleniyor…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Uygulama yüklendi."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Bu uygulamayı yüklemek istiyor musunuz?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Bu mevcut uygulamaya ait güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz silinmez."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Bu yerleşik uygulamaya ait güncellemeyi yüklemek istiyor musunuz? Mevcut verileriniz silinmez."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Uygulama yüklenmedi."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paketin yüklemesi engellendi."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Paket, mevcut bir paketle çakıştığından uygulama yüklenemedi."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Tabletinizle uyumlu olmadığından uygulama yüklenemedi."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Bu uygulama TV\'niz ile uyumlu değil."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Telefonunuzla uyumlu olmadığından uygulama yüklenemedi."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Paket geçersiz göründüğünden uygulama yüklenemedi."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> tabletinize yüklenemedi."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> TV\'nize yüklenemedi."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> telefonunuza yüklenemedi."</string>
+    <string name="launch" msgid="3952550563999890101">"Aç"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Yöneticiniz, bilinmeyen kaynaklardan edinilen uygulamaların yüklenmesine izin vermiyor"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Bilinmeyen uygulamalar bu kullanıcı tarafından yüklenemez"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Bu kullanıcının uygulama yüklemesine izin verilmiyor"</string>
+    <string name="ok" msgid="7871959885003339302">"Tamam"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Uygulamaları yönet"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Yer kalmadı"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> yüklenemedi. Boş alan açın ve yeniden deneyin."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Uygulama bulunamadı"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Uygulama, yüklü uygulamalar listesinde bulunamadı."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"İzin verilmiyor"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Geçerli kullanıcının bu yüklemeyi kaldırma izni yok."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Hata"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Uygulamanın yüklemesi kaldırılamadı."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Uygulamanın yüklemesini kaldır"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Güncelleme kaldırılsın mı?"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>, şu uygulamanın bir parçasıdır:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Bu uygulamanın yüklemesini kaldırmak istiyor musunuz?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Bu uygulamanın yüklemesini "<b>"tüm"</b>" kullanıcılar için kaldırmak istiyor musunuz? Uygulama ve verileri cihazdan "<b>"tüm"</b>" kullanıcılar için kaldırılacaktır."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı kullanıcı için bu uygulamanın yüklemesini kaldırmak istiyor musunuz?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Bu uygulamayı fabrika sürümüyle değiştirmek istiyor musunuz? Tüm veriler silinecektir."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Bu uygulamayı fabrika sürümüyle değiştirmek istiyor musunuz? Tüm veriler silinecektir. Bu, çalışma profilleri olan kullanıcılar da dahil olmak üzere cihazı kullanan tüm kullanıcıları etkiler."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Devam eden yükleme kaldırma işlemleri"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Başarısız yükleme kaldırma işlemleri"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Yükleme kaldırılıyor…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılıyor…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Yüklemeyi kaldırma işlemi tamamlandı."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırıldı"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Yükleme kaldırılamadı."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> uygulamasının yüklemesi kaldırılamadı."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Etkin cihaz yönetimi uygulamasının yüklemesi kaldırılamıyor"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> adlı kullanıcı için etkin cihaz yönetimi uygulamasının yüklemesi kaldırılamıyor"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Bu uygulama bazı kullanıcılar veya profiller için gerekli olduğundan uygulamanın yüklemesi diğer kullanıcılar için kaldırıldı"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Profiliniz için bu uygulama gerekli ve yüklemesi kaldırılamaz."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Bu uygulama, cihazınızın yöneticisi için gereklidir ve yüklemesi kaldırılamaz."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Cihaz yönetimi uygulamalarını yönet"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Kullanıcıları yönet"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> kaldırılamadı."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Paketin ayrıştırılmasında bir sorun oluştu."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Yükleme/Yüklemeyi kaldırma işlemleri Wear\'da desteklenmiyor."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Uygulama hazırlanıyor…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Bilinmiyor"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Güvenlik nedeniyle tabletinizin bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Güvenlik nedeniyle TV\'nizin bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Güvenlik nedeniyle telefonunuzun bu kaynaktan bilinmeyen uygulamalar yüklemesine izin verilmez."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefonunuz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı telefonunuzda oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tabletiniz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı tabletinizde oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV\'niz ve kişisel verileriniz, bilinmeyen uygulamaların saldırılarına karşı daha savunmasızdır. Bu uygulamayı yükleyerek, uygulama kullanımından dolayı TV\'nizde oluşabilecek hasarın veya uğrayabileceğiniz veri kaybının sorumluluğunu kabul etmiş olursunuz."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Devam"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Ayarlar"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear uygulamalarını yükleme/kaldırma"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-uk/strings.xml b/packages/PackageInstaller/res/values-uk/strings.xml
index bdc09df..b3bebf1 100644
--- a/packages/PackageInstaller/res/values-uk/strings.xml
+++ b/packages/PackageInstaller/res/values-uk/strings.xml
@@ -16,143 +16,76 @@
 
 <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="2738748390251381682">"Програма встановлення пакета"</string>
-    <string name="next" msgid="3057143178373252333">"Далі"</string>
-    <string name="install" msgid="5896438203900042068">"Установити"</string>
-    <string name="done" msgid="3889387558374211719">"Готово"</string>
-    <string name="cancel" msgid="8360346460165114585">"Скасувати"</string>
-    <string name="installing" msgid="8613631001631998372">"Встановлення…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Установлюється <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Додаток установлено."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Установити цей додаток? Він отримає такі дозволи:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Установити цей додаток? Йому не потрібні спеціальні дозволи."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Дійсно встановити оновлення для цієї наявної програми? Існуючі дані втрачено не буде. Оновлена програма отримає доступ до:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Дійсно встановити оновлення для цієї вбудованої програми? Існуючі дані втрачено не буде. Оновлена програма отримає доступ до:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Хочете встановити оновлення для наявної програми? Ваші наявні дані не зникнуть. Спеціальний доступ не потрібен."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Хочете встановити оновлення для цієї вбудованої програми? Ваші наявні дані не зникнуть. Спеціальний доступ не потрібен."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Додаток не встановлено."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Встановлення пакета заблоковано."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Додаток не встановлено, оскільки пакет конфліктує з наявним пакетом."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Додаток не встановлено, оскільки він несумісний із вашим планшетом."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Цей додаток несумісний із вашим телевізором."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Додаток не встановлено, оскільки він несумісний із вашим телефоном."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Додаток не встановлено, оскільки пакет недійсний."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити у вашому планшетному ПК."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Не вдалося встановити додаток <xliff:g id="APP_NAME">%1$s</xliff:g> на ваш телевізор."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити у вашому телефоні."</string>
-    <string name="launch" msgid="4826921505917605463">"Відкрити"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Ваш адміністратор заборонив установлювати додатки з невідомих джерел"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Цей користувач не може встановлювати невідомі додатки"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Цей користувач не може встановлювати додатки"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Керувати програмами"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Недостат. місця"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити. Звільніть місце та повторіть спробу."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Програму не знайдено"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Програму не знайдено в списку встановлених програм."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Заборонено"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Поточний користувач не може видалити цей додаток."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Помилка"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Не вдалося видалити додаток."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Видалити програму"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Видалити оновлення"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"Дія <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> є частиною такої програми:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Видалити додаток?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Хочете видалити цю програму для "<b>"всіх"</b>" користувачів? Програму та її дані буде видалено для "<b>"всіх"</b>" користувачів цього пристрою."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Видалити цей додаток для користувача <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Відновити заводську версію цього додатка? Усі дані буде видалено."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Відновити заводську версію цього додатка? Усі дані буде видалено. Це вплине на всіх користувачів цього пристрою, зокрема на користувачів із робочими профілями."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Активні видалення"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Невиконані видалення"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Видалення..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Видалення додатка <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Видалення завершено."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Додаток <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> видалено"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Видалення не здійснено."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Не вдалося видалити додаток <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Не вдається видалити активний додаток адміністратора пристрою"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Не вдається видалити активний додаток адміністратора пристрою для користувача <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Цей додаток потрібен для деяких користувачів чи профілів, але його було видалено для інших"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Цей додаток потрібен для вашого профілю, тому його не можна видалити."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Цей додаток не можна видалити – не дозволяє адміністратор пристрою."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Керувати додатками адміністратора пристрою"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Керувати користувачами"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо видалити."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Під час аналізу пакету виникла помилка."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Нові"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Усі"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Конфіденційність"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Доступ до пристрою"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Для цього оновлення не потрібні нові дозволи."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Відхилити"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Докладніше"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Усе одно заборонити"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> з <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Дозволити додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Завжди дозволяти додатку &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Лише коли додаток активний"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Завжди"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Відхилити й більше не запитувати"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> скасовано"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"усі скасовано"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"нічого не скасовано"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Дозволити"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Додатки"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Дозволи додатків"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Не запитувати знову"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Немає дозволів"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Додаткові дозволи"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Відкрити інформацію про додаток"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one">Ще <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="few">Ще <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="many">Ще <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-      <item quantity="other">Ще <xliff:g id="COUNT_1">%1$d</xliff:g></item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Цей додаток створено для старішої версії ОС Android. Якщо скасувати дозвіл, він може працювати неналежним чином."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"виконувати невідому дію"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Додатки з дозволом: <xliff:g id="COUNT_0">%1$d</xliff:g> з <xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Показати системні додатки"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Сховати системні додатки"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Немає додатків"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Налаштування геоданих"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> є постачальником служб локації для цього пристрою. Доступом до місцезнаходження можна керувати в налаштуваннях геоданих."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Якщо скасувати цей дозвіл, основні функції вашого пристрою можуть працювати неналежним чином."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Застосовується правилом"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Доступ у фоновому режимі вимкнено правилом"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Доступ у фоновому режимі ввімкнено правилом"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Доступ в активному режимі ввімкнено правилом"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Керує адміністратор"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Завжди"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Лише коли додаток активний"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Ніколи"</string>
-    <string name="loading" msgid="7811651799620593731">"Завантаження…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Усі дозволи"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Інші дозволи додатка"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Запит на дозвіл"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Виявлено накладання на екрані"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Щоб змінити налаштування цього дозволу, спершу вимкніть накладання на екрані в меню \"Налаштування\" &gt; \"Додатки\""</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Відкрити налаштування"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Дії \"установити\" або \"видалити\" не підтримуються на пристроях Android Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Виберіть, до чого &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; матиме доступ"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; оновлено. Виберіть, до чого цей додаток матиме доступ."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Скасувати"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Продовжити"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Нові дозволи"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Поточні дозволи"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Підготовка додатка…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Невідомо"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"З міркувань безпеки на вашому планшеті заборонено встановлювати невідомі додатки з цього джерела."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"З міркувань безпеки на вашому телевізорі заборонено встановлювати невідомі додатки з цього джерела."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"З міркувань безпеки на вашому телефоні заборонено встановлювати невідомі додатки з цього джерела."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Ваш телефон і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження телефона чи втрату даних унаслідок використання додатка."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ваш планшет і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження планшета чи втрату даних унаслідок використання додатка."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Ваш телевізор і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження телевізора чи втрату даних унаслідок використання додатка."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Продовжити"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Налаштування"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Встановлення або видалення додатків Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Програма встановлення пакета"</string>
+    <string name="install" msgid="711829760615509273">"Установити"</string>
+    <string name="done" msgid="6632441120016885253">"Готово"</string>
+    <string name="cancel" msgid="1018267193425558088">"Скасув."</string>
+    <string name="installing" msgid="4921993079741206516">"Встановлення…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Установлюється <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Програму встановлено."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Установити цю програму?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Установити оновлення для цього додатка? Наявні дані не буде втрачено."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Установити оновлення для цього вбудованого додатка? Наявні дані не буде втрачено."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Програму не встановлено."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Встановлення пакета заблоковано."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Додаток не встановлено, оскільки пакет конфліктує з наявним пакетом."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Додаток не встановлено, оскільки він несумісний із вашим планшетом."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Цей додаток несумісний із вашим телевізором."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Додаток не встановлено, оскільки він несумісний із вашим телефоном."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Додаток не встановлено, оскільки пакет недійсний."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити у вашому планшетному ПК."</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"Цей користувач не може встановлювати невідомі додатки"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Цей користувач не може встановлювати додатки"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Керувати додатками"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Недостат. місця"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Програму <xliff:g id="APP_NAME">%1$s</xliff:g> неможливо встановити. Звільніть місце та повторіть спробу."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Додаток не знайдено"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Програму не знайдено в списку встановлених програм."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Заборонено"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Поточний користувач не може видалити цей додаток."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Помилка"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Не вдалося видалити додаток."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Видалити додаток"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Видалити оновлення"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"Дія <xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> є частиною такої програми:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Видалити цей додаток?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Хочете видалити цю програму для "<b>"всіх"</b>" користувачів? Програму та її дані буде видалено для "<b>"всіх"</b>" користувачів цього пристрою."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Видалити цей додаток для користувача <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Відновити заводську версію цього додатка? Усі дані буде видалено."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Відновити заводську версію цього додатка? Усі дані буде видалено. Це вплине на всіх користувачів цього пристрою, зокрема на користувачів із робочими профілями."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Активні видалення"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Невиконані видалення"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Видалення..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Видалення додатка <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Видалено."</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Встановлення й видалення не підтримуються на пристроях Android Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Підготовка додатка…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Невідомо"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"З міркувань безпеки на вашому планшеті заборонено встановлювати невідомі додатки з цього джерела."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"З міркувань безпеки на вашому телевізорі заборонено встановлювати невідомі додатки з цього джерела."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"З міркувань безпеки на вашому телефоні заборонено встановлювати невідомі додатки з цього джерела."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Ваш телефон і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження телефона чи втрату даних унаслідок використання додатка."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Ваш планшет і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження планшета чи втрату даних унаслідок використання додатка."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Ваш телевізор і особисті дані більш уразливі до атак невідомих додатків. Установлюючи цей додаток, ви берете на себе відповідальність за пошкодження телевізора чи втрату даних унаслідок використання додатка."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Продовжити"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Налаштування"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Встановлення або видалення додатків Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml
deleted file mode 100644
index 78135a6..0000000
--- a/packages/PackageInstaller/res/values-ur/strings.xml
+++ /dev/null
@@ -1,156 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--  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.
- -->
-
-<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="2738748390251381682">"پیکیج انسٹال کنندہ"</string>
-    <string name="next" msgid="3057143178373252333">"اگلا"</string>
-    <string name="install" msgid="5896438203900042068">"انسٹال کریں"</string>
-    <string name="done" msgid="3889387558374211719">"ہو گیا"</string>
-    <string name="cancel" msgid="8360346460165114585">"منسوخ کریں"</string>
-    <string name="installing" msgid="8613631001631998372">"انسٹال کیا جا رہا ہے…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کو انسٹال کیا جا رہا ہے…"</string>
-    <string name="install_done" msgid="3682715442154357097">"ایپ انسٹال ہوگئی۔"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"کیا آپ یہ ایپلیکیشن انسٹال کرنا چاہتے ہیں؟ اس کو مندرجہ ذیل تک رسائی حاصل ہوگی:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"کیا آپ یہ ایپلیکیشن انسٹال کرنا چاہتے ہیں؟ اس کو کوئی خاص رسائی درکار نہیں۔"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"کیا آپ اس موجودہ ایپلیکیشن میں ایک اپ ڈیٹ انسٹال کرنا چاہتے ہیں؟ آپ کا موجودہ ڈیٹا ضائع نہیں ہوگا۔ اپ ڈیٹ کردہ ایپلیکیشن کو مندرجہ ذیل تک رسائی حاصل ہوگی:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"کیا آپ پہلے سے شامل اس ایپلیکیشن میں ایک اپ ڈیٹ انسٹال کرنا چاہتے ہیں؟ آپ کا موجودہ ڈیٹا ضائع نہیں ہوگا۔ اپ ڈیٹ کردہ ایپلیکیشن کو مندرجہ ذیل تک رسائی حاصل ہوگی:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"کیا آپ اس موجودہ ایپلیکیشن میں ایک اپ ڈیٹ انسٹال کرنا چاہتے ہیں؟ آپ کا موجودہ ڈیٹا ضائع نہیں ہوگا۔ اس کو کوئی خاص رسائی درکار نہیں۔"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"کیا آپ پہلے سے شامل اس ایپلیکیشن میں ایک اپ ڈیٹ انسٹال کرنا چاہتے ہیں؟ آپ کا موجودہ ڈیٹا ضائع نہیں ہوگا۔ اس کو کوئی خاص رسائی درکار نہیں۔"</string>
-    <string name="install_failed" msgid="6579998651498970899">"ایپ انسٹال نہیں ہوئی۔"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"پیکج کو انسٹال ہونے سے روک دیا گیا۔"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"ایپ کو پیکج کے بطور انسٹال نہیں کیا گیا کیونکہ پیکج ایک موجودہ پیکیج سے متصادم ہے۔"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"ایپ انسٹال نہیں ہوئی کیونکہ ایپ آپ کے ٹیبلیٹ کے ساتھ مطابقت پذیر نہیں ہے۔"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"‏یہ ایپ آپ کے TV کے ساتھ مطابقت پذیر نہیں ہے۔"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"ایپ انسٹال نہیں ہوئی کیونکہ ایپ آپ کے فون کے ساتھ مطابقت پذیر نہیں ہے۔"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"ایپ انسٹال نہیں ہوئی کیونکہ پیکیج غلط معلوم ہوتا ہے۔"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو آپ کے ٹیبلیٹ پر انسٹال نہیں کیا جا سکا۔"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"‏<xliff:g id="APP_NAME">%1$s</xliff:g> کو آپ کے TV پر انسٹال نہیں کیا جا سکا۔"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو آپ کے فون پر انسٹال نہیں کیا جا سکا۔"</string>
-    <string name="launch" msgid="4826921505917605463">"کھولیں"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"آپ کا منتظم نامعلوم ذرائع سے اخذ کردہ ایپس کو انسٹال کرنے کی اجازت نہیں دیتا ہے"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"اس صارف کے ذریعے نامعلوم ایپس کو انسٹال نہیں کیا جا سکتا"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"اس صارف کو ایپس انسٹال کرنے کی اجازت نہیں ہے"</string>
-    <string name="ok" msgid="3468756155452870475">"ٹھیک ہے"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"ایپس کا نظم کریں"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"جگہ ختم ہو گئی ہے"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو انسٹال نہیں کیا جا سکا۔ کچھ جگہ خالی کریں اور دوبارہ کوشش کریں۔"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"ایپ نہیں ملی"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"ایپ انسٹال کردہ ایپس کی فہرست میں نہیں ملی۔"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"اجازت نہیں ہے"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"موجودہ صارف کو اس ان انسٹالیشن کو سرانجام دینے کی اجازت نہیں ہے۔"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"خرابی"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"ایپ ان انسٹال نہیں ہو سکی۔"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"ایپ کو اَن انسٹال کریں"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"اپ ڈیٹ اَن انسٹال کریں"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> درج ذیل ایپ کا حصہ ہے:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"کیا آپ یہ ایپ اَن انسٹال کرنا چاہتے ہیں؟"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"کیا آپ "<b>"سبھی"</b>" صارفین کیلئے یہ ایپ اَن انسٹال کرنا چاہتے ہیں؟ ایپلیکیشن اور اس کا ڈیٹا آلے پر موجود "<b>"سبھی"</b>" صارفین سے ہٹا دیا جائے گا۔"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"کیا آپ اس ایپ کو صارف <xliff:g id="USERNAME">%1$s</xliff:g> کیلئے اَن انسٹال کرنا چاہتے ہیں؟"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"اس ایپ کو فیکٹری ورژن سے تبدیل کریں؟ تمام ڈیٹا ہٹا دیا جائے گا۔"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"اس ایپ کو فیکٹری ورژن سے تبدیل کریں؟ تمام ڈیٹا ہٹا دیا جائے گا۔ اس سے اس آلہ کے تمام صارف متاثر ہوں گے بشمول ان کے جن کے پاس دفتری پروفائلز ہیں۔"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"چل رہے اَن انسٹالس"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"ناکام اَن انسٹالس"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"اَن انسٹال ہو رہا ہے…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ان انسٹال ہو رہی ہے…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"اَن انسٹال پورا ہوگیا۔"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ان انسٹال ہو گیا"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"اَن انسٹال ناکام۔"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کو ان انسٹال کرنا کامیاب نہیں ہوا۔"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"فعال آلہ کے منتظم کی ایپ اَن انسٹال نہیں کر سکتے"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"فعال آلہ کے منتظم کی ایپ <xliff:g id="USERNAME">%1$s</xliff:g> کیلئے اَن انسٹال نہیں کر سکتے"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"یہ ایپ کچھ صارفین اور پروفائلوں کیلئے درکار ہے اور دیگر کیلئے ان انسٹال ہو گئی"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"یہ ایپ آپ کے پروفائل کیلئے درکار ہے اور یہ ان انسٹال نہیں ہو سکتی۔"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"یہ ایپ آپ کے آلہ کے منتظم کو درکار ہے اور اسے اَن انسٹال نہیں کیا جا سکتا ہے۔"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"آلہ کے منتظم کی ایپس کا نظم کریں"</string>
-    <string name="manage_users" msgid="3125018886835668847">"صارفین کا نظم کریں"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو اَن انسٹال نہیں کیا جا سکا۔"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"پیکیج کو پارس کرنے میں ایک دشواری پیش آگئی۔"</string>
-    <string name="newPerms" msgid="6039428254474104210">"نئی"</string>
-    <string name="allPerms" msgid="1024385515840703981">"سبھی"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"رازداری"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"آلہ کی رسائی"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"اس اپ ڈیٹ کو کوئی نئی اجازتیں درکار نہیں۔"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"مسترد کریں"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"مزید معلومات"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"بہرصورت انکار کریں"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> از <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو <xliff:g id="ACTION">%2$s</xliff:g> کی اجازت دیں؟"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"‏ہمیشہ ‎&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;‎ کو <xliff:g id="ACTION">%2$s</xliff:g> کی اجازت دیں؟"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"صرف ایپ استعمال کرنے کے دوران"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"ہمیشہ"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"انکار کریں اور دوبارہ مت پوچھیں"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> غیر فعال ہو گئیں"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"تمام غیر فعال ہو گئیں"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"کچھ بھی غیر فعال نہیں ہوا"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"اجازت دیں"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"ایپس"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"ایپ کی اجازتیں"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"دوبارہ مت پوچھیں"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"کوئی اجازتیں نہیں ہیں"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"اضافی اجازتیں"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"ایپ کی معلومات کھولیں"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مزید</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> مزید</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"‏یہ ایپ Android کے ایک پرانے ورژن کیلئے ڈیزائن کی گئی تھی۔ اجازت دینے سے انکار کرنے پر ممکن ہے کہ وہ مزید ٹھیک سے کام نہ کرے۔"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"ایک نامعلوم کارروائی کو انجام دیں"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_1">%2$d</xliff:g> میں سے <xliff:g id="COUNT_0">%1$d</xliff:g> ایپس کو اجازت دے دی گئی"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"سسٹم دکھائیں"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"سسٹم چھپائیں"</string>
-    <string name="no_apps" msgid="1965493419005012569">"کوئی ایپس نہیں ہیں"</string>
-    <string name="location_settings" msgid="1774875730854491297">"مقام کی ترتیبات"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> اس آلہ کیلئے مقام کی سروسز کا فراہم کنندہ ہے۔ مقام کی رسائی میں مقام کی ترتیبات سے ترمیم کی جا سکتی ہے۔"</string>
-    <string name="system_warning" msgid="7103819124542305179">"اگرآپ اس اجازت کو مسترد کرتے ہیں تو شاید آپ کے آلہ کی بنیادی خصوصیات ٹھیک سے کام نہ کریں۔"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"پالیسی کی طرف سے نافذ کردہ"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"پالیسی نے پس منظر کی رسائی غیر فعال کر دی ہے"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"پالیسی نے پس منظر کی رسائی فعال کر دی ہے"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"پالیسی نے پیش منظر کی رسائی فعال کر دی ہے"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"کنٹرول کردہ بذریعہ منتظم"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"ہمیشہ"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"صرف ایپ استعمال کرنے کے دوران"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"کبھی نہیں"</string>
-    <string name="loading" msgid="7811651799620593731">"لوڈ ہورہا ہے…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"تمام اجازاتیں"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"دوسری ایپ اہلیتیں"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"اجازت کی درخواست"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"اسکرین اورلے کا پتہ چلا ہے"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"‏اس اجازت کی ترتیب کو تبدیل کرنے کیلئے آپ کو پہلے ترتیبات &gt; Apps سے سکرین اورلے آف کرنا ہوگا"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"ترتیبات کھولیں"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"‏\'کاروائیاں انسٹال/ان انسٹال کریں\' Wear پر تعاون یافتہ نہیں ہے۔"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"‏انتخاب کریں کہ &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; کو کس تک رسائی کی اجازت دینی ہے"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"‏&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; اپ ڈیٹ ہو گئی ہے۔ انتخاب کریں کہ اس ایپ کو کس تک رسائی کی اجازت دینی ہے۔"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"منسوخ کریں"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"جاری رکھیں"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"نئی اجازتیں"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"موجودہ اجازتیں"</string>
-    <string name="message_staging" msgid="6151794817691100003">"ایپ کی مرحلہ بندی ہو رہی ہے…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"نامعلوم"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"آپ کی سیکیوریٹی کیلئے، آپ کے ٹیبلیٹ کو اس ذریعے سے نامعلوم ایپس انسٹال کرنے کی اجازت نہیں ہے۔"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"‏آپ کی سیکیوریٹی کیلئے، آپ کے TV کو اس ذریعے سے نامعلوم ایپس انسٹال کرنے کی اجازت نہیں ہے۔"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"آپ کی سیکیوریٹی کیلئے، آپ کے فون کو اس ذریعے سے نامعلوم ایپس انسٹال کرنے کی اجازت نہیں ہے۔"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"آپ کے فون اور ذاتی ڈیٹا کو نامعلوم ایپس کی جانب سے حملے کا زیادہ خطرہ ہے۔ اس ایپ کو انسٹال کر کے، آپ اس بات سے اتفاق کرتے ہیں کہ آپ اس سے اپنے فون کو ہونے والے کسی بھی نقصان یا ڈیٹا کے نقصان کیلئے خود ذمہ دار ہیں۔"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"آپ کے ٹیبلیٹ اور ذاتی ڈیٹا کو نامعلوم ایپس کی جانب سے حملے کا زیادہ خطرہ ہے۔ اس ایپ کو انسٹال کر کے، آپ اس بات سے اتفاق کرتے ہیں کہ آپ اس سے اپنے ٹیبلیٹ کو ہونے والے کسی بھی نقصان یا ڈیٹا کے نقصان کیلئے خود ذمہ دار ہیں۔"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"‏آپ کے TV اور ذاتی ڈیٹا کو نامعلوم ایپس کی جانب سے حملے کا زیادہ خطرہ ہے۔ اس ایپ کو انسٹال کر کے، آپ اس بات سے اتفاق کرتے ہیں کہ آپ اس سے اپنے TV کو ہونے والے کسی بھی نقصان یا ڈیٹا کے نقصان کیلئے خود ذمہ دار ہیں۔"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"جاری رکھیں"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"ترتیبات"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"‏wear ایپس کا انسٹال/ان انسٹال کرنا"</string>
-</resources>
diff --git a/packages/PackageInstaller/res/values-uz/strings.xml b/packages/PackageInstaller/res/values-uz/strings.xml
index 15a2e92..e692e0d 100644
--- a/packages/PackageInstaller/res/values-uz/strings.xml
+++ b/packages/PackageInstaller/res/values-uz/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Paket o‘rnatish vositasi"</string>
-    <string name="next" msgid="3057143178373252333">"Keyingisi"</string>
-    <string name="install" msgid="5896438203900042068">"O‘rnatish"</string>
-    <string name="done" msgid="3889387558374211719">"Tayyor"</string>
-    <string name="cancel" msgid="8360346460165114585">"Bekor qilish"</string>
-    <string name="installing" msgid="8613631001631998372">"O‘rnatilmoqda…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘rnatilmoqda…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Ilova o‘rnatildi."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Bu ilovani o‘rnatmoqchimisiz? U quyidagi ruxsatlarga ega:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Bu ilovani o‘rnatmoqchimisiz? U hech qanday maxsus ruxsat talab qilmaydi."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Bu ilova uchun yangilanishni o‘rnatmoqchimisiz? Yangilanganidan keyin u quyidagi ruxsatlarga ega bo‘ladi:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Bu ilova uchun yangilanishni o‘rnatmoqchimisiz? Yangilanganidan keyin u quyidagi ruxsatlarga ega bo‘ladi:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ushbu mavjud ilovaga yangilanish o‘rnatilsinmi? Mavjud ma’lumotlaringiz o‘chib ketmaydi. U hech qanday maxsus ruxsat talab qilmaydi."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ushbu tizim ilovasiga yangilanish o‘rnatilsinmi? Mavjud ma’lumotlaringiz o‘chib ketmaydi. U hech qanday maxsus ruxsat talab qilmaydi."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Ilova o‘rnatilmadi."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Paket o‘rnatilishga qarshi bloklangan."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Paket mavjud paket bilan zid kelganligi uchun ilovani o‘rnatib bo‘lmadi."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Ilova planshetingizga mos kelmaganligi uchun uni o‘rnatib bo‘lmadi."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Bu ilova televizoringiz bilan mos emas."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Ilova telefoningizga mos kelmaganligi uchun uni o‘rnatib bo‘lmadi."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Paket yaroqsiz bo‘lganligi uchun ilovani o‘rnatib bo‘lmadi."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"<xliff:g id="APP_NAME">%1$s</xliff:g> planshetingizga o‘rnatilmadi."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasini televizoringizga o‘rnatib bo‘lmadi."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"<xliff:g id="APP_NAME">%1$s</xliff:g> telefoningizga o‘rnatilmadi."</string>
-    <string name="launch" msgid="4826921505917605463">"Ochish"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Administratoringiz begona manbalardan olingan ilovalarni o‘rnatishga ruxsat bermagan"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Notanish ilovalarni bu foydalanuvchi tomonidan o‘rnatib bo‘lmaydi"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Bu foydalanuvchiga ilovalarni o‘rnatish uchun ruxsat berilmagan"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Ilovalarni boshqarish"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Joy qolmadi"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"<xliff:g id="APP_NAME">%1$s</xliff:g> o‘rnatilmadi. Xotiradan biroz joy bo‘shating va qaytadan urinib ko‘ring."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Ilova topilmadi"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Ilova o‘rnatilgan ilovalar ro‘yxatidan topilmadi."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Ruxsat berilmagan"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Joriy foydalanuvchiga bu o‘chirishni amalga oshirishi uchun ruxsat berilmagan."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Xato"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Ilovani o‘chirib bo‘lmadi"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Ilovani o‘chirish"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Yangilanishni o‘chirish"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> quyidagi ilovaning bir qismidir:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Bu ilova o‘chirib tashlansinmi?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ushbu ilova "<b>"barcha"</b>" foydalanuvchilar uchun o‘chirilsinmi? Ilova va uning ma’lumotlari qurilmadagi "<b>"barcha"</b>" foydalanuvchilardan o‘chib ketadi."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Haqiqatdan ham <xliff:g id="USERNAME">%1$s</xliff:g> foydalanuvchi uchun ushbu ilovani olib tashlamoqchimisiz?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Bu ilova boshlang‘ich versiyasi bilan almashtirilsinmi? Barcha ma’lumotlar o‘chirib tashlanadi."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Bu ilova boshlang‘ich versiyasi bilan almashtirilsinmi? Barcha ma’lumotlar o‘chirib tashlanadi. Bu qurilmaning barcha foydalanuvchilariga, jumladan, ularning ishchi profillariga ham ta’sir qiladi."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Davom etayotganlar"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Amalga oshmaganlar"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"O‘chirilmoqda…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirilmoqda…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"O‘chirib tashlandi."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirib tashlandi"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"O‘chirish muvaffaqiyatsizlikka uchradi."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ilovasini o‘chirib bo‘lmadi."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Faol qurilma administratori ilovasini o‘chirib bo‘lmaydi"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"<xliff:g id="USERNAME">%1$s</xliff:g> profilida faol qurilma administratori ilovasini o‘chirib bo‘lmaydi"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Bu ilova ba’zi foydalanuvchi yoki profillar uchun zarur, boshqalar uchun esa o‘chirib tashlangan"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Bu ilova profilingiz uchun kerak va uni o‘chirib bo‘lmaydi."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ushbu ilova qurilmangiz ma\'muri tomonidan ishlatiladi, shuning uchun uni olib tashlab bo\'lmaydi."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Qurilma administratori ilovalarini boshqarish"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Foydalanuvchilarni boshqarish"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"<xliff:g id="APP_NAME">%1$s</xliff:g> o‘chirilmadi."</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Paketni tahlil qilishda muammo yuz berdi."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Yangi"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Barchasi"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Maxfiylik"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Qurilmalardan foydalanish"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Ushbu yangilanish hech qanday yangi ruxsatlarni talab qilmaydi."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Rad etish"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Batafsil"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Baribir rad etilsin"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ilovasiga <xliff:g id="ACTION">%2$s</xliff:g> uchun ruxsat berilsinmi?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ilovasiga bu amalga bajarishga doim ruxsat berilsinmi: <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Faqat ilova ishlatilayotganda"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Har doim"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Rad etilsin va boshqa so‘ralmasin"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> tasi o‘chiq"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"hammasi o‘chiq"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"hech qaysi o‘chirilmagan"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Ruxsat berish"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Ilovalar"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Ilovalar uchun ruxsatlar"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Boshqa so‘ralmasin"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Hech narsa topilmadi"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Qo‘shimcha ruxsatlar"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Ilovaga oid ma’lumotni ochish"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">Yana <xliff:g id="COUNT_1">%1$d</xliff:g> ta</item>
-      <item quantity="one">Yana <xliff:g id="COUNT_0">%1$d</xliff:g> ta</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Bu ilova Androidning eskiroq versiyasiga mo‘ljallab ishlab chiqilgan. Agar ruxsat bermasangiz, u kutilganidek ishlamasligi mumkin."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"noma’lum amalni bajarish"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Ruxsat berilgan: <xliff:g id="COUNT_0">%1$d</xliff:g>/<xliff:g id="COUNT_1">%2$d</xliff:g>"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Tizimga oid jarayonlar"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Tizimga oid jarayonlarni berkitish"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Hech qanday ilova yo‘q"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Joylashuv sozlamalari"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu qurilma uchun joylashuvni aniqlash xizmatini taqdim etuvchi ilova hisoblanadi. Joylashuv ma’lumotlariga kirish vakolatini joylashuv sozlamalaridan o‘zgartirish mumkin."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Agar bu ruxsatni rad qilsangiz, qurilmangizning asosiy funksiyalari bundan buyon kutilganidek ishlamasligi mumkin."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Qoidaga muvofiq"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Fon rejimida kirish qoidaga muvofiq taqiqlangan"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Fon rejimida kirish qoidaga muvofiq yoqilgan"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Faol rejimda kirish qoidaga muvofiq yoqilgan"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Administrator tomonidan boshqariladi"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Har doim"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Faqat ilova ishlatilayotganda"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Hech qachon"</string>
-    <string name="loading" msgid="7811651799620593731">"Yuklanmoqda…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Barcha ruxsatnomalar"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Ilovaning boshqa imkoniyatlari"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Ruxsatnoma so‘rovi"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Boshqa oynalar ustidan ochiladigan ilova aniqlandi"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Bu ruxsatnoma parametrini o‘zgartirish uchun avval Sozlamalar &gt; Ilovalar bo‘limidan ekran ustidan ochilish funksiyasini o‘chirib qo‘ying"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Sozlamalarni ochish"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear qurilmasi o‘rnatish/o‘chirish amallarini qo‘llab-quvvatlamaydi."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; uchun beriladigan ruxsatlarni tanlang"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; yangilandi. Unga beriladigan ruxsatlarni tanlang."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Bekor qilish"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Davom etish"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Yangi ruxsatnomalar"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Joriy ruxsatnomalar"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Kutib turing…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Noma’lum"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Xavfsizlik yuzasidan, planshetingizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Xavfsizlik yuzasidan, televizoringizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Xavfsizlik yuzasidan, telefoningizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Telefoningiz va shaxsiy ma‘lumotlaringiz notanish ilovalar xujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan telefoningizga yetkaziladigan shikast va ma‘lumotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Planshetingiz va shaxsiy ma‘lumotlaringiz notanish ilovalar xujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan planshetingizga yetkaziladigan shikast va ma‘lumotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV va shaxsiy ma‘lumotlaringiz notanish ilovalar xujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan televizoringizga yetkaziladigan shikast va ma‘lumotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Davom etish"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Sozlamalar"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Wear ilovalarini o‘rnatish/o‘chirish"</string>
+    <string name="app_name" msgid="7488448184431507488">"Paket o‘rnatish vositasi"</string>
+    <string name="install" msgid="711829760615509273">"O‘rnatish"</string>
+    <string name="done" msgid="6632441120016885253">"OK"</string>
+    <string name="cancel" msgid="1018267193425558088">"Bekor qilish"</string>
+    <string name="installing" msgid="4921993079741206516">"O‘rnatilmoqda…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘rnatilmoqda…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Ilova o‘rnatildi."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Bu ilovani o‘rnatmoqchimisiz?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Bu ilova uchun yangilanish o‘rnatilsinmi? Mavjud axborotlaringiz o‘chib ketmaydi."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Bu ichki ilova uchun yangilanish o‘rnatilsinmi? Mavjud axborotlaringiz o‘chib ketmaydi."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Ilova o‘rnatilmadi."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Paket o‘rnatilishga qarshi bloklangan."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Paket mavjud paket bilan zid kelganligi uchun ilovani o‘rnatib bo‘lmadi."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Ilova planshetingizga mos kelmaganligi uchun uni o‘rnatib bo‘lmadi."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Bu ilova televizoringiz bilan mos emas."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Ilova telefoningizga mos kelmaganligi uchun uni o‘rnatib bo‘lmadi."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Paket yaroqsizligi uchun ilovani o‘rnatib bo‘lmadi."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"<xliff:g id="APP_NAME">%1$s</xliff:g> planshetingizga o‘rnatilmadi."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi televizoringizga o‘rnatilmadi."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"<xliff:g id="APP_NAME">%1$s</xliff:g> telefoningizga o‘rnatilmadi."</string>
+    <string name="launch" msgid="3952550563999890101">"Ochish"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Administratoringiz begona manbalardan olingan ilovalarni o‘rnatishga ruxsat bermagan"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Notanish ilovalarni bu foydalanuvchi tomonidan o‘rnatib bo‘lmaydi"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Bu foydalanuvchiga ilovalarni o‘rnatish uchun ruxsat berilmagan"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Ilovalarni boshqarish"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Joy qolmadi"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"<xliff:g id="APP_NAME">%1$s</xliff:g> o‘rnatilmadi. Xotiradan biroz joy bo‘shating va qaytadan urining."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Ilova topilmadi"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"lova o‘rnatilgan ilovalar ro‘yxatidan topilmadi."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Ruxsat berilmagan"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Joriy foydalanuvchiga bu o‘chirishni amalga oshirishi uchun ruxsat berilmagan."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Xato"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Ilova o‘chirib tashlanmadi."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Ilovani o‘chirish"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Yangilanishni o‘chirish"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> quyidagi ilovaning bir qismidir:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Bu ilovani o‘chirib tashlamoqchimisiz?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Ushbu ilova "<b>"barcha"</b>" foydalanuvchilar uchun o‘chirilsinmi? Ilova va uning axborotlari qurilmadagi "<b>"barcha"</b>" foydalanuvchilardan o‘chib ketadi."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Haqiqatdan ham <xliff:g id="USERNAME">%1$s</xliff:g> foydalanuvchi uchun ushbu ilovani olib tashlamoqchimisiz?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Bu ilova boshlang‘ich versiyasi bilan almashtirilsinmi? Barcha axborotlar o‘chirib tashlanadi."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Bu ilova boshlang‘ich versiyasi bilan almashtirilsinmi? Barcha axborotlar o‘chirib tashlanadi. Bu qurilmaning barcha foydalanuvchilariga, jumladan, ularning ishchi profillariga ham ta’sir qiladi."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Davom etayotganlar"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Amalga oshmaganlar"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"O‘chirilmoqda…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirilmoqda…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"O‘chirib tashlandi."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> o‘chirib tashlandi"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"O‘chirib tashlanmadi."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ilovasini o‘chirib bo‘lmadi."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Faol qurilma administratori ilovasini o‘chirib bo‘lmaydi"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"<xliff:g id="USERNAME">%1$s</xliff:g> profilida faol qurilma administratori ilovasini o‘chirib bo‘lmaydi"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Bu ilova ba’zi foydalanuvchi yoki profillar uchun zarur, boshqalar uchun esa o‘chirib tashlangan"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Bu ilova profilingiz uchun kerak va uni o‘chirib bo‘lmaydi."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Bu ilova qurilmangiz administratori tomonidan ishlatiladi, shuning uchun uni olib tashlab bo‘lmaydi."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Qurilma administratori ilovalarini boshqarish"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Foydalanuvchilarni boshqarish"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"<xliff:g id="APP_NAME">%1$s</xliff:g> o‘chirilmadi."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Paketni tahlil qilishda muammo yuz berdi."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear qurilmasi o‘rnatish/o‘chirish amallarini qo‘llab-quvvatlamaydi."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Kutib turing…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Noaniq"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Xavfsizlik yuzasidan, planshetingizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Xavfsizlik yuzasidan, televizoringizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Xavfsizlik yuzasidan, telefoningizga bu manbadan notanish ilovalarni o‘rnatishga ruxsat berilmagan."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefoningiz va shaxsiy axborotlaringiz notanish ilovalar hujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan telefoningizga yetkaziladigan shikast va axborotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Planshetingiz va shaxsiy axborotlaringiz notanish ilovalar hujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan planshetingizga yetkaziladigan shikast va axborotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV va shaxsiy axborotlaringiz notanish ilovalar hujumiga zaif bo‘ladi. Bu ilovani o‘rnatish bilan televizoringizga yetkaziladigan shikast va axborotlaringizni o‘chirib yuborilishiga javobgarlikni o‘z zimmangizga olasiz."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Davom etish"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Sozlamalar"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Wear ilovalarini o‘rnatish/o‘chirish"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-vi/strings.xml b/packages/PackageInstaller/res/values-vi/strings.xml
index 09998d8..91aa71c 100644
--- a/packages/PackageInstaller/res/values-vi/strings.xml
+++ b/packages/PackageInstaller/res/values-vi/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Trình cài đặt gói"</string>
-    <string name="next" msgid="3057143178373252333">"Tiếp theo"</string>
-    <string name="install" msgid="5896438203900042068">"Cài đặt"</string>
-    <string name="done" msgid="3889387558374211719">"Xong"</string>
-    <string name="cancel" msgid="8360346460165114585">"Hủy"</string>
-    <string name="installing" msgid="8613631001631998372">"Đang cài đặt…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"Đang cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"Ứng dụng đã được cài đặt."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Bạn có muốn cài đặt ứng dụng này không? Ứng dụng sẽ có quyền truy cập vào:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Bạn có muốn cài đặt ứng dụng này không? Ứng dụng này không yêu cầu bất kỳ quyền truy cập đặc biệt nào."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng hiện tại này không? Dữ liệu hiện tại của bạn sẽ không bị mất. Ứng dụng đã cập nhật sẽ có quyền truy cập vào:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng được cài sẵn này không? Dữ liệu hiện tại của bạn sẽ không bị mất. Ứng dụng được cập nhật sẽ có quyền truy cập vào:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng hiện có này không? Dữ liệu hiện có của bạn sẽ không bị mất. Việc cài đặt không yêu cầu bất kỳ quyền truy cập đặc biệt nào."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng cài sẵn này không? Dữ liệu hiện có của bạn sẽ không bị mất. Việc cài đặt không yêu cầu quyền truy cập đặc biệt nào."</string>
-    <string name="install_failed" msgid="6579998651498970899">"Ứng dụng chưa được cài đặt."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Đã chặn cài đặt gói."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Ứng dụng chưa được cài đặt dưới dạng gói xung đột với gói hiện có."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Ứng dụng chưa được cài đặt dưới dạng ứng dụng không tương thích với máy tính bảng của bạn."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Ứng dụng này không tương thích với TV của bạn."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Ứng dụng chưa được cài đặt dưới dạng ứng dụng không tương thích với điện thoại của bạn."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Ứng dụng chưa được cài đặt dưới dạng gói dường như không hợp lệ."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g> trên máy tính bảng của bạn."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"Không cài đặt được <xliff:g id="APP_NAME">%1$s</xliff:g> trên TV của bạn."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g> trên điện thoại này."</string>
-    <string name="launch" msgid="4826921505917605463">"Mở"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Quản trị viên của bạn không cho phép cài đặt ứng dụng từ nguồn không xác định"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Người dùng này không thể cài đặt ứng dụng không xác định"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Người dùng này không được phép cài đặt ứng dụng"</string>
-    <string name="ok" msgid="3468756155452870475">"OK"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Quản lý ứng dụng"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Hết dung lượng"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g>. Hãy giải phóng dung lượng và thử lại."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"Không tìm thấy ứng dụng"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Không tìm thấy ứng dụng trong danh sách các ứng dụng đã cài đặt."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Không được phép"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Người dùng hiện tại không được phép thực hiện quá trình gỡ cài đặt này."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Lỗi"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Không thể gỡ cài đặt ứng dụng."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Gỡ cài đặt ứng dụng"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Gỡ cài đặt cập nhật"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> là một phần của ứng dụng sau:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Bạn có muốn gỡ cài đặt ứng dụng này không?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Bạn có muốn gỡ cài đặt ứng dụng này cho "<b>"tất cả"</b>" người dùng không? Ứng dụng và dữ liệu của ứng dụng sẽ bị xóa khỏi "<b>"tất cả"</b>" người dùng trên thiết bị."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Bạn có muốn gỡ cài đặt ứng dụng này cho người dùng <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Thay thế ứng dụng này bằng phiên bản gốc? Tất cả dữ liệu sẽ bị xóa."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Thay thế ứng dụng này bằng phiên bản gốc? Tất cả dữ liệu sẽ bị xóa. Điều này ảnh hưởng đến tất cả người dùng thiết bị này, bao gồm cả những người có hồ sơ công việc."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Gỡ cài đặt đang chạy"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Gỡ cài đặt không thành công"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Đang gỡ cài đặt..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Đang gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Gỡ cài đặt đã hoàn tất."</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Đã gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Gỡ cài đặt không thành công."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> không thành công."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Không thể gỡ cài đặt ứng dụng dành cho quản trị viên thiết bị đang hoạt động"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Không thể gỡ cài đặt ứng dụng dành cho quản trị viên thiết bị đang hoạt động cho <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Ứng dụng này bắt buộc với một số người dùng hoặc hồ sơ và được gỡ cài đặt cho người khác"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Ứng dụng này là cần thiết cho hồ sơ của bạn và không thể gỡ cài đặt."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Ứng dụng này được quản trị viên thiết bị của bạn yêu cầu và không thể gỡ cài đặt."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Quản lý ứng dụng quản trị thiết bị"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Quản lý người dùng"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"Không thể gỡ cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Đã xảy ra sự cố khi phân tích cú pháp gói."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Mới"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Tất cả"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Bảo mật"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Truy cập thiết bị"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Bản cập nhật này không yêu cầu quyền mới."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Từ chối"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Thông tin khác"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Vẫn từ chối"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> / <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Cho phép &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Luôn cho phép &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Chỉ khi sử dụng ứng dụng"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Luôn luôn"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Từ chối và không hỏi lại"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"Đã vô hiệu hóa <xliff:g id="COUNT">%1$d</xliff:g>"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"tất cả quyền đều bị vô hiệu hóa"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"không có quyền nào bị vô hiệu hóa"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Cho phép"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Ứng dụng"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Quyền của ứng dụng"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Không hỏi lại"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Không có quyền"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Quyền khác"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Mở thông tin về ứng dụng"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> quyền khác</item>
-      <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> quyền khác</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Ứng dụng này được thiết kế cho các phiên bản Android cũ hơn. Từ chối quyền có thể làm cho ứng dụng không còn hoạt động như mong muốn."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"thực hiện hành động không xác định"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"Đã cho phép <xliff:g id="COUNT_0">%1$d</xliff:g> trong số <xliff:g id="COUNT_1">%2$d</xliff:g> ứng dụng"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Hiển thị hệ thống"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Ẩn hệ thống"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Không có ứng dụng"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Cài đặt vị trí"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> là nhà cung cấp dịch vụ vị trí cho thiết bị này. Bạn có thể sửa đổi quyền truy cập vị trí từ cài đặt vị trí."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Nếu bạn từ chối quyền này, các tính năng cơ bản trên thiết bị của bạn có thể không còn hoạt động như dự kiến."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Được thực thi bằng chính sách"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Quyền truy cập nền bị tắt theo chính sách"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Quyền truy cập nền được bật theo chính sách"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Quyền truy cập nền trước được bật theo chính sách"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Do quản trị viên kiểm soát"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Luôn luôn"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Chỉ khi sử dụng ứng dụng"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Không bao giờ"</string>
-    <string name="loading" msgid="7811651799620593731">"Đang tải…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Tất cả các quyền"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Các khả năng khác của ứng dụng"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Yêu cầu quyền"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Đã phát hiện lớp phủ màn hình"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Để thay đổi cài đặt quyền này, trước tiên bạn phải tắt lớp phủ màn hình từ Cài đặt &gt; Ứng dụng"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Mở cài đặt"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Không hỗ trợ tác vụ Cài đặt/Gỡ cài đặt trên Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Chọn cho phép &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; truy cập những gì"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"Đã cập nhật &lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;. Chọn cho phép ứng dụng này truy cập những gì."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Hủy"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Tiếp tục"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Các quyền mới"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Các quyền hiện tại"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Đang sắp xếp ứng dụng…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Không xác định"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Để bảo mật, máy tính bảng của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Để bảo mật, TV của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Để bảo mật, điện thoại của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Điện thoại và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với điện thoại của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Máy tính bảng và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với máy tính bảng của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"TV và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với TV của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Tiếp tục"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Cài đặt"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Cài đặt/gỡ cài đặt ứng dụng Wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Trình cài đặt gói"</string>
+    <string name="install" msgid="711829760615509273">"Cài đặt"</string>
+    <string name="done" msgid="6632441120016885253">"Xong"</string>
+    <string name="cancel" msgid="1018267193425558088">"Hủy"</string>
+    <string name="installing" msgid="4921993079741206516">"Đang cài đặt…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"Đang cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Ứng dụng đã được cài đặt."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Bạn có muốn cài đặt ứng dụng này không?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng hiện có này không? Dữ liệu hiện có của bạn sẽ không bị mất."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Bạn có muốn cài đặt bản cập nhật cho ứng dụng cài sẵn này không? Dữ liệu hiện có của bạn sẽ không bị mất."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Ứng dụng chưa được cài đặt."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Đã chặn cài đặt gói."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Chưa cài đặt được ứng dụng do gói xung đột với một gói hiện có."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Chưa cài đặt được ứng dụng do ứng dụng không tương thích với máy tính bảng của bạn."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Ứng dụng này không tương thích với TV của bạn."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Chưa cài đặt được ứng dụng do ứng dụng không tương thích với điện thoại của bạn."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Chưa cài đặt được ứng dụng do gói có vẻ không hợp lệ."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g> trên máy tính bảng của bạn."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g> trên TV của bạn."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g> trên điện thoại của bạn."</string>
+    <string name="launch" msgid="3952550563999890101">"Mở"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Quản trị viên của bạn không cho phép cài đặt ứng dụng từ nguồn không xác định"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Người dùng này không thể cài đặt ứng dụng không xác định"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Người dùng này không được phép cài đặt ứng dụng"</string>
+    <string name="ok" msgid="7871959885003339302">"OK"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Quản lý ứng dụng"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Hết dung lượng"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"Không thể cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g>. Hãy giải phóng dung lượng và thử lại."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Không tìm thấy ứng dụng"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Không tìm thấy ứng dụng trong danh sách các ứng dụng đã cài đặt."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Không được phép"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Người dùng hiện tại không được phép thực hiện quá trình gỡ cài đặt này."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Lỗi"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Không thể gỡ cài đặt ứng dụng."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Gỡ cài đặt ứng dụng"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Gỡ cài đặt bản cập nhật"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> là một phần của ứng dụng sau:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Bạn có muốn gỡ cài đặt ứng dụng này không?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Bạn có muốn gỡ cài đặt ứng dụng này cho "<b>"tất cả"</b>" người dùng không? Ứng dụng và dữ liệu của ứng dụng sẽ bị xóa khỏi "<b>"tất cả"</b>" người dùng trên thiết bị."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Bạn có muốn gỡ cài đặt ứng dụng này cho người dùng <xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Thay thế ứng dụng này bằng phiên bản gốc? Tất cả dữ liệu sẽ bị xóa."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Thay thế ứng dụng này bằng phiên bản gốc? Tất cả dữ liệu sẽ bị xóa. Điều này ảnh hưởng đến tất cả người dùng thiết bị này, bao gồm cả những người có hồ sơ công việc."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Các quá trình gỡ cài đặt đang chạy"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Gỡ cài đặt không thành công"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Đang gỡ cài đặt..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Đang gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Đã gỡ cài đặt xong."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Đã gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Gỡ cài đặt không thành công."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Gỡ cài đặt <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> không thành công."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Không thể gỡ cài đặt ứng dụng quản trị thiết bị đang hoạt động"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Không thể gỡ cài đặt ứng dụng quản trị thiết bị đang hoạt động cho <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Ứng dụng này bắt buộc với một số người dùng hoặc hồ sơ và được gỡ cài đặt cho người khác"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Ứng dụng này là cần thiết cho hồ sơ của bạn và không thể gỡ cài đặt."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Ứng dụng này được quản trị viên thiết bị yêu cầu và không thể gỡ cài đặt."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Quản lý ứng dụng quản trị thiết bị"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Quản lý người dùng"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"Không thể gỡ cài đặt <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Đã xảy ra sự cố khi phân tích cú pháp gói."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Không hỗ trợ thao tác Cài đặt/Gỡ cài đặt trên ứng dụng Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Đang thử nghiệm ứng dụng…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Không xác định"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Để bảo mật, máy tính bảng của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Để bảo mật, TV của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Để bảo mật, điện thoại của bạn không được phép cài đặt các ứng dụng không xác định từ nguồn này."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Điện thoại và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với điện thoại của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Máy tính bảng và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với máy tính bảng của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV và dữ liệu cá nhân của bạn dễ bị các ứng dụng không xác định tấn công hơn. Bằng cách cài đặt ứng dụng này, bạn đồng ý tự chịu trách nhiệm cho mọi hỏng hóc đối với TV của mình hoặc mất mát dữ liệu có thể phát sinh do sử dụng ứng dụng này."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Tiếp tục"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Cài đặt"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Cài đặt/gỡ cài đặt ứng dụng Wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-zh-rCN/strings.xml b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
index d559774..d3b5e68 100644
--- a/packages/PackageInstaller/res/values-zh-rCN/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rCN/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"软件包安装程序"</string>
-    <string name="next" msgid="3057143178373252333">"下一步"</string>
-    <string name="install" msgid="5896438203900042068">"安装"</string>
-    <string name="done" msgid="3889387558374211719">"完成"</string>
-    <string name="cancel" msgid="8360346460165114585">"取消"</string>
-    <string name="installing" msgid="8613631001631998372">"正在安装..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"正在安装<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"应用安装完成。"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"要安装此应用吗?它将获得以下权限:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"您要安装此应用吗?此应用不需要任何特殊权限。"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"您要安装此应用的新版本吗?您现有的数据不会丢失。更新后的应用将具备以下权限:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"您要安装此内置应用的新版本吗?您现有的数据不会丢失。更新后的应用将具备以下权限:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"是否要为这一现有应用安装更新?您现有的数据不会丢失,且安装过程无需任何特殊权限。"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"是否要为这一内置应用安装更新?您现有的数据不会丢失,且安装过程无需任何特殊权限。"</string>
-    <string name="install_failed" msgid="6579998651498970899">"应用未安装。"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"系统禁止安装该软件包。"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"应用未安装:软件包与现有软件包存在冲突。"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"应用未安装:应用与您的平板电脑不兼容。"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"此应用与您的电视不兼容。"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"应用未安装:应用与您的手机不兼容。"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"应用未安装:软件包似乎无效。"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"无法在您的平板电脑上安装“<xliff:g id="APP_NAME">%1$s</xliff:g>”。"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"无法将<xliff:g id="APP_NAME">%1$s</xliff:g>安装到您的电视上。"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"无法在您的手机上安装“<xliff:g id="APP_NAME">%1$s</xliff:g>”。"</string>
-    <string name="launch" msgid="4826921505917605463">"打开"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"您的管理员不允许安装来源不明的应用"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"该用户无法安装未知应用"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"此用户不能安装应用"</string>
-    <string name="ok" msgid="3468756155452870475">"确定"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"管理应用"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"没有存储空间"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"无法安装“<xliff:g id="APP_NAME">%1$s</xliff:g>”,请释放一些存储空间并重试。"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"未找到应用"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"未在已安装应用的列表中找到该应用。"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"不允许"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"当前用户无法执行这项卸载操作。"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"错误"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"无法卸载应用。"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"卸载应用"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"卸载更新"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>属于以下应用:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"要卸载此应用吗?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"是否要为"<b>"所有"</b>"用户卸载此应用?系统将为设备上的"<b>"所有"</b>"用户删除此应用及其数据。"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"您要为用户<xliff:g id="USERNAME">%1$s</xliff:g>卸载此应用吗?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"要将此应用替换为出厂版本吗?这样会移除所有数据。"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"要将此应用替换为出厂版本吗?这样会移除所有数据,并会影响此设备的所有用户(包括已设置工作资料的用户)。"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"进行中的卸载操作"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"失败的卸载操作"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"正在卸载..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"正在卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"卸载完成。"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"已卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"卸载失败。"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>失败。"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"无法卸载正在使用中的设备管理应用"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"无法为<xliff:g id="USERNAME">%1$s</xliff:g>卸载正在使用中的设备管理应用"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"这是部分用户或个人资料所需的应用;已为其他用户或个人资料卸载此应用"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"这是您的个人资料所需的应用,因此无法卸载。"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"这是您的设备管理员要求必须安装的应用,因此无法卸载。"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"管理设备管理应用"</string>
-    <string name="manage_users" msgid="3125018886835668847">"管理用户"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"无法卸载“<xliff:g id="APP_NAME">%1$s</xliff:g>”。"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"解析软件包时出现问题。"</string>
-    <string name="newPerms" msgid="6039428254474104210">"新权限"</string>
-    <string name="allPerms" msgid="1024385515840703981">"全部"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"隐私相关权限"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"设备相关权限"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"新版本不需要任何新的权限。"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"拒绝"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"详情"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"仍然拒绝"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"第 <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> 项权限(共 <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> 项)"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"要允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;<xliff:g id="ACTION">%2$s</xliff:g>吗?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"要一律允许&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;<xliff:g id="ACTION">%2$s</xliff:g>吗?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"仅限使用应用时"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"一律允许"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"拒绝,不要再询问"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> 项已停用"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"全部已停用"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"均未停用"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"允许"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"应用"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"应用权限"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"不再询问"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"没有权限"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"其他权限"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"打开应用信息"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">另外 <xliff:g id="COUNT_1">%1$d</xliff:g> 项</item>
-      <item quantity="one">另外 <xliff:g id="COUNT_0">%1$d</xliff:g> 项</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"此应用专为旧版 Android 打造。拒绝权限可能会导致其无法正常运行。"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"执行未知操作"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"已授权 <xliff:g id="COUNT_0">%1$d</xliff:g> 个应用(共 <xliff:g id="COUNT_1">%2$d</xliff:g> 个)"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"显示系统应用"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"隐藏系统应用"</string>
-    <string name="no_apps" msgid="1965493419005012569">"没有应用"</string>
-    <string name="location_settings" msgid="1774875730854491297">"位置信息设置"</string>
-    <string name="location_warning" msgid="8778701356292735971">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”是此设备的一个位置信息服务提供程序。您可以在位置信息设置中修改位置信息使用权。"</string>
-    <string name="system_warning" msgid="7103819124542305179">"如果您拒绝此权限,您设备的基本功能可能会无法正常使用。"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"依据政策强制执行"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"已根据政策停用后台访问权限"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"已根据政策启用后台访问权限"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"已根据政策启用前台访问权限"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"由管理员控制"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"一律允许"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"仅限使用应用时"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"永不"</string>
-    <string name="loading" msgid="7811651799620593731">"正在加载…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"所有权限"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"其他应用功能"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"权限请求"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"检测到屏幕叠加层"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"要更改此权限设置,您必须首先在“设置”&gt;“应用”中关闭屏幕叠加层"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"打开设置"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear 不支持安装/卸载操作。"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"请选择要向&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;授予哪些权限"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt;已更新。请选择要向此应用授予哪些权限。"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"取消"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"继续"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"新权限"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"当前权限"</string>
-    <string name="message_staging" msgid="6151794817691100003">"正在准备安装应用…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"未知"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"出于安全考虑,已禁止您的平板电脑安装来自此来源的未知应用。"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"出于安全考虑,已禁止您的电视安装来自此来源的未知应用。"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"出于安全考虑,已禁止您的手机安装来自此来源的未知应用。"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"来历不明的应用很可能会损害您的手机和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何手机损坏或数据丢失情况,您负有全部责任。"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"来历不明的应用很可能会损害您的平板电脑和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何平板电脑损坏或数据丢失情况,您负有全部责任。"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"来历不明的应用很可能会损害您的电视和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何电视损坏或数据丢失情况,您负有全部责任。"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"继续"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"设置"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"正在安装/卸载 Android Wear 应用"</string>
+    <string name="app_name" msgid="7488448184431507488">"软件包安装程序"</string>
+    <string name="install" msgid="711829760615509273">"安装"</string>
+    <string name="done" msgid="6632441120016885253">"完成"</string>
+    <string name="cancel" msgid="1018267193425558088">"取消"</string>
+    <string name="installing" msgid="4921993079741206516">"正在安装…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"正在安装<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"已安装应用。"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"要安装此应用吗?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"要为此应用安装更新吗?您现有的数据将不会丢失。"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"要为此内置应用安装更新吗?您现有的数据将不会丢失。"</string>
+    <string name="install_failed" msgid="5777824004474125469">"未安装应用。"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"系统已禁止安装该软件包。"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"应用未安装:软件包与现有软件包存在冲突。"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"应用未安装:应用与您的平板电脑不兼容。"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"此应用与您的电视不兼容。"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"应用未安装:应用与您的手机不兼容。"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"应用未安装:软件包似乎无效。"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"无法在您的平板电脑上安装<xliff:g id="APP_NAME">%1$s</xliff:g>。"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"该用户无法安装未知应用"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"此用户无权安装应用"</string>
+    <string name="ok" msgid="7871959885003339302">"确定"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"管理应用"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"空间不足"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"无法安装<xliff:g id="APP_NAME">%1$s</xliff:g>。请释放一些存储空间并重试。"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"未找到应用"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"在已安装应用列表中找不到该应用。"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"不允许"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"当前用户无权执行这项卸载操作。"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"错误"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"无法卸载应用。"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"卸载应用"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"卸载更新"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>属于以下应用:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"要卸载此应用吗?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"要为"<b>"所有"</b>"用户卸载此应用吗?系统将为设备上的"<b>"所有"</b>"用户移除此应用及其数据。"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"要为用户<xliff:g id="USERNAME">%1$s</xliff:g>卸载此应用吗?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"要将此应用替换为出厂版本吗?这样会移除所有数据。"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"要将此应用替换为出厂版本吗?这样会移除所有数据,并会影响此设备的所有用户(包括已设置工作资料的用户)。"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"正在进行卸载操作"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"卸载操作失败"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"正在卸载…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"正在卸载<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"卸载完成。"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear 不支持安装/卸载操作。"</string>
+    <string name="message_staging" msgid="8032722385658438567">"正在准备安装应用…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"未知"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"出于安全考虑,已禁止您的平板电脑安装来自此来源的未知应用。"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"出于安全考虑,已禁止您的电视安装来自此来源的未知应用。"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"出于安全考虑,已禁止您的手机安装来自此来源的未知应用。"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"来历不明的应用很可能会损害您的手机和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何手机损坏或数据丢失情况,您负有全部责任。"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"来历不明的应用很可能会损害您的平板电脑和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何平板电脑损坏或数据丢失情况,您负有全部责任。"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"来历不明的应用很可能会损害您的电视和个人数据。安装该应用即表示,您同意对于因使用该应用可能导致的任何电视损坏或数据丢失情况,您负有全部责任。"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"继续"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"设置"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"正在安装/卸载 Wear 应用"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-zh-rHK/strings.xml b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
index 0401eb1..bb3605f 100644
--- a/packages/PackageInstaller/res/values-zh-rHK/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rHK/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"程式安裝器"</string>
-    <string name="next" msgid="3057143178373252333">"下一步"</string>
-    <string name="install" msgid="5896438203900042068">"安裝"</string>
-    <string name="done" msgid="3889387558374211719">"完成"</string>
-    <string name="cancel" msgid="8360346460165114585">"取消"</string>
-    <string name="installing" msgid="8613631001631998372">"正在安裝..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"正在安裝 <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"已安裝應用程式。"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"您要安裝這個應用程式嗎?應用程式將取得以下存取權:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"您要安裝這個應用程式嗎?應用程式不需任何特殊存取權。"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"您要為這個現有的應用程式安裝更新嗎?您的現有資料將會喪失,更新後的應用程式將取得以下存取權:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"您要為這個內置的應用程式安裝更新嗎?您的現有資料將會喪失,更新後的應用程式將取得以下存取權:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"您要為這個現有的應用程式安裝更新嗎?您不會遺失現有的資料,而應用程式無需任何特殊的存取權限。"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"您要為這個內置應用程式安裝更新嗎?您不會遺失現有的資料,而應用程式無需任何特殊的存取權限。"</string>
-    <string name="install_failed" msgid="6579998651498970899">"未安裝應用程式。"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"套件已遭封鎖,無法安裝。"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"套件與現有的套件發生衝突,無法安裝應用程式。"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"應用程式與平板電腦不兼容,無法安裝應用程式。"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"此應用程式與您的電視不相容。"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"應用程式與手機不兼容,無法安裝應用程式。"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"套件好像無效,無法安裝應用程式。"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"無法在您的平板電腦上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"無法在您的電視上安裝 <xliff:g id="APP_NAME">%1$s</xliff:g>。"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"無法在您的手機上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="launch" msgid="4826921505917605463">"開啟"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"您的管理員不允許安裝來自不明來源的應用程式"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"此使用者無法安裝不明的應用程式"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"此使用者無法安裝應用程式"</string>
-    <string name="ok" msgid="3468756155452870475">"確定"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"管理應用程式"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"空間不足"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"無法解除安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。請先騰出一些空間,然後再試一次。"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"找不到應用程式"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"在已安裝的應用程式清單中找不到這個應用程式。"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"不允許"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"目前的使用者不允許執行這項解除安裝操作。"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"錯誤"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"應用程式無法解除安裝。"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"解除安裝應用程式"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"解除安裝更新"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"「<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>」隸屬於以下應用程式:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"您要解除安裝這個應用程式嗎?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"您要為"<b>"所有"</b>"使用者解除安裝這個應用程式嗎?應用程式及其資料會從裝置上的"<b>"所有"</b>"使用者設定檔中移除。"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"您要為使用者 <xliff:g id="USERNAME">%1$s</xliff:g> 解除安裝這個應用程式嗎?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"要將此應用程式回復至原廠版本嗎?所有資料將會刪除。"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"要將此應用程式回復至原廠版本嗎?所有資料將會刪除,此裝置的所有使用者 (包括使用工作設定檔的使用者) 亦會受影響。"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"正在執行的解除安裝操作"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"失敗的解除安裝操作"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"正在解除安裝..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"完成解除安裝。"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"已解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"解除安裝失敗。"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」失敗。"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"無法解除安裝可用的裝置管理員應用程式"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"無法為<xliff:g id="USERNAME">%1$s</xliff:g>解除安裝可用的裝置管理員應用程式"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"這是部分使用者或設定檔所需的應用程式,其他使用者或設定檔已解除安裝此應用程式"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"這是您設定檔所需的應用程式,因此無法解除安裝。"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"這是您的裝置管理員要求安裝的應用程式,因此無法解除安裝。"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"管理裝置管理員應用程式"</string>
-    <string name="manage_users" msgid="3125018886835668847">"管理使用者"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"無法解除安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"剖析套件時發生問題。"</string>
-    <string name="newPerms" msgid="6039428254474104210">"新增"</string>
-    <string name="allPerms" msgid="1024385515840703981">"全部"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"私隱權"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"裝置存取權"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"這項更新不需新權限。"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"拒絕"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"更多資訊"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"一律拒絕"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"第 <xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> 個 (共 <xliff:g id="PERMISSION_COUNT">%2$s</xliff:g> 個)"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<xliff:g id="ACTION">%2$s</xliff:g>嗎?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"要一律允許「<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;b&gt;&lt;/b&gt;」<xliff:g id="ACTION">%2$s</xliff:g>嗎?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"只在使用應用程式時"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"一律"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"拒絕,不要再詢問"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> 個權限已停用"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"所有權限已停用"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"沒有權限已停用"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"允許"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"應用程式"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"應用程式權限"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"不要再問我"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"沒有權限"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"其他權限"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"打開應用程式資料"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">還有 <xliff:g id="COUNT_1">%1$d</xliff:g> 個</item>
-      <item quantity="one">還有 <xliff:g id="COUNT_0">%1$d</xliff:g> 個</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"這個應用程式專為舊版本的 Android 設計。拒絕權限可能會導致它無法如預期 運作。"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"執行不明的操作"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"已允許 <xliff:g id="COUNT_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="COUNT_1">%2$d</xliff:g> 個)"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"顯示系統"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"隱藏系統"</string>
-    <string name="no_apps" msgid="1965493419005012569">"沒有應用程式"</string>
-    <string name="location_settings" msgid="1774875730854491297">"位置設定"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g>為此裝置提供位置資訊服務。您可以在位置設定中更改位置存取權。"</string>
-    <string name="system_warning" msgid="7103819124542305179">"如果您拒絕這個權限,您的裝置的基本功能可能無法正常運作。"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"由政策強制執行"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"已根據政策停用背景存取權"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"已根據政策啟用背景存取權"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"已根據政策啟用前景存取權"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"由管理員控制"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"一律"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"只在使用應用程式時"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"永不"</string>
-    <string name="loading" msgid="7811651799620593731">"正在載入…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"所有權限"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"其他應用程式功能"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"權限要求"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"已偵測到螢幕重疊功能"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"如要變更此權限設定,請先前往 [設定] &gt; [應用程式],以關閉螢幕重疊功能"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"開啟設定"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear 不支援安裝/解除安裝操作。"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"選擇允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」存取的內容"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"已更新「<xliff:g id="APP_NAME">%1$s</xliff:g>」。選擇允許此應用程式存取的內容。"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"取消"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"繼續"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"新權限"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"目前權限"</string>
-    <string name="message_staging" msgid="6151794817691100003">"正在準備安裝應用程式…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"不明"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"為安全起見,您的平板電腦不得安裝此來源的不明應用程式。"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"為安全起見,您的電視不得安裝此來源的不明應用程式。"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"為安全起見,您的手機不得安裝此來源的不明應用程式。"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"來源不明的應用程式可能會侵害您的手機和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致手機損壞或資料遺失的責任。"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"來源不明的應用程式可能會侵害您的平板電腦和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致平板電腦損壞或資料遺失的責任。"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"來源不明的應用程式可能會侵害您的電視和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致電視損壞或資料遺失的責任。"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"繼續"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"設定"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"正在安裝/解除安裝 Wear 應用程式"</string>
+    <string name="app_name" msgid="7488448184431507488">"套件安裝程式"</string>
+    <string name="install" msgid="711829760615509273">"安裝"</string>
+    <string name="done" msgid="6632441120016885253">"完成"</string>
+    <string name="cancel" msgid="1018267193425558088">"取消"</string>
+    <string name="installing" msgid="4921993079741206516">"正在安裝…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"正在安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
+    <string name="install_done" msgid="5987363587661783896">"已安裝應用程式。"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"要安裝此應用程式嗎?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"您要為這個現有的應用程式安裝更新嗎?您不會遺失現有的資料。"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"您要為這個內置的應用程式安裝更新嗎?您不會遺失現有的資料。"</string>
+    <string name="install_failed" msgid="5777824004474125469">"未安裝應用程式。"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"套件已遭封鎖,無法安裝。"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"套件與現有的套件發生衝突,無法安裝應用程式。"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"應用程式與平板電腦不兼容,無法安裝應用程式。"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"此應用程式與電視不兼容。"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"應用程式與手機不兼容,無法安裝應用程式。"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"套件似乎無效,無法安裝應用程式。"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"無法在您的平板電腦上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"此使用者無法安裝來源不明的應用程式"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"此使用者無法安裝應用程式"</string>
+    <string name="ok" msgid="7871959885003339302">"確定"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"管理應用程式"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"儲存空間不足"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"無法安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。請先騰出一些儲存空間,然後再試一次。"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"找不到應用程式"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"在已安裝應用程式的清單中找不到這個應用程式。"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"不允許"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"目前的使用者不允許執行這項解除安裝操作。"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"錯誤"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"應用程式無法解除安裝。"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"解除安裝應用程式"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"解除安裝更新"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"「<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>」屬於以下應用程式:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"您要解除安裝此應用程式嗎?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"您要為"<b>"所有"</b>"使用者解除安裝這個應用程式嗎?應用程式及其資料會從裝置上的"<b>"所有"</b>"使用者設定檔中移除。"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"您要為使用者<xliff:g id="USERNAME">%1$s</xliff:g>解除安裝此應用程式嗎?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"要將此應用程式回復至原廠版本嗎?系統會移除所有資料。"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"要將此應用程式回復至原廠版本嗎?系統會移除所有資料。此裝置的所有使用者 (包括使用工作設定檔的使用者) 亦會受影響。"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"正在執行的解除安裝操作"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"失敗的解除安裝操作"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"正在解除安裝…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"完成解除安裝。"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear 不支援安裝/解除安裝操作。"</string>
+    <string name="message_staging" msgid="8032722385658438567">"正在準備安裝應用程式…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"不明"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"為安全起見,您的平板電腦不得安裝此來源的不明應用程式。"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"為安全起見,您的電視不得安裝此來源的不明應用程式。"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"為安全起見,您的手機不得安裝此來源的不明應用程式。"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"來源不明的應用程式可能會侵害您的手機和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致手機損壞或資料遺失的責任。"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"來源不明的應用程式可能會侵害您的平板電腦和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致平板電腦損壞或資料遺失的責任。"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"來源不明的應用程式可能會侵害您的電視和個人資料。安裝此應用程式,即表示您同意承擔因使用這個應用程式而導致電視損壞或資料遺失的責任。"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"繼續"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"設定"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"正在安裝/解除安裝 Wear 應用程式"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-zh-rTW/strings.xml b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
index db96924..513b16a 100644
--- a/packages/PackageInstaller/res/values-zh-rTW/strings.xml
+++ b/packages/PackageInstaller/res/values-zh-rTW/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"程式安裝器"</string>
-    <string name="next" msgid="3057143178373252333">"下一步"</string>
-    <string name="install" msgid="5896438203900042068">"安裝"</string>
-    <string name="done" msgid="3889387558374211719">"完成"</string>
-    <string name="cancel" msgid="8360346460165114585">"取消"</string>
-    <string name="installing" msgid="8613631001631998372">"安裝中…"</string>
-    <string name="installing_app" msgid="4097935682329028894">"正在安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
-    <string name="install_done" msgid="3682715442154357097">"已安裝應用程式。"</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"你要安裝這個應用程式嗎?應用程式將取得以下權限:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"你要安裝這個應用程式嗎?應用程式不需任何特殊權限。"</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"你要為這個現有的應用程式安裝更新嗎?你的現有資料不會遺失,而更新後的應用程式將取得以下權限:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"你要為這個內建的應用程式安裝更新嗎?你的現有資料不會遺失,而更新後的應用程式將取得以下權限:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"你要為這個現有的應用程式安裝更新嗎?你不會遺失現有的資料,且應用程式不需任何特殊權限。"</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"你要為這個現有的內建應用程式安裝更新嗎?你不會遺失現有的資料,且應用程式不需任何特殊權限。"</string>
-    <string name="install_failed" msgid="6579998651498970899">"未安裝應用程式。"</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"這個套件已遭到封鎖,因此無法安裝。"</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"應用程式套件與現有套件衝突,因此未能完成安裝。"</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"應用程式與你的平板電腦不相容,因此未能完成安裝。"</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"這個應用程式與你的電視不相容。"</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"應用程式與你的手機不相容,因此未能完成安裝。"</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"應用程式套件無效,因此未能完成安裝。"</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"無法在你的平板電腦上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"無法在你的電視上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"無法在你的手機上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="launch" msgid="4826921505917605463">"開啟"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"你的管理員不允許安裝來源不明的應用程式"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"這位使用者無法安裝不明的應用程式"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"這位使用者無法安裝應用程式"</string>
-    <string name="ok" msgid="3468756155452870475">"確定"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"管理應用程式"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"空間不足"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"無法安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。請先釋出部分空間,然後再試一次。"</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"找不到應用程式"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"在已安裝的應用程式清單中找不到這個應用程式。"</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"不允許此操作"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"目前的使用者無法執行這項解除安裝作業。"</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"發生錯誤"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"無法解除安裝應用程式。"</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"解除安裝應用程式"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"解除安裝更新"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"「<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>」屬於下列應用程式:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"你要解除安裝這個應用程式嗎?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"你要為"<b>"所有"</b>"使用者解除安裝這個應用程式嗎?該應用程式及其資料會從裝置上的"<b>"所有"</b>"使用者設定檔移除。"</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"你要為使用者 <xliff:g id="USERNAME">%1$s</xliff:g> 解除安裝這個應用程式嗎?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"要將應用程式換成原廠版本嗎?這麼做會移除所有資料。"</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"要將應用程式換成原廠版本嗎?這麼做會移除所有資料。凡是這個裝置的使用者 (包括設置工作資料夾的使用者),皆會受到影響。"</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"執行中的解除安裝作業"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"失敗的解除安裝作業"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"解除安裝中…"</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"解除安裝完成。"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"已解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"解除安裝失敗。"</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"無法解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」。"</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"無法解除安裝使用中的裝置管理員應用程式"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"無法為<xliff:g id="USERNAME">%1$s</xliff:g>解除安裝使用中的裝置管理員應用程式"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"部分使用者或設定檔需要使用這個應用程式;已為其他使用者解除安裝"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"你的設定檔需要使用這個應用程式,因此無法解除安裝。"</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"這是你的裝置管理員要求安裝的應用程式,因此無法解除安裝。"</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"管理裝置管理員應用程式"</string>
-    <string name="manage_users" msgid="3125018886835668847">"管理使用者"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"無法解除安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"剖析套件時發生問題。"</string>
-    <string name="newPerms" msgid="6039428254474104210">"新增"</string>
-    <string name="allPerms" msgid="1024385515840703981">"全部"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"隱私權"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"裝置存取權"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"這項更新不需新權限。"</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"拒絕"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"瞭解詳情"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"直接拒絕"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g>/<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<xliff:g id="ACTION">%2$s</xliff:g>嗎?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"要一律允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<xliff:g id="ACTION">%2$s</xliff:g>嗎?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"僅限使用應用程式時"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"一律允許"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"拒絕且不要再詢問"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"已停用 <xliff:g id="COUNT">%1$d</xliff:g> 項權限"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"已停用所有權限"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"未停用任何權限"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"允許"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"應用程式"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"應用程式權限"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"不要再詢問"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"沒有權限"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"其他權限"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"開啟應用程式資訊"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="other">還有 <xliff:g id="COUNT_1">%1$d</xliff:g> 項</item>
-      <item quantity="one">還有 <xliff:g id="COUNT_0">%1$d</xliff:g> 項</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"這個應用程式是為舊版 Android 所開發。拒絕授予權限可能導致應用程式無法正常運作。"</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"執行不明的動作"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"已授權 <xliff:g id="COUNT_0">%1$d</xliff:g> 個應用程式 (共 <xliff:g id="COUNT_1">%2$d</xliff:g> 個)"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"顯示系統"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"隱藏系統"</string>
-    <string name="no_apps" msgid="1965493419005012569">"沒有應用程式"</string>
-    <string name="location_settings" msgid="1774875730854491297">"位置資訊設定"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> 是這台裝置的定位服務供應商。你可以在位置資訊設定中修改位置資訊存取權。"</string>
-    <string name="system_warning" msgid="7103819124542305179">"如果你拒絕這項權限,裝置的基本功能可能無法正常運作。"</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"依據政策規定執行"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"已根據政策停用背景存取權"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"已根據政策啟用背景存取權"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"已根據政策啟用前景存取權"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"由管理員控管"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"一律允許"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"僅限使用應用程式時"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"永不"</string>
-    <string name="loading" msgid="7811651799620593731">"載入中…"</string>
-    <string name="all_permissions" msgid="5156669007784613042">"所有權限"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"其他應用程式功能"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"權限要求"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"偵測到畫面重疊圖層"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"如要變更這項權限設定,你必須先依序前往 [設定] &gt; [應用程式],關閉裝置畫面重疊圖層"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"開啟設定"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Wear 不支援安裝及解除安裝操作。"</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"選擇要將哪些存取權限授予「<xliff:g id="APP_NAME">%1$s</xliff:g>」"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已更新。請選擇要將哪些存取權限授予這個應用程式。"</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"取消"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"繼續"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"新權限"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"目前權限"</string>
-    <string name="message_staging" msgid="6151794817691100003">"正在啟動應用程式安裝程序…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"不明"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"為了安全起見,你的平板電腦禁止安裝這個來源提供的不明應用程式。"</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"為了安全起見,你的電視禁止安裝這個來源提供的不明應用程式。"</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"為了安全起見,你的手機禁止安裝這個來源提供的不明應用程式。"</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"來歷不明的應用程式可能會損害你的手機和個人資料。如因安裝及使用這個應用程式,導致你的手機受損或資料遺失,請自行負責。"</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"來歷不明的應用程式可能會損害你的平板電腦和個人資料。如因安裝及使用這個應用程式,導致你的平板電腦受損或資料遺失,請自行負責。"</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"來歷不明的應用程式可能會損害你的電視和個人資料。如因安裝及使用這個應用程式,導致你的電視受損或資料遺失,請自行負責。"</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"繼續"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"設定"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"安裝/解除安裝 Wear 應用程式"</string>
+    <string name="app_name" msgid="7488448184431507488">"套件安裝程式"</string>
+    <string name="install" msgid="711829760615509273">"安裝"</string>
+    <string name="done" msgid="6632441120016885253">"完成"</string>
+    <string name="cancel" msgid="1018267193425558088">"取消"</string>
+    <string name="installing" msgid="4921993079741206516">"安裝中…"</string>
+    <string name="installing_app" msgid="1165095864863849422">"正在安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
+    <string name="install_done" msgid="5987363587661783896">"已安裝應用程式。"</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"要安裝這個應用程式嗎?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"要為這個現有的應用程式安裝更新嗎?你不會遺失現有的資料。"</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"要為這個內建的應用程式安裝更新嗎?你不會遺失現有的資料。"</string>
+    <string name="install_failed" msgid="5777824004474125469">"未安裝應用程式。"</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"系統已封鎖這個套件,因此無法安裝。"</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"應用程式套件與現有套件衝突,因此未能完成安裝。"</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"應用程式與你的平板電腦不相容,因此未能完成安裝。"</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"這個應用程式與您的電視不相容。"</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"應用程式與你的手機不相容,因此未能完成安裝。"</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"應用程式套件無效,因此未能完成安裝。"</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"無法在你的平板電腦上安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。"</string>
+    <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_user_restriction_dlg_text" msgid="151020786933988344">"這位使用者無法安裝不明的應用程式"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"這位使用者無法安裝應用程式"</string>
+    <string name="ok" msgid="7871959885003339302">"確定"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"管理應用程式"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"空間不足"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"無法安裝「<xliff:g id="APP_NAME">%1$s</xliff:g>」。請先釋出部分空間,然後再試一次。"</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"找不到應用程式"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"在已安裝應用程式的清單中找不到這個應用程式。"</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"不允許此操作"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"目前的使用者無法執行這項解除安裝作業。"</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"錯誤"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"無法解除安裝應用程式。"</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"解除安裝應用程式"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"解除安裝更新"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"「<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g>」屬於下列應用程式:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"要解除安裝這個應用程式嗎?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"要為"<b>"所有"</b>"使用者解除安裝這個應用程式嗎?該應用程式及其資料會從裝置上的"<b>"所有"</b>"使用者設定檔移除。"</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"要為使用者 <xliff:g id="USERNAME">%1$s</xliff:g> 解除安裝這個應用程式嗎?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"要將應用程式換成原廠版本嗎?這麼做會移除所有資料。"</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"要將應用程式換成原廠版本嗎?這麼做會移除所有資料。凡是這個裝置的使用者 (包括設置工作資料夾的使用者),皆會受到影響。"</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"執行中的解除安裝作業"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"失敗的解除安裝作業"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"解除安裝中…"</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"正在解除安裝「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"已順利解除安裝。"</string>
+    <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_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_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>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Wear 不支援安裝及解除安裝操作。"</string>
+    <string name="message_staging" msgid="8032722385658438567">"正在準備應用程式安裝程序…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"不明"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"為了安全起見,你的平板電腦禁止安裝這個來源提供的不明應用程式。"</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"為了安全起見,你的電視禁止安裝這個來源提供的不明應用程式。"</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"為了安全起見,你的手機禁止安裝這個來源提供的不明應用程式。"</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"來歷不明的應用程式可能會損害你的手機和個人資料。如因安裝及使用這個應用程式,導致你的手機受損或資料遺失,請自行負責。"</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"來歷不明的應用程式可能會損害你的平板電腦和個人資料。如因安裝及使用這個應用程式,導致你的平板電腦受損或資料遺失,請自行負責。"</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"來歷不明的應用程式可能會損害你的電視和個人資料。如因安裝及使用這個應用程式,導致你的電視受損或資料遺失,請自行負責。"</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"繼續"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"設定"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"安裝/解除安裝中的 Wear 應用程式"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values-zu/strings.xml b/packages/PackageInstaller/res/values-zu/strings.xml
index 6ece479..bc91ed1 100644
--- a/packages/PackageInstaller/res/values-zu/strings.xml
+++ b/packages/PackageInstaller/res/values-zu/strings.xml
@@ -16,141 +16,76 @@
 
 <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="2738748390251381682">"Isifaki sephakheji"</string>
-    <string name="next" msgid="3057143178373252333">"Okulandelayo"</string>
-    <string name="install" msgid="5896438203900042068">"Faka"</string>
-    <string name="done" msgid="3889387558374211719">"Kwenziwe"</string>
-    <string name="cancel" msgid="8360346460165114585">"Khansela"</string>
-    <string name="installing" msgid="8613631001631998372">"Iyafaka..."</string>
-    <string name="installing_app" msgid="4097935682329028894">"Ifaka i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="install_done" msgid="3682715442154357097">"I-App ifakiwe."</string>
-    <string name="install_confirm_question" msgid="7295206719219043890">"Ngabe ufuna ukufaka lolu hlelo lokusebenza? Lizothola ukufinyelela ku:"</string>
-    <string name="install_confirm_question_no_perms" msgid="5918305641302873520">"Ngabe ufuna ukufaka lolu hlelo lokusebenza? Alidingi ukufinyelela okukhethekile."</string>
-    <string name="install_confirm_question_update" msgid="4624159567361487964">"Ngabe ufuna ukufaka isibuyekezo ohlelweni lokusebenza olukhona? Idatha yakho ekhona izolahleka. Uhlelo lokusebenza olubuyekeziwe lizothola ukufinyelela ku:"</string>
-    <string name="install_confirm_question_update_system" msgid="1302330093676416336">"Ngabe ufuna ukufaka isibuyekezo kulolu hlelo lokusebenza olakhelwe phakathi? Idatha yakho ekhona izolahleka. Uhlelo lokusebenza olubuyekeziwe luzothola ukufinyelela ku:"</string>
-    <string name="install_confirm_question_update_no_perms" msgid="4885928136844618944">"Ingabe ufuna ukufaka isibuyekezo kulolu hlelo lokusebenza olukhona? Idatha yakho ekhona ngeke ilahleke. Akudingi ukufinyelela okukhethekile."</string>
-    <string name="install_confirm_question_update_system_no_perms" msgid="7676593512694724374">"Ungabe ufuna ukukhipha isibuyekezo kulolu hlelo lokusebenza olakhelwe ngaphakathi? Idatha yakho ekhona ngeke ilahleke. Akudingi ukufinyelela okukhethekile."</string>
-    <string name="install_failed" msgid="6579998651498970899">"I-app ayifakiwe."</string>
-    <string name="install_failed_blocked" msgid="1606870930588770025">"Iphakheji livinjiwe kusukela ekufakweni."</string>
-    <string name="install_failed_conflict" msgid="5336045235168070954">"Uhlelo lokusebenza alufakiwe njengoba ukuphakheja kushayisana nephakheji elikhona."</string>
-    <string name="install_failed_incompatible" product="tablet" msgid="6682387386242708974">"Uhlelo lokusebenza alufakiwe njengoba uhlelo lokusebenza lungahambisani nethebulethi yakho."</string>
-    <string name="install_failed_incompatible" product="tv" msgid="3553367270510072729">"Lolu hlelo lokusebenza aluhambisani ne-TV yakho."</string>
-    <string name="install_failed_incompatible" product="default" msgid="7917996365659426872">"Uhlelo lokusebenza alufakiwe njengoba uhlelo lokusebenza lungahambisani nefoni yakho."</string>
-    <string name="install_failed_invalid_apk" msgid="269885385245534742">"Uhlelo lokusebenza alufakiwe njengoba iphakheji ibonakala ingavumelekile."</string>
-    <string name="install_failed_msg" product="tablet" msgid="8368835262605608787">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa kuthebhulethi."</string>
-    <string name="install_failed_msg" product="tv" msgid="3990457938384021566">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa ku-TV yakho."</string>
-    <string name="install_failed_msg" product="default" msgid="8554909560982962052">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa efonini."</string>
-    <string name="launch" msgid="4826921505917605463">"Vula"</string>
-    <string name="unknown_apps_admin_dlg_text" msgid="7488386758312008790">"Umlawuli wakho akavumeli ukufakwa kwezinhlelo zokusebenza ezitholwe kusukela kumithombo engaziwa"</string>
-    <string name="unknown_apps_user_restriction_dlg_text" msgid="5785226253054083336">"Izinhlelo zokusebenza ezingaziwa azikwazi ukufakwa ilo msebenzisi"</string>
-    <string name="install_apps_user_restriction_dlg_text" msgid="5041150186260066212">"Lo msebenzisi akavunyelwe ukufaka izinhlelo zokusebenza"</string>
-    <string name="ok" msgid="3468756155452870475">"KULUNGILE"</string>
-    <string name="manage_applications" msgid="4033876279091996596">"Phatha izinhlelo zokusebenza"</string>
-    <string name="out_of_space_dlg_title" msgid="7843674437613797326">"Iphelelwe yisikhala"</string>
-    <string name="out_of_space_dlg_text" msgid="4774775404294282216">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa. Khulula isikhala bese uzama futhi."</string>
-    <string name="app_not_found_dlg_title" msgid="2692335460569505484">"I-App ayitholakalanga"</string>
-    <string name="app_not_found_dlg_text" msgid="6107465056055095930">"Uhlelo lokusebenza alutholakalanga ohlwini lwezinhlelo zokusebenza ezifakiwe."</string>
-    <string name="user_is_not_allowed_dlg_title" msgid="118128026847201582">"Akuvumelekile"</string>
-    <string name="user_is_not_allowed_dlg_text" msgid="739716827677987545">"Umsebenzisi wamanje akavunyelwe ukwenza lokhu kukhipha."</string>
-    <string name="generic_error_dlg_title" msgid="2684806600635296961">"Iphutha"</string>
-    <string name="generic_error_dlg_text" msgid="4288738047825333954">"Amafu ohlelo lokusebenza angakhishwa."</string>
-    <string name="uninstall_application_title" msgid="1860074100811653963">"Khipha i-app"</string>
-    <string name="uninstall_update_title" msgid="4146940097553335390">"Khipha isibuyekezo"</string>
-    <string name="uninstall_activity_text" msgid="6680688689803932550">"I-<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ingxenye yohlelo lokusebenza olulandelayo:"</string>
-    <string name="uninstall_application_text" msgid="6691975835951187030">"Ufuna ukukhipha le-app?"</string>
-    <string name="uninstall_application_text_all_users" msgid="5574704453233525222">"Ingabe ufuna ukukhipha lolu hlelo lokusebenza kubo "<b>"bonke"</b>" abasebenzisi? Uhlelo lokusebenza nedatha yalo kuzosuswa kubo "<b>"bonke"</b>" abasebenzisi kudivayisi."</string>
-    <string name="uninstall_application_text_user" msgid="8766882355635485733">"Ingabe ufuna ukukhiphela lolu hlelo lokusebenza kumsebenzisi ongu-<xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
-    <string name="uninstall_update_text" msgid="1394549691152728409">"Shintshanisa lolu hlelo lokusebenza ngenguqulo yasekuqaleni? Yonke idatha izosuswa."</string>
-    <string name="uninstall_update_text_multiuser" msgid="2083665452990861991">"Shintshanisa lolu hlelo lokusebenza ngenguqulo yasekuqaleni? Yonke idatha izosuswa. Lokhu kuthinta bonke abasebenzisi bale divayisi, abafaka labo abanamaphrofayela wokusebenza."</string>
-    <string name="uninstalling_notification_channel" msgid="5698369661583525583">"Ukukhishwa okuqhubekayo"</string>
-    <string name="uninstall_failure_notification_channel" msgid="8224276726364132314">"Ukukhishwa okuhlulekile"</string>
-    <string name="uninstalling" msgid="5556217435895938250">"Iyakhipha..."</string>
-    <string name="uninstalling_app" msgid="2773617614877719294">"Ikhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
-    <string name="uninstall_done" msgid="3792487853420281888">"Ukukhipha kuqedile"</string>
-    <string name="uninstall_done_app" msgid="775837862728680479">"Kukhishwe i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
-    <string name="uninstall_failed" msgid="631122574306299512">"Ukukhipha akuphumelelanga."</string>
-    <string name="uninstall_failed_app" msgid="945277834056527022">"Ukukhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> akuphumelele."</string>
-    <string name="uninstall_failed_device_policy_manager" msgid="2727361164694743362">"Ayikwazi ukukhipha uhlelo lokusebenza lomlawuli ledivayisi esebenzayo"</string>
-    <string name="uninstall_failed_device_policy_manager_of_user" msgid="2161462242935805756">"Ayikwazi ukukhipha uhlelo lokusebenza lomlawuli ledivayisi esebenzayo lika-<xliff:g id="USERNAME">%1$s</xliff:g>"</string>
-    <string name="uninstall_all_blocked_profile_owner" msgid="3544933038594382346">"Lolu hlelo lokusebenza luyadingeka kwabanye abasebenzisi noma amaphrofayela futhi lukhishelwe abanye"</string>
-    <string name="uninstall_blocked_profile_owner" msgid="6912141045528994954">"Lolu hlelo lokusebenza ludingelwa iphrofayela yakho futhi alikwazi ukukhishwa."</string>
-    <string name="uninstall_blocked_device_owner" msgid="7074175526413453063">"Lolu hlelo lokusebenza ludingwa umlawuli wedivayisi yakho futhi alukwazi ukukhishwa."</string>
-    <string name="manage_device_administrators" msgid="118178632652346535">"Phatha izinhlelo zokusebenza zedivayisi yomlawuli"</string>
-    <string name="manage_users" msgid="3125018886835668847">"Phatha abasebenzisi"</string>
-    <string name="uninstall_failed_msg" msgid="8969754702803951175">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukukhishwa"</string>
-    <string name="Parse_error_dlg_text" msgid="7623286983621067011">"Kube nenkinga yokwehlukanisa iphakheji."</string>
-    <string name="newPerms" msgid="6039428254474104210">"Okusha"</string>
-    <string name="allPerms" msgid="1024385515840703981">"Konke"</string>
-    <string name="privacyPerms" msgid="1850527049572617">"Ubumfihlo"</string>
-    <string name="devicePerms" msgid="6733560207731294504">"Ukufinyelela kwedivayisi"</string>
-    <string name="no_new_perms" msgid="6657813692169565975">"Lesi sibuyekezo asidingi zimvume."</string>
-    <string name="grant_dialog_button_deny" msgid="2176510645406614340">"Phika"</string>
-    <string name="grant_dialog_button_more_info" msgid="2218220771432058426">"Olunye ulwazi"</string>
-    <string name="grant_dialog_button_deny_anyway" msgid="847960499284125250">"Yenqaba noma kunjalo"</string>
-    <string name="current_permission_template" msgid="6378304249516652817">"<xliff:g id="CURRENT_PERMISSION_INDEX">%1$s</xliff:g> kokungu-<xliff:g id="PERMISSION_COUNT">%2$s</xliff:g>"</string>
-    <string name="permission_warning_template" msgid="7332275268559121742">"Vumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukuthi <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="permission_add_background_warning_template" msgid="5391175001698541141">"Njalo vumela i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ukwenza <xliff:g id="ACTION">%2$s</xliff:g>?"</string>
-    <string name="allow_permission_foreground_only" msgid="1016389465002335286">"Kuphela ngenkathi usebenzisa uhlelo lokusebenza"</string>
-    <string name="allow_permission_always" msgid="7047379650123289823">"Njalo"</string>
-    <string name="deny_permission_deny_and_dont_ask_again" msgid="8003202275002645629">"Yenqaba futhi ungasabuzi"</string>
-    <string name="permission_revoked_count" msgid="7386129423432613024">"<xliff:g id="COUNT">%1$d</xliff:g> kukhutshaziwe"</string>
-    <string name="permission_revoked_all" msgid="8595742638132863678">"konke kukhutshaziwe"</string>
-    <string name="permission_revoked_none" msgid="2059511550181271342">"Lutho olukhutshaziwe"</string>
-    <string name="grant_dialog_button_allow" msgid="4616529495342337095">"Vumela"</string>
-    <string name="app_permissions_breadcrumb" msgid="3390836200791539264">"Izinhlelo zokusebenza"</string>
-    <string name="app_permissions" msgid="3146758905824597178">"Izimvume zohlelo lokusebenza"</string>
-    <string name="never_ask_again" msgid="1089938738199748687">"Ungaphindi ubuze"</string>
-    <string name="no_permissions" msgid="3210542466245591574">"Akukho zimvume"</string>
-    <string name="additional_permissions" msgid="6667573114240111763">"Izimvume ezingeziwe"</string>
-    <string name="app_permissions_info_button_label" msgid="7789812060395257748">"Vula ulwazi lohlelo lokusebenza"</string>
-    <plurals name="additional_permissions_more" formatted="false" msgid="945127158155064388">
-      <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> okuningi</item>
-      <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> okuningi</item>
-    </plurals>
-    <string name="old_sdk_deny_warning" msgid="3872277112584842615">"Lolu hlelo lokusebenza ludizayinelwe inguqulo endala ye-Android. Ukwala imvume kungalibangela ukuthi lingasasebenzi njengoba kuhlosiwe."</string>
-    <string name="default_permission_description" msgid="4992892207044156668">"Yenza isenzo esingaziwa"</string>
-    <string name="app_permissions_group_summary" msgid="4787239772223699263">"<xliff:g id="COUNT_0">%1$d</xliff:g> kuzinhlelo zokusebenza ezingu-<xliff:g id="COUNT_1">%2$d</xliff:g> ezivunyelwe"</string>
-    <string name="menu_show_system" msgid="6773743421743728921">"Bonisa isistimu"</string>
-    <string name="menu_hide_system" msgid="7595471742649432977">"Fihla isistimu"</string>
-    <string name="no_apps" msgid="1965493419005012569">"Azikho izinhlelo zokusebenza"</string>
-    <string name="location_settings" msgid="1774875730854491297">"Izilungiselelo Zendawo"</string>
-    <string name="location_warning" msgid="8778701356292735971">"<xliff:g id="APP_NAME">%1$s</xliff:g> ingumhlinzeki wamasevisi wendawo kule divayisi. Ukufinyelela kwendawo kungashintshwa kusuka kuzilungiselelo zendawo."</string>
-    <string name="system_warning" msgid="7103819124542305179">"Uma unqabela le mvume, izici eziyisisekelo zedivayisi yakho zingahle zingasasebenzi njengoba zihlosiwe."</string>
-    <string name="permission_summary_enforced_by_policy" msgid="3418617316188986205">"Isetshenziswe yinqubomgomo"</string>
-    <string name="permission_summary_disabled_by_policy_background_only" msgid="160007162349980265">"Ukufinyelela kwangemuva kukhutshazwe inqubomgomo"</string>
-    <string name="permission_summary_enabled_by_policy_background_only" msgid="4834971700297385342">"Ukufinyelela kwangemuva kunikwe amandla ngenqubomgomo"</string>
-    <string name="permission_summary_enabled_by_policy_foreground_only" msgid="5150061275247925588">"Ukufinyelela kwangaphambili kunikwe amandla ngenqubomgomo"</string>
-    <string name="permission_summary_enforced_by_admin" msgid="1702707982488952544">"Kulawulwa umqondisi"</string>
-    <!-- no translation found for background_access_chooser_dialog_choices:0 (7142769853837915143) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:1 (7804653189249679164) -->
-    <!-- no translation found for background_access_chooser_dialog_choices:2 (1131794379787779680) -->
-    <string name="permission_access_always" msgid="5642491469836594184">"Njalo"</string>
-    <string name="permission_access_only_foreground" msgid="6906814759741316041">"Kuphela ngenkathi usebenzisa uhlelo lokusebenza"</string>
-    <string name="permission_access_never" msgid="1258330706341318622">"Soze"</string>
-    <string name="loading" msgid="7811651799620593731">"Iyalayisha..."</string>
-    <string name="all_permissions" msgid="5156669007784613042">"Zonke izimvume"</string>
-    <string name="other_permissions" msgid="2016192512386091933">"Amanye amakhono wohlelo lokusebenza"</string>
-    <string name="permission_request_title" msgid="1204446718549121199">"Isicelo semvume"</string>
-    <string name="screen_overlay_title" msgid="3021729846864038529">"Kutholwe imbondela yesikrini"</string>
-    <string name="screen_overlay_message" msgid="2141944461571677331">"Ukuze uguqule lesi silungiselelo semvume, kuzomele uqale uvale imbondela yesikrini kusukela ku-Izilungiselelo &gt; Izinhlelo zokusebenza"</string>
-    <string name="screen_overlay_button" msgid="4344544843349937743">"Vula izilungiselelo"</string>
-    <string name="wear_not_allowed_dlg_title" msgid="8104666773577525713">"I-Android Wear"</string>
-    <string name="wear_not_allowed_dlg_text" msgid="1322352525843583064">"Izenzo zokufaka/ukukhipha azisekelwe ku-Wear."</string>
-    <string name="permission_review_title_template_install" msgid="6819338441305295479">"Khetha ukuthi uzovumela ini ukuthi i-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ifinyelele kuyo"</string>
-    <string name="permission_review_title_template_update" msgid="8632233603161669426">"I-&lt;b&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/b&gt; ibuyekeziwe. Khetha ukuthi uzovumela ini ukuthi ifinyelelwe ilolu hlelo lokusebenza."</string>
-    <string name="review_button_cancel" msgid="957906817733578877">"Khansela"</string>
-    <string name="review_button_continue" msgid="4809162078179371370">"Qhubeka"</string>
-    <string name="new_permissions_category" msgid="3213523410139204183">"Izimvume ezintsha"</string>
-    <string name="current_permissions_category" msgid="998210994450606094">"Izimvume zamanje"</string>
-    <string name="message_staging" msgid="6151794817691100003">"Ifaka kusiteji uhlelo lokusebenza…"</string>
-    <string name="app_name_unknown" msgid="8931522764510159105">"Akwaziwa"</string>
-    <string name="untrusted_external_source_warning" product="tablet" msgid="1483151219938173935">"Ukuze uvikelwe, ithebulethi yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza ezingaziwa kusukela kulo mthombo."</string>
-    <string name="untrusted_external_source_warning" product="tv" msgid="5373768281884328560">"Ukuze uvikelwe, i-TV yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza ezingaziwa kusukela kulo mthombo."</string>
-    <string name="untrusted_external_source_warning" product="default" msgid="2223486836232706553">"Ukuze uvikelwe, ifoni yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza kusukela kulo mthombo."</string>
-    <string name="anonymous_source_warning" product="default" msgid="7700263729981815614">"Idatha yakho yefoni neyohlelo lwakho lokusebenza isengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala kufoni yakho noma ukulahlekelwa kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
-    <string name="anonymous_source_warning" product="tablet" msgid="8854462805499848630">"Ithebulethi yakho nedatha yomuntu siqu zisengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala kuthebulethi yakho noma ukulahleka kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
-    <string name="anonymous_source_warning" product="tv" msgid="1291472686734385872">"Idatha yakho ye-TV neyomuntu siqu isengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala ku-TV yakho noma ukulahlekelwa kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
-    <string name="anonymous_source_continue" msgid="2094381167954332292">"Qhubeka"</string>
-    <string name="external_sources_settings" msgid="8601453744517291632">"Izilungiselelo"</string>
-    <string name="wear_app_channel" msgid="6200840123672949356">"Ifaka/ikhipha izinhlelo zokusebenza ze-wear"</string>
+    <string name="app_name" msgid="7488448184431507488">"Isifaki sephakheji"</string>
+    <string name="install" msgid="711829760615509273">"Faka"</string>
+    <string name="done" msgid="6632441120016885253">"Kwenziwe"</string>
+    <string name="cancel" msgid="1018267193425558088">"Khansela"</string>
+    <string name="installing" msgid="4921993079741206516">"Iyafaka..."</string>
+    <string name="installing_app" msgid="1165095864863849422">"Ifaka i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="install_done" msgid="5987363587661783896">"Uhlelo lokusebenza olufakiwe."</string>
+    <string name="install_confirm_question" msgid="8176284075816604590">"Ingabe ufuna ukufaka lolu hlelo lokusebenza?"</string>
+    <string name="install_confirm_question_update" msgid="7942235418781274635">"Ingabe ufuna ukufaka lesi sibuyekezo kulolu hlelo lokusebenza olukhona? Idatha yakho ekhona ngeke ize ilahleke."</string>
+    <string name="install_confirm_question_update_system" msgid="4713001702777910263">"Uyafuna ukufaka isibuyekezo kulolu hlelo lokusebenza olwakhelwe ngaphakathi? Idatha yakho ekhona ngeke ize ilahleke."</string>
+    <string name="install_failed" msgid="5777824004474125469">"Uhlelo lokusebenza alufakiwe."</string>
+    <string name="install_failed_blocked" msgid="8512284352994752094">"Iphakheji livinjiwe kusukela ekufakweni."</string>
+    <string name="install_failed_conflict" msgid="3493184212162521426">"Uhlelo lokusebenza alufakiwe njengoba ukuphakheja kushayisana nephakheji elikhona."</string>
+    <string name="install_failed_incompatible" product="tablet" msgid="6019021440094927928">"Uhlelo lokusebenza alufakiwe njengoba uhlelo lokusebenza lungahambisani nethebulethi yakho."</string>
+    <string name="install_failed_incompatible" product="tv" msgid="2890001324362291683">"Lolu hlelo lokusebenza aluhambisani ne-TV yakho."</string>
+    <string name="install_failed_incompatible" product="default" msgid="7254630419511645826">"Uhlelo lokusebenza alufakiwe njengoba uhlelo lokusebenza lungahambisani nefoni yakho."</string>
+    <string name="install_failed_invalid_apk" msgid="8581007676422623930">"Uhlelo lokusebenza alufakiwe njengoba iphakheji ibonakala ingavumelekile."</string>
+    <string name="install_failed_msg" product="tablet" msgid="6298387264270562442">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa kuthebulethi yakho."</string>
+    <string name="install_failed_msg" product="tv" msgid="1920009940048975221">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa ku-TV yakho."</string>
+    <string name="install_failed_msg" product="default" msgid="6484461562647915707">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa efonini."</string>
+    <string name="launch" msgid="3952550563999890101">"Vula"</string>
+    <string name="unknown_apps_admin_dlg_text" msgid="4456572224020176095">"Umlawuli wakho akavumeli ukufakwa kwezinhlelo zokusebenza ezitholwe kusukela kumithombo engaziwa"</string>
+    <string name="unknown_apps_user_restriction_dlg_text" msgid="151020786933988344">"Izinhlelo zokusebenza ezingaziwa azikwazi ukufakwa ilo msebenzisi"</string>
+    <string name="install_apps_user_restriction_dlg_text" msgid="2154119597001074022">"Lo msebenzisi akavunyelwe ukufaka izinhlelo zokusebenza"</string>
+    <string name="ok" msgid="7871959885003339302">"KULUNGILE"</string>
+    <string name="manage_applications" msgid="5400164782453975580">"Phatha izinhlelo zokusebenza"</string>
+    <string name="out_of_space_dlg_title" msgid="4156690013884649502">"Iphelelwe yisikhala"</string>
+    <string name="out_of_space_dlg_text" msgid="8727714096031856231">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukufakwa. Khulula isikhala bese uzama futhi."</string>
+    <string name="app_not_found_dlg_title" msgid="5107924008597470285">"Uhlelo lokusebenza alutholiwe"</string>
+    <string name="app_not_found_dlg_text" msgid="5219983779377811611">"Uhlelo lokusebenza alutholakalanga ohlwini lwezinhlelo zokusebenza ezifakiwe."</string>
+    <string name="user_is_not_allowed_dlg_title" msgid="6915293433252210232">"Akuvumelekile"</string>
+    <string name="user_is_not_allowed_dlg_text" msgid="3468447791330611681">"Umsebenzisi wamanje akavunyelwe ukwenza lokhu kukhipha."</string>
+    <string name="generic_error_dlg_title" msgid="5863195085927067752">"Iphutha"</string>
+    <string name="generic_error_dlg_text" msgid="5287861443265795232">"Uhlelo lokusebenza alikwazanga ukufakwa."</string>
+    <string name="uninstall_application_title" msgid="4045420072401428123">"Khipha uhlelo lokusebenza"</string>
+    <string name="uninstall_update_title" msgid="824411791011583031">"Khipha isibuyekezo"</string>
+    <string name="uninstall_activity_text" msgid="1928194674397770771">"I-<xliff:g id="ACTIVITY_NAME">%1$s</xliff:g> ingxenye yohlelo lokusebenza olulandelayo:"</string>
+    <string name="uninstall_application_text" msgid="3816830743706143980">"Ufuna ukukhipha le app?"</string>
+    <string name="uninstall_application_text_all_users" msgid="575491774380227119">"Ingabe ufuna ukukhipha lolu hlelo lokusebenza kubo "<b>"bonke"</b>" abasebenzisi? Uhlelo lokusebenza nedatha yalo kuzosuswa kubo "<b>"bonke"</b>" abasebenzisi kudivayisi."</string>
+    <string name="uninstall_application_text_user" msgid="498072714173920526">"Ingabe ufuna ukukhiphela lolu hlelo lokusebenza kumsebenzisi ongu-<xliff:g id="USERNAME">%1$s</xliff:g>?"</string>
+    <string name="uninstall_update_text" msgid="863648314632448705">"Shintshanisa lolu hlelo lokusebenza ngenguqulo yasekuqaleni? Yonke idatha izosuswa."</string>
+    <string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Shintshanisa lolu hlelo lokusebenza ngenguqulo yasekuqaleni? Yonke idatha izosuswa. Lokhu kuthinta bonke abasebenzisi bale divayisi, abafaka labo abanamaphrofayela wokusebenza."</string>
+    <string name="uninstalling_notification_channel" msgid="840153394325714653">"Ukukhishwa okuqhubekayo"</string>
+    <string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ukukhishwa okuhlulekile"</string>
+    <string name="uninstalling" msgid="8709566347688966845">"Iyakhipha..."</string>
+    <string name="uninstalling_app" msgid="8866082646836981397">"Ikhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
+    <string name="uninstall_done" msgid="439354138387969269">"Ukukhipha kuqedile."</string>
+    <string name="uninstall_done_app" msgid="4588850984473605768">"Kukhishwe i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+    <string name="uninstall_failed" msgid="1847750968168364332">"Ukukhipha akuphumelelanga."</string>
+    <string name="uninstall_failed_app" msgid="5506028705017601412">"Ukukhipha i-<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> akuphumelele."</string>
+    <string name="uninstall_failed_device_policy_manager" msgid="785293813665540305">"Ayikwazi ukukhipha uhlelo lokusebenza lomlawuli ledivayisi esebenzayo"</string>
+    <string name="uninstall_failed_device_policy_manager_of_user" msgid="4813104025494168064">"Ayikwazi ukukhipha uhlelo lokusebenza lomlawuli ledivayisi esebenzayo lika-<xliff:g id="USERNAME">%1$s</xliff:g>"</string>
+    <string name="uninstall_all_blocked_profile_owner" msgid="2009393666026751501">"Lolu hlelo lokusebenza luyadingeka kwabanye abasebenzisi noma amaphrofayela futhi lukhishelwe abanye"</string>
+    <string name="uninstall_blocked_profile_owner" msgid="6373897407002404848">"Lolu hlelo lokusebenza ludingelwa iphrofayela yakho futhi alikwazi ukukhishwa."</string>
+    <string name="uninstall_blocked_device_owner" msgid="6724602931761073901">"Lolu hlelo lokusebenza ludingwa umlawuli wedivayisi yakho futhi alukwazi ukukhishwa."</string>
+    <string name="manage_device_administrators" msgid="3092696419363842816">"Phatha izinhlelo zokusebenza zedivayisi yomlawuli"</string>
+    <string name="manage_users" msgid="1243995386982560813">"Phatha abasebenzisi"</string>
+    <string name="uninstall_failed_msg" msgid="2176744834786696012">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> ayikwazanga ukukhishwa"</string>
+    <string name="Parse_error_dlg_text" msgid="1661404001063076789">"Kube nenkinga yokwehlukanisa iphakheji."</string>
+    <string name="wear_not_allowed_dlg_title" msgid="8664785993465117517">"I-Android Wear"</string>
+    <string name="wear_not_allowed_dlg_text" msgid="704615521550939237">"Izenzo zokufaka/ukukhipha azisekelwe ku-Wear."</string>
+    <string name="message_staging" msgid="8032722385658438567">"Ifaka kusiteji uhlelo lokusebenza…"</string>
+    <string name="app_name_unknown" msgid="6881210203354323926">"Akwaziwa"</string>
+    <string name="untrusted_external_source_warning" product="tablet" msgid="6539403649459942547">"Ukuze uvikelwe, ithebulethi yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza ezingaziwa kusukela kulo mthombo."</string>
+    <string name="untrusted_external_source_warning" product="tv" msgid="1206648674551321364">"Ukuze uvikelwe, i-TV yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza ezingaziwa kusukela kulo mthombo."</string>
+    <string name="untrusted_external_source_warning" product="default" msgid="7279739265754475165">"Ukuze uvikelwe, ifoni yakho ayivunyelwe ukuthi ifake izinhlelo zokusebenza kusukela kulo mthombo."</string>
+    <string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Idatha yakho yefoni neyohlelo lwakho lokusebenza isengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala kufoni yakho noma ukulahlekelwa kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
+    <string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Ithebulethi yakho nedatha yomuntu siqu zisengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala kuthebulethi yakho noma ukulahleka kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
+    <string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Idatha yakho ye-TV neyomuntu siqu isengcupheni kakhulu ekuhlaselweni izinhlelo zokusebenza ezingaziwa. Ngokufaka lolu hlelo lokusebenza, uyavuma ukuthi unesibopho sanoma ikuphi ukonakala ku-TV yakho noma ukulahlekelwa kwedatha okungabangelwa ukusetshenziswa kwayo."</string>
+    <string name="anonymous_source_continue" msgid="4375745439457209366">"Qhubeka"</string>
+    <string name="external_sources_settings" msgid="4046964413071713807">"Izilungiselelo"</string>
+    <string name="wear_app_channel" msgid="1960809674709107850">"Ifaka/ikhipha izinhlelo zokusebenza ze-wear"</string>
 </resources>
diff --git a/packages/PackageInstaller/res/values/strings.xml b/packages/PackageInstaller/res/values/strings.xml
index ba81278..0f065ab 100644
--- a/packages/PackageInstaller/res/values/strings.xml
+++ b/packages/PackageInstaller/res/values/strings.xml
@@ -228,4 +228,14 @@
     <!-- Label for the notification channel containing notifications for embedded app operations [CHAR LIMIT=40] -->
     <string name="wear_app_channel">Installing/uninstalling wear apps</string>
 
+    <!-- Description for the app installer notification channel [CHAR LIMIT=40] -->
+    <string name="app_installed_notification_channel_description">App installed notification</string>
+
+    <!-- Notification message shown in status bar when an application is successfully installed.
+         [CHAR LIMIT=30] -->
+    <string name="notification_installation_success_message">Successfully installed</string>
+
+    <!-- Notification shown in status bar when an application is successfully installed.
+         [CHAR LIMIT=50] -->
+    <string name="notification_installation_success_status">Successfully installed \u201c<xliff:g id="appname" example="Package Installer">%1$s</xliff:g>\u201d</string>
 </resources>
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
index b3f1105..f2de9ec 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java
@@ -54,9 +54,14 @@
         Intent intent = getIntent();
         String callingPackage = getCallingPackage();
 
+        final boolean isSessionInstall =
+                PackageInstaller.ACTION_CONFIRM_INSTALL.equals(intent.getAction());
+
         // If the activity was started via a PackageInstaller session, we retrieve the calling
         // package from that session
-        int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1);
+        final int sessionId = (isSessionInstall
+                ? intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID, -1)
+                : -1);
         if (callingPackage == null && sessionId != -1) {
             PackageInstaller packageInstaller = getPackageManager().getPackageInstaller();
             PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
@@ -99,13 +104,16 @@
         nextActivity.putExtra(PackageInstallerActivity.EXTRA_ORIGINAL_SOURCE_INFO, sourceInfo);
         nextActivity.putExtra(Intent.EXTRA_ORIGINATING_UID, originatingUid);
 
-        if (PackageInstaller.ACTION_CONFIRM_INSTALL.equals(intent.getAction())) {
+        if (isSessionInstall) {
             nextActivity.setClass(this, PackageInstallerActivity.class);
         } else {
             Uri packageUri = intent.getData();
 
             if (packageUri != null && (packageUri.getScheme().equals(ContentResolver.SCHEME_FILE)
                     || packageUri.getScheme().equals(ContentResolver.SCHEME_CONTENT))) {
+                // [IMPORTANT] This path is deprecated, but should still work. Only necessary
+                // features should be added.
+
                 // Copy file to prevent it from being changed underneath this process
                 nextActivity.setClass(this, InstallStaging.class);
             } else if (packageUri != null && packageUri.getScheme().equals(
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledNotificationUtils.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledNotificationUtils.java
new file mode 100644
index 0000000..2ebbefa
--- /dev/null
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledNotificationUtils.java
@@ -0,0 +1,347 @@
+/*
+ * 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.
+ */
+
+package com.android.packageinstaller;
+
+import android.annotation.NonNull;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+
+/**
+ * A util class that handle and post new app installed notifications.
+ */
+class PackageInstalledNotificationUtils {
+    private static final String TAG = PackageInstalledNotificationUtils.class.getSimpleName();
+
+    private static final String NEW_APP_INSTALLED_CHANNEL_ID_PREFIX = "INSTALLER:";
+    private static final String META_DATA_INSTALLER_NOTIFICATION_SMALL_ICON_KEY =
+            "com.android.packageinstaller.notification.smallIcon";
+    private static final String META_DATA_INSTALLER_NOTIFICATION_COLOR_KEY =
+            "com.android.packageinstaller.notification.color";
+
+    private static final float DEFAULT_MAX_LABEL_SIZE_PX = 500f;
+
+    private final Context mContext;
+    private final NotificationManager mNotificationManager;
+
+    private final String mInstallerPackage;
+    private final String mInstallerAppLabel;
+    private final Icon mInstallerAppSmallIcon;
+    private final Integer mInstallerAppColor;
+
+    private final String mInstalledPackage;
+    private final String mInstalledAppLabel;
+    private final Icon mInstalledAppLargeIcon;
+
+    private final String mChannelId;
+
+    PackageInstalledNotificationUtils(@NonNull Context context, @NonNull String installerPackage,
+            @NonNull String installedPackage) {
+        mContext = context;
+        mNotificationManager = context.getSystemService(NotificationManager.class);
+        ApplicationInfo installerAppInfo;
+        ApplicationInfo installedAppInfo;
+
+        try {
+            installerAppInfo = context.getPackageManager().getApplicationInfo(installerPackage,
+                    PackageManager.GET_META_DATA);
+        } catch (PackageManager.NameNotFoundException e) {
+            // Should not happen
+            throw new IllegalStateException("Unable to get application info: " + installerPackage);
+        }
+        try {
+            installedAppInfo = context.getPackageManager().getApplicationInfo(installedPackage,
+                    PackageManager.GET_META_DATA);
+        } catch (PackageManager.NameNotFoundException e) {
+            // Should not happen
+            throw new IllegalStateException("Unable to get application info: " + installedPackage);
+        }
+        mInstallerPackage = installerPackage;
+        mInstallerAppLabel = getAppLabel(context, installerAppInfo, installerPackage);
+        mInstallerAppSmallIcon = getAppNotificationIcon(context, installerAppInfo);
+        mInstallerAppColor = getAppNotificationColor(context, installerAppInfo);
+
+        mInstalledPackage = installedPackage;
+        mInstalledAppLabel = getAppLabel(context, installedAppInfo, installerPackage);
+        mInstalledAppLargeIcon = getAppLargeIcon(installedAppInfo);
+
+        mChannelId = NEW_APP_INSTALLED_CHANNEL_ID_PREFIX + installerPackage;
+    }
+
+    /**
+     * Get app label from app's manifest.
+     *
+     * @param context     A context of the current app
+     * @param appInfo     Application info of targeted app
+     * @param packageName Package name of targeted app
+     * @return The label of targeted application, or package name if label is not found
+     */
+    private static String getAppLabel(@NonNull Context context, @NonNull ApplicationInfo appInfo,
+            @NonNull String packageName) {
+        CharSequence label = appInfo.loadSafeLabel(context.getPackageManager(),
+                DEFAULT_MAX_LABEL_SIZE_PX,
+                PackageItemInfo.SAFE_LABEL_FLAG_TRIM
+                        | PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE).toString();
+        if (label != null) {
+            return label.toString();
+        }
+        return packageName;
+    }
+
+    /**
+     * The app icon from app's manifest.
+     *
+     * @param appInfo Application info of targeted app
+     * @return App icon of targeted app, or Android default app icon if icon is not found
+     */
+    private static Icon getAppLargeIcon(@NonNull ApplicationInfo appInfo) {
+        if (appInfo.icon != 0) {
+            return Icon.createWithResource(appInfo.packageName, appInfo.icon);
+        } else {
+            return Icon.createWithResource("android", android.R.drawable.sym_def_app_icon);
+        }
+    }
+
+    /**
+     * Get notification icon from installer's manifest meta-data.
+     *
+     * @param context A context of the current app
+     * @param appInfo Installer application info
+     * @return Notification icon that listed in installer's manifest meta-data.
+     * If icon is not found in meta-data, then it returns Android default download icon.
+     */
+    private static Icon getAppNotificationIcon(@NonNull Context context,
+            @NonNull ApplicationInfo appInfo) {
+        if (appInfo.metaData == null) {
+            return Icon.createWithResource(context, R.drawable.ic_file_download);
+        }
+
+        int iconResId = appInfo.metaData.getInt(
+                META_DATA_INSTALLER_NOTIFICATION_SMALL_ICON_KEY, 0);
+        if (iconResId != 0) {
+            return Icon.createWithResource(appInfo.packageName, iconResId);
+        }
+        return Icon.createWithResource(context, R.drawable.ic_file_download);
+    }
+
+    /**
+     * Get notification color from installer's manifest meta-data.
+     *
+     * @param context A context of the current app
+     * @param appInfo Installer application info
+     * @return Notification color that listed in installer's manifest meta-data, or null if
+     * meta-data is not found.
+     */
+    private static Integer getAppNotificationColor(@NonNull Context context,
+            @NonNull ApplicationInfo appInfo) {
+        if (appInfo.metaData == null) {
+            return null;
+        }
+
+        int colorResId = appInfo.metaData.getInt(
+                META_DATA_INSTALLER_NOTIFICATION_COLOR_KEY, 0);
+        if (colorResId != 0) {
+            try {
+                PackageManager pm = context.getPackageManager();
+                Resources resources = pm.getResourcesForApplication(appInfo.packageName);
+                return resources.getColor(colorResId, context.getTheme());
+            } catch (PackageManager.NameNotFoundException e) {
+                Log.e(TAG, "Error while loading notification color: " + colorResId + " for "
+                        + appInfo.packageName);
+            }
+        }
+        return null;
+    }
+
+    private static Intent getAppDetailIntent(@NonNull String packageName) {
+        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+        intent.setData(Uri.fromParts("package", packageName, null));
+        return intent;
+    }
+
+    private static Intent resolveIntent(@NonNull Context context, @NonNull Intent i) {
+        ResolveInfo result = context.getPackageManager().resolveActivity(i, 0);
+        if (result == null) {
+            return null;
+        }
+        return new Intent(i.getAction()).setClassName(result.activityInfo.packageName,
+                result.activityInfo.name);
+    }
+
+    private static Intent getAppStoreLink(@NonNull Context context,
+            @NonNull String installerPackageName, @NonNull String packageName) {
+        Intent intent = new Intent(Intent.ACTION_SHOW_APP_INFO)
+                .setPackage(installerPackageName);
+
+        Intent result = resolveIntent(context, intent);
+        if (result != null) {
+            result.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
+            return result;
+        }
+        return null;
+    }
+
+    /**
+     * Create notification channel for showing apps installed notifications.
+     */
+    private void createChannel() {
+        NotificationChannel channel = new NotificationChannel(mChannelId, mInstallerAppLabel,
+                NotificationManager.IMPORTANCE_DEFAULT);
+        channel.setDescription(
+                mContext.getString(R.string.app_installed_notification_channel_description));
+        channel.enableVibration(false);
+        channel.setSound(null, null);
+        channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
+        channel.setBlockableSystem(true);
+
+        mNotificationManager.createNotificationChannel(channel);
+    }
+
+    /**
+     * Returns a pending intent when user clicks on apps installed notification.
+     * It should launch the app if possible, otherwise it will return app store's app page.
+     * If app store's app page is not available, it will return Android app details page.
+     */
+    private PendingIntent getInstalledAppLaunchIntent() {
+        Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(mInstalledPackage);
+
+        // If installed app does not have a launch intent, bring user to app store page
+        if (intent == null) {
+            intent = getAppStoreLink(mContext, mInstallerPackage, mInstalledPackage);
+        }
+
+        // If app store cannot handle this, bring user to app settings page
+        if (intent == null) {
+            intent = getAppDetailIntent(mInstalledPackage);
+        }
+
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return PendingIntent.getActivity(mContext,
+                0 /* request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
+    /**
+     * Returns a pending intent that starts installer's launch intent.
+     * If it doesn't have a launch intent, it will return installer's Android app details page.
+     */
+    private PendingIntent getInstallerEntranceIntent() {
+        Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(mInstallerPackage);
+
+        // If installer does not have a launch intent, bring user to app settings page
+        if (intent == null) {
+            intent = getAppDetailIntent(mInstallerPackage);
+        }
+
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        return PendingIntent.getActivity(mContext,
+                0 /* request code */, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+    }
+
+    /**
+     * Returns a notification builder for grouped notifications.
+     */
+    private Notification.Builder getGroupNotificationBuilder() {
+        PendingIntent contentIntent = getInstallerEntranceIntent();
+
+        Bundle extras = new Bundle();
+        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, mInstallerAppLabel);
+
+        Notification.Builder builder =
+                new Notification.Builder(mContext, mChannelId)
+                        .setSmallIcon(mInstallerAppSmallIcon)
+                        .setGroup(mChannelId)
+                        .setExtras(extras)
+                        .setLocalOnly(true)
+                        .setCategory(Notification.CATEGORY_STATUS)
+                        .setContentIntent(contentIntent)
+                        .setGroupSummary(true);
+
+        if (mInstallerAppColor != null) {
+            builder.setColor(mInstallerAppColor);
+        }
+        return builder;
+    }
+
+    /**
+     * Returns notification build for individual installed applications.
+     */
+    private Notification.Builder getAppInstalledNotificationBuilder() {
+        PendingIntent contentIntent = getInstalledAppLaunchIntent();
+
+        Bundle extras = new Bundle();
+        extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME, mInstallerAppLabel);
+
+        String tickerText = String.format(
+                mContext.getString(R.string.notification_installation_success_status),
+                mInstalledAppLabel);
+
+        Notification.Builder builder =
+                new Notification.Builder(mContext, mChannelId)
+                        .setAutoCancel(true)
+                        .setSmallIcon(mInstallerAppSmallIcon)
+                        .setContentTitle(mInstalledAppLabel)
+                        .setContentText(mContext.getString(
+                                R.string.notification_installation_success_message))
+                        .setContentIntent(contentIntent)
+                        .setTicker(tickerText)
+                        .setCategory(Notification.CATEGORY_STATUS)
+                        .setShowWhen(true)
+                        .setWhen(System.currentTimeMillis())
+                        .setLocalOnly(true)
+                        .setGroup(mChannelId)
+                        .addExtras(extras)
+                        .setStyle(new Notification.BigTextStyle());
+
+        if (mInstalledAppLargeIcon != null) {
+            builder.setLargeIcon(mInstalledAppLargeIcon);
+        }
+        if (mInstallerAppColor != null) {
+            builder.setColor(mInstallerAppColor);
+        }
+        return builder;
+    }
+
+    /**
+     * Post new app installed notification.
+     */
+    void postAppInstalledNotification() {
+        createChannel();
+
+        // Post app installed notification
+        Notification.Builder appNotificationBuilder = getAppInstalledNotificationBuilder();
+        mNotificationManager.notify(mInstalledPackage, mInstalledPackage.hashCode(),
+                appNotificationBuilder.build());
+
+        // Post installer group notification
+        Notification.Builder groupNotificationBuilder = getGroupNotificationBuilder();
+        mNotificationManager.notify(mInstallerPackage, mInstallerPackage.hashCode(),
+                groupNotificationBuilder.build());
+    }
+}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java
index 67ac99f..1eb423e 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java
@@ -19,16 +19,54 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
 
 /**
  * Receive new app installed broadcast and notify user new app installed.
  */
 public class PackageInstalledReceiver extends BroadcastReceiver {
+    private static final String TAG = PackageInstalledReceiver.class.getSimpleName();
 
-    private static final String TAG = "PackageInstalledReceiver";
+    private static final boolean DEBUG = false;
+    private static final boolean APP_INSTALLED_NOTIFICATION_ENABLED = false;
 
     @Override
     public void onReceive(Context context, Intent intent) {
-        // TODO: Add logic to handle new app installed.
+        if (!APP_INSTALLED_NOTIFICATION_ENABLED) {
+            return;
+        }
+
+        String action = intent.getAction();
+
+        if (DEBUG) {
+            Log.i(TAG, "Received action: " + action);
+        }
+
+        if (Intent.ACTION_PACKAGE_ADDED.equals(action)) {
+            Uri packageUri = intent.getData();
+            if (packageUri == null) {
+                return;
+            }
+
+            String packageName = packageUri.getSchemeSpecificPart();
+            if (packageName == null) {
+                Log.e(TAG, "No package name");
+                return;
+            }
+
+            if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+                if (DEBUG) {
+                    Log.i(TAG, "Not new app, skip it: " + packageName);
+                }
+                return;
+            }
+
+            // TODO: Make sure the installer information here is accurate
+            String installer =
+                    context.getPackageManager().getInstallerPackageName(packageName);
+            new PackageInstalledNotificationUtils(context, installer,
+                    packageName).postAppInstalledNotification();
+        }
     }
 }
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index 8c29a25..441dbac 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -16,7 +16,7 @@
 */
 package com.android.packageinstaller;
 
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -281,7 +281,7 @@
 
     @Override
     protected void onCreate(Bundle icicle) {
-        getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+        getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
 
         super.onCreate(null);
 
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerApplication.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerApplication.java
index 9b7e64e..a0f0ae9 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerApplication.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerApplication.java
@@ -23,6 +23,6 @@
     @Override
     public void onCreate() {
         super.onCreate();
-        PackageItemInfo.setForceSafeLabels(true);
+        PackageItemInfo.forceSafeLabels();
     }
 }
diff --git a/packages/PrintSpooler/Android.bp b/packages/PrintSpooler/Android.bp
new file mode 100644
index 0000000..c40a817
--- /dev/null
+++ b/packages/PrintSpooler/Android.bp
@@ -0,0 +1,38 @@
+// Copyright (C) 2013 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT 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: "PrintSpooler",
+
+    resource_dirs: ["res"],
+
+    srcs: [
+        "src/**/*.java",
+        "src/com/android/printspooler/renderer/IPdfRenderer.aidl",
+        "src/com/android/printspooler/renderer/IPdfEditor.aidl",
+    ],
+
+    platform_apis: true,
+
+    jni_libs: ["libprintspooler_jni"],
+    static_libs: [
+        "android-support-v7-recyclerview",
+        "android-support-compat",
+        "android-support-media-compat",
+        "android-support-core-utils",
+        "android-support-core-ui",
+        "android-support-fragment",
+        "android-support-annotations",
+    ],
+}
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
deleted file mode 100644
index e356f38..0000000
--- a/packages/PrintSpooler/Android.mk
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (C) 2013 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT 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_RESOURCE_DIR := $(LOCAL_PATH)/res
-LOCAL_USE_AAPT2 := true
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SRC_FILES += \
-    src/com/android/printspooler/renderer/IPdfRenderer.aidl \
-    src/com/android/printspooler/renderer/IPdfEditor.aidl
-
-LOCAL_PACKAGE_NAME := PrintSpooler
-LOCAL_PRIVATE_PLATFORM_APIS := true
-
-LOCAL_JNI_SHARED_LIBRARIES := libprintspooler_jni
-LOCAL_STATIC_ANDROID_LIBRARIES := \
-    android-support-v7-recyclerview \
-    android-support-compat \
-    android-support-media-compat \
-    android-support-core-utils \
-    android-support-core-ui \
-    android-support-fragment
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-annotations
-
-include $(BUILD_PACKAGE)
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
index 1644546..42c1997 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java
@@ -218,8 +218,14 @@
             throw new IllegalStateException("Cannot update in state:" + stateToString(mState));
         }
 
-        // We schedule a layout if the constraints changed.
-        if (!mUpdateSpec.hasSameConstraints(attributes, preview)) {
+        /*
+         * We schedule a layout in two cases:
+         * - if the current command is canceling. In this case the mUpdateSpec will be marked as
+         *   stale once the command is done, hence we have to start from scratch
+         * - if the constraints changed we have a different document, hence start a new layout
+         */
+        if (mCurrentCommand != null && mCurrentCommand.isCanceling()
+                || !mUpdateSpec.hasSameConstraints(attributes, preview)) {
             willUpdate = true;
 
             // If there is a current command that is running we ask for a
diff --git a/packages/PrintSpooler/tests/Android.mk b/packages/PrintSpooler/tests/Android.mk
deleted file mode 100644
index 83e00ce..0000000
--- a/packages/PrintSpooler/tests/Android.mk
+++ /dev/null
@@ -1,19 +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)
-
-include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/packages/PrintSpooler/tests/outofprocess/Android.bp b/packages/PrintSpooler/tests/outofprocess/Android.bp
new file mode 100644
index 0000000..e88074e
--- /dev/null
+++ b/packages/PrintSpooler/tests/outofprocess/Android.bp
@@ -0,0 +1,30 @@
+// 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_test {
+    name: "PrintSpoolerOutOfProcessTests",
+
+    srcs: ["src/**/*.java"],
+
+    libs: ["android.test.runner.stubs"],
+    static_libs: [
+        "android-support-test",
+        "ub-uiautomator",
+        "mockito-target-minus-junit4",
+        "print-test-util-lib",
+    ],
+
+    sdk_version: "test_current",
+    test_suites: ["device-tests"],
+}
diff --git a/packages/PrintSpooler/tests/outofprocess/Android.mk b/packages/PrintSpooler/tests/outofprocess/Android.mk
deleted file mode 100644
index 161a600..0000000
--- a/packages/PrintSpooler/tests/outofprocess/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_MODULE_TAGS := tests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner.stubs
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ub-uiautomator mockito-target-minus-junit4 print-test-util-lib
-
-LOCAL_PACKAGE_NAME := PrintSpoolerOutOfProcessTests
-LOCAL_SDK_VERSION := current
-LOCAL_COMPATIBILITY_SUITE := device-tests
-
-include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/Android.bp b/packages/SettingsLib/Android.bp
index 89438e5..5161344 100644
--- a/packages/SettingsLib/Android.bp
+++ b/packages/SettingsLib/Android.bp
@@ -2,20 +2,19 @@
 
     name: "SettingsLib",
 
-    libs: [
+    static_libs: [
         "androidx.annotation_annotation",
         "androidx.legacy_legacy-support-v4",
         "androidx.recyclerview_recyclerview",
         "androidx.preference_preference",
         "androidx.appcompat_appcompat",
         "androidx.lifecycle_lifecycle-runtime",
-    ],
 
-    static_libs: [
         "SettingsLibHelpUtils",
         "SettingsLibRestrictedLockUtils",
         "SettingsLibAppPreference",
         "SettingsLibSearchWidget",
+        "SettingsLibSettingsSpinner",
     ],
 
     // ANDROIDMK TRANSLATION ERROR: unsupported assignment to LOCAL_SHARED_JAVA_LIBRARIES
diff --git a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
index 7306d968..e407d72 100644
--- a/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
+++ b/packages/SettingsLib/HelpUtils/src/com/android/settingslib/HelpUtils.java
@@ -187,17 +187,17 @@
 
         if (sendPackageName && includePackageName) {
             String[] packageNameKey =
-                    {resources.getString(android.R.string.config_help_package_name_key)};
+                    {resources.getString(android.R.string.config_helpPackageNameKey)};
             String[] packageNameValue =
-                    {resources.getString(android.R.string.config_help_package_name_value)};
+                    {resources.getString(android.R.string.config_helpPackageNameValue)};
             String helpIntentExtraKey =
-                    resources.getString(android.R.string.config_help_intent_extra_key);
+                    resources.getString(android.R.string.config_helpIntentExtraKey);
             String helpIntentNameKey =
-                    resources.getString(android.R.string.config_help_intent_name_key);
+                    resources.getString(android.R.string.config_helpIntentNameKey);
             String feedbackIntentExtraKey =
-                    resources.getString(android.R.string.config_feedback_intent_extra_key);
+                    resources.getString(android.R.string.config_feedbackIntentExtraKey);
             String feedbackIntentNameKey =
-                    resources.getString(android.R.string.config_feedback_intent_name_key);
+                    resources.getString(android.R.string.config_feedbackIntentNameKey);
             intent.putExtra(helpIntentExtraKey, packageNameKey);
             intent.putExtra(helpIntentNameKey, packageNameValue);
             intent.putExtra(feedbackIntentExtraKey, packageNameKey);
diff --git a/packages/SettingsLib/RestrictedLockUtils/res/layout/restricted_icon.xml b/packages/SettingsLib/RestrictedLockUtils/res/layout/restricted_icon.xml
index 0f02abd..0748192 100644
--- a/packages/SettingsLib/RestrictedLockUtils/res/layout/restricted_icon.xml
+++ b/packages/SettingsLib/RestrictedLockUtils/res/layout/restricted_icon.xml
@@ -15,7 +15,7 @@
 -->
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/restricted_icon"
-    android:layout_width="@*android:dimen/config_restricted_icon_size"
-    android:layout_height="@*android:dimen/config_restricted_icon_size"
+    android:layout_width="@*android:dimen/config_restrictedIconSize"
+    android:layout_height="@*android:dimen/config_restrictedIconSize"
     android:tint="?android:attr/colorAccent"
     android:src="@*android:drawable/ic_info" />
diff --git a/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java
index 738181d..8529e3e 100644
--- a/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/RestrictedLockUtils/src/com/android/settingslib/RestrictedLockUtils.java
@@ -33,13 +33,13 @@
  * support message dialog.
  */
 public class RestrictedLockUtils {
-    public static EnforcedAdmin getProfileOrDeviceOwner(Context context, int userId) {
-        return getProfileOrDeviceOwner(context, null, userId);
+    public static EnforcedAdmin getProfileOrDeviceOwner(Context context, UserHandle user) {
+        return getProfileOrDeviceOwner(context, null, user);
     }
 
     public static EnforcedAdmin getProfileOrDeviceOwner(
-            Context context, String enforcedRestriction, int userId) {
-        if (userId == UserHandle.USER_NULL) {
+            Context context, String enforcedRestriction, UserHandle user) {
+        if (user == null) {
             return null;
         }
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
@@ -47,14 +47,14 @@
         if (dpm == null) {
             return null;
         }
-        ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId);
+        ComponentName adminComponent = dpm.getProfileOwnerAsUser(user);
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
+            return new EnforcedAdmin(adminComponent, enforcedRestriction, user);
         }
-        if (dpm.getDeviceOwnerUserId() == userId) {
+        if (Objects.equals(dpm.getDeviceOwnerUser(), user)) {
             adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
             if (adminComponent != null) {
-                return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
+                return new EnforcedAdmin(adminComponent, enforcedRestriction, user);
             }
         }
         return null;
@@ -66,9 +66,9 @@
     public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
         final Intent intent = getShowAdminSupportDetailsIntent(context, admin);
         int targetUserId = UserHandle.myUserId();
-        if (admin != null && admin.userId != UserHandle.USER_NULL
-                && isCurrentUserOrProfile(context, admin.userId)) {
-            targetUserId = admin.userId;
+        if (admin != null && admin.user != null
+                && isCurrentUserOrProfile(context, admin.user.getIdentifier())) {
+            targetUserId = admin.user.getIdentifier();
         }
         intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, admin.enforcedRestriction);
         context.startActivityAsUser(intent, UserHandle.of(targetUserId));
@@ -80,24 +80,17 @@
             if (admin.component != null) {
                 intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin.component);
             }
-            int adminUserId = UserHandle.myUserId();
-            if (admin.userId != UserHandle.USER_NULL) {
-                adminUserId = admin.userId;
-            }
-            intent.putExtra(Intent.EXTRA_USER_ID, adminUserId);
+            final UserHandle adminUser = admin.user != null
+                    ? admin.user
+                    : UserHandle.of(UserHandle.myUserId());
+            intent.putExtra(Intent.EXTRA_USER, adminUser);
         }
         return intent;
     }
 
     public static boolean isCurrentUserOrProfile(Context context, int userId) {
         UserManager um = context.getSystemService(UserManager.class);
-        int[] userIds = um.getProfileIds(UserHandle.myUserId(), true);
-        for (int i = 0; i < userIds.length; i++) {
-            if (userIds[i] == userId) {
-                return true;
-            }
-        }
-        return false;
+        return um.getUserProfiles().contains(UserHandle.of(userId));
     }
 
     public static class EnforcedAdmin {
@@ -109,7 +102,8 @@
          */
         @Nullable
         public String enforcedRestriction = null;
-        public int userId = UserHandle.USER_NULL;
+        @Nullable
+        public UserHandle user = null;
 
         // We use this to represent the case where a policy is enforced by multiple admins.
         public final static EnforcedAdmin MULTIPLE_ENFORCED_ADMIN = new EnforcedAdmin();
@@ -121,15 +115,15 @@
             return enforcedAdmin;
         }
 
-        public EnforcedAdmin(ComponentName component, int userId) {
+        public EnforcedAdmin(ComponentName component, UserHandle user) {
             this.component = component;
-            this.userId = userId;
+            this.user = user;
         }
 
-        public EnforcedAdmin(ComponentName component, String enforcedRestriction, int userId) {
+        public EnforcedAdmin(ComponentName component, String enforcedRestriction, UserHandle user) {
             this.component = component;
             this.enforcedRestriction = enforcedRestriction;
-            this.userId = userId;
+            this.user = user;
         }
 
         public EnforcedAdmin(EnforcedAdmin other) {
@@ -138,7 +132,7 @@
             }
             this.component = other.component;
             this.enforcedRestriction = other.enforcedRestriction;
-            this.userId = other.userId;
+            this.user = other.user;
         }
 
         public EnforcedAdmin() {
@@ -149,14 +143,14 @@
             if (this == o) return true;
             if (o == null || getClass() != o.getClass()) return false;
             EnforcedAdmin that = (EnforcedAdmin) o;
-            return userId == that.userId &&
+            return Objects.equals(user, that.user) &&
                     Objects.equals(component, that.component) &&
                     Objects.equals(enforcedRestriction, that.enforcedRestriction);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(component, enforcedRestriction, userId);
+            return Objects.hash(component, enforcedRestriction, user);
         }
 
         @Override
@@ -164,7 +158,7 @@
             return "EnforcedAdmin{" +
                     "component=" + component +
                     ", enforcedRestriction='" + enforcedRestriction +
-                    ", userId=" + userId +
+                    ", user=" + user +
                     '}';
         }
     }
diff --git a/packages/SettingsLib/SearchWidget/res/values-af/strings.xml b/packages/SettingsLib/SearchWidget/res/values-af/strings.xml
new file mode 100644
index 0000000..f89b66e
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-af/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Soekinstellings"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-am/strings.xml b/packages/SettingsLib/SearchWidget/res/values-am/strings.xml
new file mode 100644
index 0000000..03e31c9
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-am/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"የፍለጋ ቅንብሮች"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ar/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ar/strings.xml
new file mode 100644
index 0000000..8d7fd348
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ar/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"البحث في الإعدادات"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-az/strings.xml b/packages/SettingsLib/SearchWidget/res/values-az/strings.xml
new file mode 100644
index 0000000..fab4156
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-az/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Seçimlər"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..f556eae
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Podešavanja pretrage"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-be/strings.xml b/packages/SettingsLib/SearchWidget/res/values-be/strings.xml
new file mode 100644
index 0000000..9e2ce1e
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-be/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Налады пошуку"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-bg/strings.xml b/packages/SettingsLib/SearchWidget/res/values-bg/strings.xml
new file mode 100644
index 0000000..7f54164
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-bg/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Настройки за търсене"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml b/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml
new file mode 100644
index 0000000..b56d734
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-bn/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"সেটিংস সার্চ করুন"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-bs/strings.xml b/packages/SettingsLib/SearchWidget/res/values-bs/strings.xml
new file mode 100644
index 0000000..9765ef8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-bs/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Pretražite postavke"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ca/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ca/strings.xml
new file mode 100644
index 0000000..829e9ca
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ca/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Cerca opcions de configuració"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-cs/strings.xml b/packages/SettingsLib/SearchWidget/res/values-cs/strings.xml
new file mode 100644
index 0000000..41fe009
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-cs/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Prohledat nastavení"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-da/strings.xml b/packages/SettingsLib/SearchWidget/res/values-da/strings.xml
new file mode 100644
index 0000000..d6b39e1
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-da/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Søgeindstillinger"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-de/strings.xml b/packages/SettingsLib/SearchWidget/res/values-de/strings.xml
new file mode 100644
index 0000000..b438607
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-de/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Sucheinstellungen"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-el/strings.xml b/packages/SettingsLib/SearchWidget/res/values-el/strings.xml
new file mode 100644
index 0000000..c8fae5d
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-el/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Ρυθμίσεις αναζήτησης"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-en-rAU/strings.xml b/packages/SettingsLib/SearchWidget/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..3e7ded8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-en-rAU/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Search settings"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-en-rCA/strings.xml b/packages/SettingsLib/SearchWidget/res/values-en-rCA/strings.xml
new file mode 100644
index 0000000..3e7ded8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-en-rCA/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Search settings"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-en-rGB/strings.xml b/packages/SettingsLib/SearchWidget/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..3e7ded8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-en-rGB/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Search settings"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-en-rIN/strings.xml b/packages/SettingsLib/SearchWidget/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..3e7ded8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-en-rIN/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Search settings"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-en-rXC/strings.xml b/packages/SettingsLib/SearchWidget/res/values-en-rXC/strings.xml
new file mode 100644
index 0000000..c8627c8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-en-rXC/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‏‎‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‎‏‏‏‎‎‏‏‎‏‎‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‎‎‏‎‎‏‎Search settings‎‏‎‎‏‎"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml b/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..40a8fd0
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-es-rUS/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Configuración de búsqueda"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-es/strings.xml b/packages/SettingsLib/SearchWidget/res/values-es/strings.xml
new file mode 100644
index 0000000..c713c7d
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-es/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Buscar ajustes"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-et/strings.xml b/packages/SettingsLib/SearchWidget/res/values-et/strings.xml
new file mode 100644
index 0000000..294bced
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-et/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Otsinguseaded"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-eu/strings.xml b/packages/SettingsLib/SearchWidget/res/values-eu/strings.xml
new file mode 100644
index 0000000..f47273e
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-eu/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Bilaketa-ezarpenak"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-fa/strings.xml b/packages/SettingsLib/SearchWidget/res/values-fa/strings.xml
new file mode 100644
index 0000000..3787005
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-fa/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"تنظیمات جستجو"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-fi/strings.xml b/packages/SettingsLib/SearchWidget/res/values-fi/strings.xml
new file mode 100644
index 0000000..21df5a0
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-fi/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Hakuasetukset"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml b/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..e065fa0
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-fr-rCA/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Paramètres de recherche"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-fr/strings.xml b/packages/SettingsLib/SearchWidget/res/values-fr/strings.xml
new file mode 100644
index 0000000..e065fa0
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-fr/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Paramètres de recherche"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-gl/strings.xml b/packages/SettingsLib/SearchWidget/res/values-gl/strings.xml
new file mode 100644
index 0000000..4e30f8c
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-gl/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Configuración de busca"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-gu/strings.xml b/packages/SettingsLib/SearchWidget/res/values-gu/strings.xml
new file mode 100644
index 0000000..43c616b
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-gu/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"શોધ સેટિંગ"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-hi/strings.xml b/packages/SettingsLib/SearchWidget/res/values-hi/strings.xml
new file mode 100644
index 0000000..e6ab56c
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-hi/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"खोज सेटिंग"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-hr/strings.xml b/packages/SettingsLib/SearchWidget/res/values-hr/strings.xml
new file mode 100644
index 0000000..f5d3436
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-hr/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Pretraži postavke"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-hu/strings.xml b/packages/SettingsLib/SearchWidget/res/values-hu/strings.xml
new file mode 100644
index 0000000..7fd110c
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-hu/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Keresési beállítások"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-hy/strings.xml b/packages/SettingsLib/SearchWidget/res/values-hy/strings.xml
new file mode 100644
index 0000000..04c3416
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-hy/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Որոնման կարգավորումներ"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-in/strings.xml b/packages/SettingsLib/SearchWidget/res/values-in/strings.xml
new file mode 100644
index 0000000..b5a97d0
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-in/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Setelan penelusuran"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-is/strings.xml b/packages/SettingsLib/SearchWidget/res/values-is/strings.xml
new file mode 100644
index 0000000..341058c
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-is/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Leitarstillingar"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-it/strings.xml b/packages/SettingsLib/SearchWidget/res/values-it/strings.xml
new file mode 100644
index 0000000..c59db23
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-it/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Impostazioni di ricerca"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-iw/strings.xml b/packages/SettingsLib/SearchWidget/res/values-iw/strings.xml
new file mode 100644
index 0000000..671f69a
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-iw/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"הגדרות חיפוש"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ja/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ja/strings.xml
new file mode 100644
index 0000000..133e525
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ja/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"検索設定"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ka/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ka/strings.xml
new file mode 100644
index 0000000..bd7e353
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ka/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"ძიების პარამეტრები"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-kk/strings.xml b/packages/SettingsLib/SearchWidget/res/values-kk/strings.xml
new file mode 100644
index 0000000..03538a1
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-kk/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Іздеу параметрлері"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-km/strings.xml b/packages/SettingsLib/SearchWidget/res/values-km/strings.xml
new file mode 100644
index 0000000..f012e3a
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-km/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"ការកំណត់ការ​ស្វែងរក"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-kn/strings.xml b/packages/SettingsLib/SearchWidget/res/values-kn/strings.xml
new file mode 100644
index 0000000..dbfcb1a
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-kn/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"ಹುಡುಕಾಟ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ko/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ko/strings.xml
new file mode 100644
index 0000000..948eb03
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ko/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"검색 설정"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ky/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ky/strings.xml
new file mode 100644
index 0000000..81679cd
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ky/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Издөө жөндөөлөрү"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-lo/strings.xml b/packages/SettingsLib/SearchWidget/res/values-lo/strings.xml
new file mode 100644
index 0000000..bb4bb46
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-lo/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"ການຕັ້ງຄ່າການຊອກຫາ"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-lt/strings.xml b/packages/SettingsLib/SearchWidget/res/values-lt/strings.xml
new file mode 100644
index 0000000..0d3f62b
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-lt/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Paieškos nustatymai"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-lv/strings.xml b/packages/SettingsLib/SearchWidget/res/values-lv/strings.xml
new file mode 100644
index 0000000..aca4624
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-lv/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Meklēšanas iestatījumi"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-mk/strings.xml b/packages/SettingsLib/SearchWidget/res/values-mk/strings.xml
new file mode 100644
index 0000000..79fde5d
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-mk/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Поставки за пребарување"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ml/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ml/strings.xml
new file mode 100644
index 0000000..ada622f
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ml/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"തിരയൽ ക്രമീകരണം"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-mn/strings.xml b/packages/SettingsLib/SearchWidget/res/values-mn/strings.xml
new file mode 100644
index 0000000..445b592
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-mn/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Тохиргоог хайх"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-mr/strings.xml b/packages/SettingsLib/SearchWidget/res/values-mr/strings.xml
new file mode 100644
index 0000000..a57b25a
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-mr/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"सेटिंग्ज शोधा"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ms/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ms/strings.xml
new file mode 100644
index 0000000..69afdcf
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ms/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Tetapan carian"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-my/strings.xml b/packages/SettingsLib/SearchWidget/res/values-my/strings.xml
new file mode 100644
index 0000000..9d532e8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-my/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"ရှာဖွေမှု ဆက်တင်များ"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-nb/strings.xml b/packages/SettingsLib/SearchWidget/res/values-nb/strings.xml
new file mode 100644
index 0000000..53b808f
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-nb/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Søk i innstillingene"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ne/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ne/strings.xml
new file mode 100644
index 0000000..f3ffa47
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ne/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"खोजसम्बन्धी सेटिङहरू"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-nl/strings.xml b/packages/SettingsLib/SearchWidget/res/values-nl/strings.xml
new file mode 100644
index 0000000..3bd1c3a
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-nl/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Zoekinstellingen"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml
new file mode 100644
index 0000000..73f46e7
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-pa/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"ਖੋਜ ਸੈਟਿੰਗਾਂ"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-pl/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pl/strings.xml
new file mode 100644
index 0000000..2d28432
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-pl/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Wyszukaj ustawienia"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-pt-rBR/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..f406bc1
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-pt-rBR/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Configurações de pesquisa"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..7846be1
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-pt-rPT/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Definições de pesquisa"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-pt/strings.xml b/packages/SettingsLib/SearchWidget/res/values-pt/strings.xml
new file mode 100644
index 0000000..f406bc1
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-pt/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Configurações de pesquisa"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ro/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ro/strings.xml
new file mode 100644
index 0000000..12ff956
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ro/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Căutați în setări"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ru/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ru/strings.xml
new file mode 100644
index 0000000..4593ca7
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ru/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Настройки поиска"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-si/strings.xml b/packages/SettingsLib/SearchWidget/res/values-si/strings.xml
new file mode 100644
index 0000000..3dff095
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-si/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"සෙවීම් සැකසීම්"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-sk/strings.xml b/packages/SettingsLib/SearchWidget/res/values-sk/strings.xml
new file mode 100644
index 0000000..2fac6fe
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-sk/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Hľadajte v nastaveniach"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-sl/strings.xml b/packages/SettingsLib/SearchWidget/res/values-sl/strings.xml
new file mode 100644
index 0000000..f937c85
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-sl/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Nastavitve iskanja"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-sq/strings.xml b/packages/SettingsLib/SearchWidget/res/values-sq/strings.xml
new file mode 100644
index 0000000..d7085f4
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-sq/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Cilësimet e kërkimit"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-sr/strings.xml b/packages/SettingsLib/SearchWidget/res/values-sr/strings.xml
new file mode 100644
index 0000000..650a975
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-sr/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Подешавања претраге"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-sv/strings.xml b/packages/SettingsLib/SearchWidget/res/values-sv/strings.xml
new file mode 100644
index 0000000..7afce7f
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-sv/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Sökinställningar"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml b/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml
new file mode 100644
index 0000000..d446b20
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-sw/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Mipangilio ya utafutaji"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-ta/strings.xml b/packages/SettingsLib/SearchWidget/res/values-ta/strings.xml
new file mode 100644
index 0000000..47eb217
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-ta/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"அமைப்புகளில் தேடு்க"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-te/strings.xml b/packages/SettingsLib/SearchWidget/res/values-te/strings.xml
new file mode 100644
index 0000000..86c212b
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-te/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"శోధన సెట్టింగ్‌లు"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-th/strings.xml b/packages/SettingsLib/SearchWidget/res/values-th/strings.xml
new file mode 100644
index 0000000..903d8b5
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-th/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"ค้นหาการตั้งค่า"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-tl/strings.xml b/packages/SettingsLib/SearchWidget/res/values-tl/strings.xml
new file mode 100644
index 0000000..337dabe
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-tl/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Mga setting ng paghahanap"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-tr/strings.xml b/packages/SettingsLib/SearchWidget/res/values-tr/strings.xml
new file mode 100644
index 0000000..9805a9d
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-tr/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Arama ayarları"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-uk/strings.xml b/packages/SettingsLib/SearchWidget/res/values-uk/strings.xml
new file mode 100644
index 0000000..b365646
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-uk/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Налаштування пошуку"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-uz/strings.xml b/packages/SettingsLib/SearchWidget/res/values-uz/strings.xml
new file mode 100644
index 0000000..786cc40
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-uz/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Qidiruv sozlamalari"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-vi/strings.xml b/packages/SettingsLib/SearchWidget/res/values-vi/strings.xml
new file mode 100644
index 0000000..95f98c8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-vi/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Tìm kiếm mục cài đặt"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-zh-rCN/strings.xml b/packages/SettingsLib/SearchWidget/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..36748b8
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-zh-rCN/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"搜索设置"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-zh-rHK/strings.xml b/packages/SettingsLib/SearchWidget/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..50b4014
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-zh-rHK/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"搜尋設定"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-zh-rTW/strings.xml b/packages/SettingsLib/SearchWidget/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..50b4014
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-zh-rTW/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"搜尋設定"</string>
+</resources>
diff --git a/packages/SettingsLib/SearchWidget/res/values-zu/strings.xml b/packages/SettingsLib/SearchWidget/res/values-zu/strings.xml
new file mode 100644
index 0000000..def158d
--- /dev/null
+++ b/packages/SettingsLib/SearchWidget/res/values-zu/strings.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+   -->
+
+<resources 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">"Sesha izilungiselelo"</string>
+</resources>
diff --git a/packages/SettingsLib/SettingsSpinner/Android.bp b/packages/SettingsLib/SettingsSpinner/Android.bp
new file mode 100644
index 0000000..f18917c
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/Android.bp
@@ -0,0 +1,9 @@
+android_library {
+    name: "SettingsLibSettingsSpinner",
+
+    srcs: ["src/**/*.java"],
+    resource_dirs: ["res"],
+
+    sdk_version: "system_current",
+    min_sdk_version: "21",
+}
diff --git a/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml b/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml
new file mode 100644
index 0000000..5db9335
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?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.settingslib.widget.settingsspinner">
+
+    <uses-sdk android:minSdkVersion="21" />
+
+</manifest>
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml
new file mode 100644
index 0000000..827d0b5
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/arrow_drop_down_24dp.xml
@@ -0,0 +1,26 @@
+<?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.
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:viewportWidth="24"
+        android:viewportHeight="24"
+        android:width="24dp"
+        android:height="24dp">
+    <path
+        android:pathData="M7 10l5 5 5 -5z"
+        android:fillColor="?android:attr/textColorPrimary"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
new file mode 100644
index 0000000..cbebbb3
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
@@ -0,0 +1,41 @@
+<?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.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
+            android:paddingMode="stack">
+    <item>
+        <shape
+            android:tint="?android:attr/colorForeground">
+            <corners
+                android:radius="20dp"/>
+            <solid
+                android:color="@android:color/transparent"/>
+            <stroke
+                android:color="#1f000000"
+                android:width="1dp"/>
+            <size
+                android:height="32dp"/>
+        </shape>
+    </item>
+
+    <item
+        android:gravity="center|end"
+        android:width="24dp"
+        android:height="24dp"
+        android:end="4dp"
+        android:drawable="@drawable/arrow_drop_down_24dp"/>
+</layer-list>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml
new file mode 100644
index 0000000..bdd370f
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/layout/settings_spinner_view.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2018 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    style="@style/SettingsSpinnerTitleBar"
+    android:maxLines="1"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:ellipsize="marquee"/>
diff --git a/packages/SettingsLib/SettingsSpinner/res/values/styles.xml b/packages/SettingsLib/SettingsSpinner/res/values/styles.xml
new file mode 100644
index 0000000..8447b08
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/res/values/styles.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2018 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <style name="SettingsSpinnerTitleBar">
+        <item name="android:textAppearance">?android:attr/textAppearance</item>
+        <item name="android:paddingStart">16dp</item>
+        <item name="android:paddingEnd">36dp</item>
+        <item name="android:paddingTop">8dp</item>
+        <item name="android:paddingBottom">8dp</item>
+    </style>
+</resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
new file mode 100644
index 0000000..130cef2
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinner.java
@@ -0,0 +1,122 @@
+/*
+ * 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.widget.settingsspinner;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Spinner;
+
+/**
+ * A {@link Spinner} with settings style.
+ *
+ * The items in the SettingsSpinner come from the {@link SettingsSpinnerAdapter} associated with
+ * this view.
+ */
+public class SettingsSpinner extends Spinner {
+
+    /**
+     * Constructs a new SettingsSpinner with the given context's theme.
+     * And it also set a background resource with settings style.
+     *
+     * @param context The Context the view is running in, through which it can
+     *                access the current theme, resources, etc.
+     */
+    public SettingsSpinner(Context context) {
+        super(context);
+        setBackgroundResource(R.drawable.settings_spinner_background);
+    }
+
+    /**
+     * Constructs a new SettingsSpinner with the given context's theme and the supplied
+     * mode of displaying choices. <code>mode</code> may be one of
+     * {@link Spinner#MODE_DIALOG} or {@link Spinner#MODE_DROPDOWN}.
+     * And it also set a background resource with settings style.
+     *
+     * @param context The Context the view is running in, through which it can
+     *                access the current theme, resources, etc.
+     * @param mode Constant describing how the user will select choices from
+     *             the spinner.
+     *
+     * @see Spinner#MODE_DIALOG
+     * @see Spinner#MODE_DROPDOWN
+     */
+    public SettingsSpinner(Context context, int mode) {
+        super(context, mode);
+        setBackgroundResource(R.drawable.settings_spinner_background);
+    }
+
+    /**
+     * Constructs a new SettingsSpinner with the given context's theme and the supplied
+     * attribute set.
+     * And it also set a background resource with settings style.
+     *
+     * @param context The Context the view is running in, through which it can
+     *                access the current theme, resources, etc.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     */
+    public SettingsSpinner(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setBackgroundResource(R.drawable.settings_spinner_background);
+    }
+
+    /**
+     * Constructs a new SettingsSpinner with the given context's theme, the supplied
+     * attribute set, and default style attribute.
+     * And it also set a background resource with settings style.
+     *
+     * @param context The Context the view is running in, through which it can
+     *                access the current theme, resources, etc.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *                     reference to a style resource that supplies default
+     *                     values for the view. Can be 0 to not look for
+     *                     defaults.
+     */
+    public SettingsSpinner(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        setBackgroundResource(R.drawable.settings_spinner_background);
+    }
+
+    /**
+     * Constructs a new SettingsSpinner with the given context's theme, the supplied
+     * attribute set, and default styles. <code>mode</code> may be one of
+     * {@link Spinner#MODE_DIALOG} or {@link Spinner#MODE_DROPDOWN} and determines how the
+     * user will select choices from the spinner.
+     * And it also set a background resource with settings style.
+     *
+     * @param context The Context the view is running in, through which it can
+     *                access the current theme, resources, etc.
+     * @param attrs The attributes of the XML tag that is inflating the view.
+     * @param defStyleAttr An attribute in the current theme that contains a
+     *                     reference to a style resource that supplies default
+     *                     values for the view. Can be 0 to not look for
+     *                     defaults.
+     * @param defStyleRes A resource identifier of a style resource that
+     *                    supplies default values for the view, used only if
+     *                    defStyleAttr is 0 or can not be found in the theme.
+     *                    Can be 0 to not look for defaults.
+     * @param mode Constant describing how the user will select choices from
+     *             the spinner.
+     *
+     * @see Spinner#MODE_DIALOG
+     * @see Spinner#MODE_DROPDOWN
+     */
+    public SettingsSpinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes,
+            int mode) {
+        super(context, attrs, defStyleAttr, defStyleRes, mode, null);
+    }
+}
\ No newline at end of file
diff --git a/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java
new file mode 100644
index 0000000..8bf8fce
--- /dev/null
+++ b/packages/SettingsLib/SettingsSpinner/src/com/android/settingslib/widget/settingsspinner/SettingsSpinnerAdapter.java
@@ -0,0 +1,40 @@
+/*
+ * 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.widget.settingsspinner;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+
+/**
+ * An ArrayAdapter which was used by {@link SettingsSpinner} with settings style.
+ */
+public class SettingsSpinnerAdapter<T> extends ArrayAdapter<T> {
+
+    /**
+     * Constructs a new SettingsSpinnerAdapter with the given context.
+     * And it customizes title bar with a settings style.
+     *
+     * @param context The Context the view is running in, through which it can
+     *                access the current theme, resources, etc.
+     */
+    public SettingsSpinnerAdapter(Context context) {
+        super(context, R.layout.settings_spinner_view);
+        setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+    }
+}
diff --git a/packages/SettingsLib/res/layout/restricted_switch_widget.xml b/packages/SettingsLib/res/layout/restricted_switch_widget.xml
index e1f6cdf..5dbcb79 100644
--- a/packages/SettingsLib/res/layout/restricted_switch_widget.xml
+++ b/packages/SettingsLib/res/layout/restricted_switch_widget.xml
@@ -16,8 +16,8 @@
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
     <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/restricted_icon"
-        android:layout_width="@*android:dimen/config_restricted_icon_size"
-        android:layout_height="@*android:dimen/config_restricted_icon_size"
+        android:layout_width="@*android:dimen/config_restrictedIconSize"
+        android:layout_height="@*android:dimen/config_restrictedIconSize"
         android:tint="?android:attr/colorAccent"
         android:src="@*android:drawable/ic_info"
         android:gravity="end|center_vertical" />
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
index c03ba9a..1457fcf 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtilsInternal.java
@@ -58,7 +58,7 @@
     public static Drawable getRestrictedPadlock(Context context) {
         Drawable restrictedPadlock = context.getDrawable(android.R.drawable.ic_info);
         final int iconSize = context.getResources().getDimensionPixelSize(
-                android.R.dimen.config_restricted_icon_size);
+                android.R.dimen.config_restrictedIconSize);
 
         TypedArray ta = context.obtainStyledAttributes(new int[]{android.R.attr.colorAccent});
         int colorAccent = ta.getColor(0, 0);
@@ -164,6 +164,17 @@
     }
 
     /**
+     * @return the UserHandle for a userId. Return null for USER_NULL
+     */
+    private static UserHandle getUserHandleOf(@UserIdInt int userId) {
+        if (userId == UserHandle.USER_NULL) {
+            return null;
+        } else {
+            return UserHandle.of(userId);
+        }
+    }
+
+    /**
      * Filter a set of device admins based on a predicate {@code check}. This is equivalent to
      * {@code admins.stream().filter(check).map(x → new EnforcedAdmin(admin, userId)} except it's
      * returning a zero/one/many-type thing.
@@ -183,11 +194,13 @@
         if (admins == null) {
             return null;
         }
+
+        final UserHandle user = getUserHandleOf(userId);
         EnforcedAdmin enforcedAdmin = null;
         for (ComponentName admin : admins) {
             if (check.isEnforcing(dpm, admin, userId)) {
                 if (enforcedAdmin == null) {
-                    enforcedAdmin = new EnforcedAdmin(admin, userId);
+                    enforcedAdmin = new EnforcedAdmin(admin, user);
                 } else {
                     return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
                 }
@@ -211,7 +224,7 @@
         IPackageManager ipm = AppGlobals.getPackageManager();
         try {
             if (ipm.getBlockUninstallForUser(packageName, userId)) {
-                return getProfileOrDeviceOwner(context, userId);
+                return getProfileOrDeviceOwner(context, getUserHandleOf(userId));
             }
         } catch (RemoteException e) {
             // Nothing to do
@@ -230,7 +243,7 @@
         IPackageManager ipm = AppGlobals.getPackageManager();
         try {
             if (ipm.isPackageSuspendedForUser(packageName, userId)) {
-                return getProfileOrDeviceOwner(context, userId);
+                return getProfileOrDeviceOwner(context, getUserHandleOf(userId));
             }
         } catch (RemoteException | IllegalArgumentException e) {
             // Nothing to do
@@ -245,14 +258,15 @@
         if (dpm == null) {
             return null;
         }
-        EnforcedAdmin admin = getProfileOrDeviceOwner(context, userId);
+        EnforcedAdmin admin = getProfileOrDeviceOwner(context, getUserHandleOf(userId));
         boolean permitted = true;
         if (admin != null) {
             permitted = dpm.isInputMethodPermittedByAdmin(admin.component,
                     packageName, userId);
         }
         int managedProfileId = getManagedProfileId(context, userId);
-        EnforcedAdmin profileAdmin = getProfileOrDeviceOwner(context, managedProfileId);
+        EnforcedAdmin profileAdmin = getProfileOrDeviceOwner(context,
+                getUserHandleOf(managedProfileId));
         boolean permittedByProfileAdmin = true;
         if (profileAdmin != null) {
             permittedByProfileAdmin = dpm.isInputMethodPermittedByAdmin(profileAdmin.component,
@@ -298,14 +312,15 @@
         if (dpm == null) {
             return null;
         }
-        EnforcedAdmin admin = getProfileOrDeviceOwner(context, userId);
+        EnforcedAdmin admin = getProfileOrDeviceOwner(context, getUserHandleOf(userId));
         boolean permitted = true;
         if (admin != null) {
             permitted = dpm.isAccessibilityServicePermittedByAdmin(admin.component,
                     packageName, userId);
         }
         int managedProfileId = getManagedProfileId(context, userId);
-        EnforcedAdmin profileAdmin = getProfileOrDeviceOwner(context, managedProfileId);
+        EnforcedAdmin profileAdmin = getProfileOrDeviceOwner(context,
+                getUserHandleOf(managedProfileId));
         boolean permittedByProfileAdmin = true;
         if (profileAdmin != null) {
             permittedByProfileAdmin = dpm.isAccessibilityServicePermittedByAdmin(
@@ -365,7 +380,7 @@
         if (!isAccountTypeDisabled) {
             return null;
         }
-        return getProfileOrDeviceOwner(context, userId);
+        return getProfileOrDeviceOwner(context, getUserHandleOf(userId));
     }
 
     /**
@@ -377,7 +392,8 @@
      */
     public static EnforcedAdmin checkIfMeteredDataRestricted(Context context,
             String packageName, int userId) {
-        final EnforcedAdmin enforcedAdmin = getProfileOrDeviceOwner(context, userId);
+        final EnforcedAdmin enforcedAdmin = getProfileOrDeviceOwner(context,
+                getUserHandleOf(userId));
         if (enforcedAdmin == null) {
             return null;
         }
@@ -402,7 +418,7 @@
             return null;
         }
         ComponentName adminComponent = dpm.getDeviceOwnerComponentOnCallingUser();
-        return new EnforcedAdmin(adminComponent, UserHandle.myUserId());
+        return new EnforcedAdmin(adminComponent, getUserHandleOf(UserHandle.myUserId()));
     }
 
     /**
@@ -434,10 +450,11 @@
                 return null;
             }
             EnforcedAdmin enforcedAdmin = null;
+            final UserHandle user = getUserHandleOf(userId);
             for (ComponentName admin : admins) {
                 if (check.isEnforcing(dpm, admin, userId)) {
                     if (enforcedAdmin == null) {
-                        enforcedAdmin = new EnforcedAdmin(admin, userId);
+                        enforcedAdmin = new EnforcedAdmin(admin, user);
                     } else {
                         return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
                     }
@@ -488,13 +505,14 @@
             if (admins == null) {
                 continue;
             }
+            final UserHandle user = getUserHandleOf(userInfo.id);
             final boolean isSeparateProfileChallengeEnabled =
                     sProxy.isSeparateProfileChallengeEnabled(lockPatternUtils, userInfo.id);
             for (ComponentName admin : admins) {
                 if (!isSeparateProfileChallengeEnabled) {
                     if (check.isEnforcing(dpm, admin, userInfo.id)) {
                         if (enforcedAdmin == null) {
-                            enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
+                            enforcedAdmin = new EnforcedAdmin(admin, user);
                         } else {
                             return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
                         }
@@ -511,7 +529,7 @@
                     DevicePolicyManager parentDpm = sProxy.getParentProfileInstance(dpm, userInfo);
                     if (check.isEnforcing(parentDpm, admin, userInfo.id)) {
                         if (enforcedAdmin == null) {
-                            enforcedAdmin = new EnforcedAdmin(admin, userInfo.id);
+                            enforcedAdmin = new EnforcedAdmin(admin, user);
                         } else {
                             return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
                         }
@@ -535,7 +553,7 @@
         ComponentName adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
         if (adminComponent != null) {
             return new EnforcedAdmin(
-                    adminComponent, enforcedRestriction, dpm.getDeviceOwnerUserId());
+                    adminComponent, enforcedRestriction, dpm.getDeviceOwnerUser());
         }
         return null;
     }
@@ -556,7 +574,7 @@
         }
         ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId);
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
+            return new EnforcedAdmin(adminComponent, enforcedRestriction, getUserHandleOf(userId));
         }
         return null;
     }
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java b/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
index 3102239..3c45112 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/DefaultAppInfo.java
@@ -25,7 +25,6 @@
 import android.content.pm.PackageManager;
 import android.graphics.drawable.Drawable;
 import android.os.RemoteException;
-import android.os.UserHandle;
 import android.util.IconDrawableFactory;
 
 import com.android.settingslib.widget.CandidateInfo;
@@ -46,8 +45,8 @@
         this(context, pm, uid, cn, null /* summary */, true /* enabled */);
     }
 
-    public DefaultAppInfo(Context context, PackageManager pm, PackageItemInfo info) {
-        this(context, pm, info, null /* summary */, true /* enabled */);
+    public DefaultAppInfo(Context context, PackageManager pm, int uid, PackageItemInfo info) {
+        this(context, pm, uid, info, null /* summary */, true /* enabled */);
     }
 
     public DefaultAppInfo(Context context, PackageManager pm, int uid, ComponentName cn,
@@ -61,12 +60,12 @@
         this.summary = summary;
     }
 
-    public DefaultAppInfo(Context context, PackageManager pm, PackageItemInfo info,
+    public DefaultAppInfo(Context context, PackageManager pm, int uid, PackageItemInfo info,
                           String summary, boolean enabled) {
         super(enabled);
         mContext = context;
         mPm = pm;
-        userId = UserHandle.myUserId();
+        userId = uid;
         packageItemInfo = info;
         componentName = null;
         this.summary = summary;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 4aca2bb..7124096 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -267,8 +267,10 @@
                 cachedDevice = mDeviceManager.addDevice(device);
                 Log.d(TAG, "DeviceFoundHandler created new CachedBluetoothDevice: "
                         + cachedDevice);
-            } else if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
-                // Dispatch device add callback to show bonded BT device in discovery mode
+            } else if (cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED
+                    &&!cachedDevice.getDevice().isConnected()) {
+                // Dispatch device add callback to show bonded but
+                // not connected devices in discovery mode
                 dispatchDeviceAdded(cachedDevice);
             }
             cachedDevice.setRssi(rssi);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 750a843..a2e30df 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -60,11 +60,11 @@
     private short mRssi;
 
     private final List<LocalBluetoothProfile> mProfiles =
-            new ArrayList<LocalBluetoothProfile>();
+            Collections.synchronizedList(new ArrayList<>());
 
     // List of profiles that were previously in mProfiles, but have been removed
     private final List<LocalBluetoothProfile> mRemovedProfiles =
-            new ArrayList<LocalBluetoothProfile>();
+            Collections.synchronizedList(new ArrayList<>());
 
     // Device supports PANU but not NAP: remove PanProfile after device disconnects from NAP
     private boolean mLocalNapRoleConnected;
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
index 78963f3..027ca09 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/EventLogWriter.java
@@ -102,8 +102,4 @@
     public void count(Context context, String name, int value) {
         MetricsLogger.count(context, name, value);
     }
-
-    public void histogram(Context context, String name, int bucket) {
-        MetricsLogger.histogram(context, name, bucket);
-    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
index 4b9f572..379a820 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/LogWriter.java
@@ -76,9 +76,4 @@
      * Logs a count.
      */
     void count(Context context, String name, int value);
-
-    /**
-     * Logs a histogram event.
-     */
-    void histogram(Context context, String name, int bucket);
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
index 1e5b378..662fa10 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/MetricsFeatureProvider.java
@@ -59,44 +59,18 @@
         }
     }
 
-    /**
-     * Logs a user action. Includes the elapsed time since the containing
-     * fragment has been visible.
-     */
-    public void action(VisibilityLoggerMixin visibilityLogger, int category, int value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(category, value,
-                    sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible()));
-        }
-    }
-
-    /**
-     * Logs a user action. Includes the elapsed time since the containing
-     * fragment has been visible.
-     */
-    public void action(VisibilityLoggerMixin visibilityLogger, int category, boolean value) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.action(category, value,
-                    sinceVisibleTaggedData(visibilityLogger.elapsedTimeSinceVisible()));
-        }
-    }
-
     public void action(Context context, int category, Pair<Integer, Object>... taggedData) {
         for (LogWriter writer : mLoggerWriters) {
             writer.action(context, category, taggedData);
         }
     }
 
-    /** @deprecated use {@link #action(VisibilityLoggerMixin, int, int)} */
-    @Deprecated
     public void action(Context context, int category, int value) {
         for (LogWriter writer : mLoggerWriters) {
             writer.action(context, category, value);
         }
     }
 
-    /** @deprecated use {@link #action(VisibilityLoggerMixin, int, boolean)} */
-    @Deprecated
     public void action(Context context, int category, boolean value) {
         for (LogWriter writer : mLoggerWriters) {
             writer.action(context, category, value);
@@ -116,12 +90,6 @@
         }
     }
 
-    public void histogram(Context context, String name, int bucket) {
-        for (LogWriter writer : mLoggerWriters) {
-            writer.histogram(context, name, bucket);
-        }
-    }
-
     public int getMetricsCategory(Object object) {
         if (object == null || !(object instanceof Instrumentable)) {
             return MetricsEvent.VIEW_UNKNOWN;
@@ -153,7 +121,4 @@
                 Pair.create(MetricsEvent.FIELD_CONTEXT, sourceMetricsCategory));
     }
 
-    private Pair<Integer, Object> sinceVisibleTaggedData(long timestamp) {
-        return Pair.create(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS, timestamp);
-    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
index eeaa987..183d485 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/DataUsageController.java
@@ -24,6 +24,8 @@
 import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
 import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
 
+import android.app.usage.NetworkStats.Bucket;
+import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.INetworkStatsService;
@@ -37,6 +39,7 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
+import android.util.FeatureFlagUtils;
 import android.util.Log;
 import android.util.Range;
 
@@ -51,6 +54,8 @@
 public class DataUsageController {
 
     private static final String TAG = "DataUsageController";
+    @VisibleForTesting
+    static final String DATA_USAGE_V2 = "settings_data_usage_v2";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
     private static final int FIELDS = FIELD_RX_BYTES | FIELD_TX_BYTES;
     private static final StringBuilder PERIOD_BUILDER = new StringBuilder(50);
@@ -62,6 +67,7 @@
     private final ConnectivityManager mConnectivityManager;
     private final INetworkStatsService mStatsService;
     private final NetworkPolicyManager mPolicyManager;
+    private final NetworkStatsManager mNetworkStatsManager;
 
     private INetworkStatsSession mSession;
     private Callback mCallback;
@@ -74,6 +80,7 @@
         mStatsService = INetworkStatsService.Stub.asInterface(
                 ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
         mPolicyManager = NetworkPolicyManager.from(mContext);
+        mNetworkStatsManager = context.getSystemService(NetworkStatsManager.class);
     }
 
     public void setNetworkController(NetworkNameProvider networkController) {
@@ -89,6 +96,7 @@
     }
 
     @VisibleForTesting
+    @Deprecated
     INetworkStatsSession getSession() {
         if (mSession == null) {
             try {
@@ -128,71 +136,72 @@
     }
 
     public DataUsageInfo getDataUsageInfo(NetworkTemplate template) {
-        final INetworkStatsSession session = getSession();
-        if (session == null) {
-            return warn("no stats session");
-        }
         final NetworkPolicy policy = findNetworkPolicy(template);
-        try {
-            final NetworkStatsHistory history = session.getHistoryForNetwork(template, FIELDS);
-            final long now = System.currentTimeMillis();
-            final long start, end;
-            final Iterator<Range<ZonedDateTime>> it =
-                    (policy != null) ? policy.cycleIterator() : null;
-            if (it != null && it.hasNext()) {
-                final Range<ZonedDateTime> cycle = it.next();
-                start = cycle.getLower().toInstant().toEpochMilli();
-                end = cycle.getUpper().toInstant().toEpochMilli();
-            } else {
-                // period = last 4 wks
-                end = now;
-                start = now - DateUtils.WEEK_IN_MILLIS * 4;
-            }
-            final long callStart = System.currentTimeMillis();
-            final NetworkStatsHistory.Entry entry = history.getValues(start, end, now, null);
-            final long callEnd = System.currentTimeMillis();
-            if (DEBUG) Log.d(TAG, String.format("history call from %s to %s now=%s took %sms: %s",
-                    new Date(start), new Date(end), new Date(now), callEnd - callStart,
-                    historyEntryToString(entry)));
-            if (entry == null) {
-                return warn("no entry data");
-            }
-            final long totalBytes = entry.rxBytes + entry.txBytes;
-            final DataUsageInfo usage = new DataUsageInfo();
-            usage.startDate = start;
-            usage.usageLevel = totalBytes;
-            usage.period = formatDateRange(start, end);
-            usage.cycleStart = start;
-            usage.cycleEnd = end;
-
-            if (policy != null) {
-                usage.limitLevel = policy.limitBytes > 0 ? policy.limitBytes : 0;
-                usage.warningLevel = policy.warningBytes > 0 ? policy.warningBytes : 0;
-            } else {
-                usage.warningLevel = getDefaultWarningLevel();
-            }
-            if (usage != null && mNetworkController != null) {
-                usage.carrier = mNetworkController.getMobileDataNetworkName();
-            }
-            return usage;
-        } catch (RemoteException e) {
-            return warn("remote call failed");
+        final long now = System.currentTimeMillis();
+        final long start, end;
+        final Iterator<Range<ZonedDateTime>> it = (policy != null) ? policy.cycleIterator() : null;
+        if (it != null && it.hasNext()) {
+            final Range<ZonedDateTime> cycle = it.next();
+            start = cycle.getLower().toInstant().toEpochMilli();
+            end = cycle.getUpper().toInstant().toEpochMilli();
+        } else {
+            // period = last 4 wks
+            end = now;
+            start = now - DateUtils.WEEK_IN_MILLIS * 4;
         }
+        final long totalBytes;
+        final long callStart = System.currentTimeMillis();
+        if (FeatureFlagUtils.isEnabled(mContext, DATA_USAGE_V2)) {
+            totalBytes = getUsageLevel(template, start, end);
+        } else {
+            totalBytes = getUsageLevel(template, start, end, now);
+        }
+        if (totalBytes < 0L) {
+            return warn("no entry data");
+        }
+        final DataUsageInfo usage = new DataUsageInfo();
+        usage.startDate = start;
+        usage.usageLevel = totalBytes;
+        usage.period = formatDateRange(start, end);
+        usage.cycleStart = start;
+        usage.cycleEnd = end;
+
+        if (policy != null) {
+            usage.limitLevel = policy.limitBytes > 0 ? policy.limitBytes : 0;
+            usage.warningLevel = policy.warningBytes > 0 ? policy.warningBytes : 0;
+        } else {
+            usage.warningLevel = getDefaultWarningLevel();
+        }
+        if (usage != null && mNetworkController != null) {
+            usage.carrier = mNetworkController.getMobileDataNetworkName();
+        }
+        return usage;
     }
 
     /**
      * Get the total usage level recorded in the network history
      * @param template the network template to retrieve the network history
-     * @return the total usage level recorded in the network history
+     * @return the total usage level recorded in the network history or -1L if there is error
+     * retrieving the data.
      */
-    public long getHistoriclUsageLevel(NetworkTemplate template) {
+    public long getHistoricalUsageLevel(NetworkTemplate template) {
+        if (FeatureFlagUtils.isEnabled(mContext, DATA_USAGE_V2)) {
+            return getUsageLevel(template, 0L /* start */, System.currentTimeMillis() /* end */);
+        } else {
+            final long now = System.currentTimeMillis();
+            return getUsageLevel(template, 0L /* start */, now /* end */, now);
+        }
+    }
+
+    @Deprecated
+    private long getUsageLevel(NetworkTemplate template, long start, long end, long now) {
         final INetworkStatsSession session = getSession();
         if (session != null) {
             try {
-                final NetworkStatsHistory history = session.getHistoryForNetwork(template, FIELDS);
-                final long now = System.currentTimeMillis();
-                final NetworkStatsHistory.Entry entry =
-                        history.getValues(0L /* start */, now /* end */, now, null /* recycle */);
+                final NetworkStatsHistory history =
+                    session.getHistoryForNetwork(template, FIELDS);
+                final NetworkStatsHistory.Entry entry = history.getValues(
+                        start, end, System.currentTimeMillis() /* now */, null /* recycle */);
                 if (entry != null) {
                     return entry.rxBytes + entry.txBytes;
                 }
@@ -201,7 +210,21 @@
                 Log.w(TAG, "Failed to get data usage, remote call failed");
             }
         }
-        return 0L;
+        return -1L;
+    }
+
+    private long getUsageLevel(NetworkTemplate template, long start, long end) {
+        try {
+            final Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
+                getNetworkType(template), getActiveSubscriberId(mContext), start, end);
+            if (bucket != null) {
+                return bucket.getRxBytes() + bucket.getTxBytes();
+            }
+            Log.w(TAG, "Failed to get data usage, no entry data");
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to get data usage, remote call failed");
+        }
+        return -1L;
     }
 
     private NetworkPolicy findNetworkPolicy(NetworkTemplate template) {
@@ -218,6 +241,7 @@
         return null;
     }
 
+    @Deprecated
     private static String historyEntryToString(NetworkStatsHistory.Entry entry) {
         return entry == null ? null : new StringBuilder("Entry[")
                 .append("bucketDuration=").append(entry.bucketDuration)
@@ -231,6 +255,17 @@
                 .append(']').toString();
     }
 
+    private static String statsBucketToString(Bucket bucket) {
+        return bucket == null ? null : new StringBuilder("Entry[")
+            .append("bucketDuration=").append(bucket.getEndTimeStamp() - bucket.getStartTimeStamp())
+            .append(",bucketStart=").append(bucket.getStartTimeStamp())
+            .append(",rxBytes=").append(bucket.getRxBytes())
+            .append(",rxPackets=").append(bucket.getRxPackets())
+            .append(",txBytes=").append(bucket.getTxBytes())
+            .append(",txPackets=").append(bucket.getTxPackets())
+            .append(']').toString();
+    }
+
     public void setMobileDataEnabled(boolean enabled) {
         Log.d(TAG, "setMobileDataEnabled: enabled=" + enabled);
         mTelephonyManager.setDataEnabled(enabled);
@@ -249,6 +284,25 @@
         return mTelephonyManager.getDataEnabled();
     }
 
+    static int getNetworkType(NetworkTemplate networkTemplate) {
+        if (networkTemplate == null) {
+            return ConnectivityManager.TYPE_NONE;
+        }
+        final int matchRule = networkTemplate.getMatchRule();
+        switch (matchRule) {
+            case NetworkTemplate.MATCH_MOBILE:
+            case NetworkTemplate.MATCH_MOBILE_WILDCARD:
+                return ConnectivityManager.TYPE_MOBILE;
+            case NetworkTemplate.MATCH_WIFI:
+            case NetworkTemplate.MATCH_WIFI_WILDCARD:
+                return  ConnectivityManager.TYPE_WIFI;
+            case NetworkTemplate.MATCH_ETHERNET:
+                return  ConnectivityManager.TYPE_ETHERNET;
+            default:
+                return ConnectivityManager.TYPE_MOBILE;
+        }
+    }
+
     private static String getActiveSubscriberId(Context context) {
         final TelephonyManager tele = TelephonyManager.from(context);
         final String actualSubscriberId = tele.getSubscriberId(
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java
index 7ae3398..ec5a0b5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleChartDataLoader.java
@@ -43,9 +43,9 @@
     @Override
     void recordUsage(long start, long end) {
         try {
-            final NetworkStats stats = mNetworkStatsManager.querySummary(
+            final NetworkStats.Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
                 mNetworkType, mSubId, start, end);
-            final long total = getTotalUsage(stats);
+            final long total = bucket == null ? 0L : bucket.getRxBytes() + bucket.getTxBytes();
             if (total > 0L) {
                 final NetworkCycleChartData.Builder builder = new NetworkCycleChartData.Builder();
                 builder.setUsageBuckets(getUsageBuckets(start, end))
@@ -80,9 +80,11 @@
         while (bucketEnd <= end) {
             long usage = 0L;
             try {
-                final NetworkStats stats = mNetworkStatsManager.querySummary(
+                final NetworkStats.Bucket bucket = mNetworkStatsManager.querySummaryForDevice(
                     mNetworkType, mSubId, bucketStart, bucketEnd);
-                usage = getTotalUsage(stats);
+                if (bucket != null) {
+                    usage = bucket.getRxBytes() + bucket.getTxBytes();
+                }
             } catch (RemoteException e) {
                 Log.e(TAG, "Exception querying network detail.", e);
             }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
index 95efb4c..cc970b9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataForUidLoader.java
@@ -36,10 +36,12 @@
 
     private final List<NetworkCycleDataForUid> mData;
     private final int mUid;
+    private final boolean mRetrieveDetail;
 
     private NetworkCycleDataForUidLoader(Builder builder) {
         super(builder);
         mUid = builder.mUid;
+        mRetrieveDetail = builder.mRetrieveDetail;
         mData = new ArrayList<NetworkCycleDataForUid>();
     }
 
@@ -50,13 +52,15 @@
                 mNetworkType, mSubId, start, end, mUid);
             final long total = getTotalUsage(stats);
             if (total > 0L) {
-                final long foreground = getForegroundUsage(start, end);
                 final NetworkCycleDataForUid.Builder builder = new NetworkCycleDataForUid.Builder();
-                builder.setBackgroundUsage(total - foreground)
-                    .setForegroundUsage(foreground)
-                    .setStartTime(start)
+                builder.setStartTime(start)
                     .setEndTime(end)
                     .setTotalUsage(total);
+                if (mRetrieveDetail) {
+                    final long foreground = getForegroundUsage(start, end);
+                    builder.setBackgroundUsage(total - foreground)
+                        .setForegroundUsage(foreground);
+                }
                 mData.add(builder.build());
             }
         } catch (Exception e) {
@@ -88,6 +92,7 @@
             extends NetworkCycleDataLoader.Builder<T> {
 
         private int mUid;
+        private boolean mRetrieveDetail = true;
 
         public Builder(Context context) {
             super(context);
@@ -97,6 +102,11 @@
             mUid = uid;
             return this;
         }
+
+        public Builder<T> setRetrieveDetail(boolean retrieveDetail) {
+            mRetrieveDetail = retrieveDetail;
+            return this;
+        }
     }
 
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
index cc936d2..d957801 100644
--- a/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
+++ b/packages/SettingsLib/src/com/android/settingslib/net/NetworkCycleDataLoader.java
@@ -22,6 +22,7 @@
 import android.app.usage.NetworkStats;
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
 import android.net.NetworkPolicy;
@@ -34,6 +35,8 @@
 import android.text.format.DateUtils;
 import android.util.Pair;
 
+import com.android.settingslib.NetworkPolicyEditor;
+
 import java.time.ZonedDateTime;
 import java.util.Iterator;
 
@@ -55,7 +58,6 @@
 
     protected NetworkCycleDataLoader(Builder<?> builder) {
         super(builder.mContext);
-        mPolicy = builder.mPolicy;
         mSubId = builder.mSubId;
         mNetworkType = builder.mNetworkType;
         mNetworkTemplate = builder.mNetworkTemplate;
@@ -63,6 +65,10 @@
             builder.mContext.getSystemService(Context.NETWORK_STATS_SERVICE);
         mNetworkStatsService = INetworkStatsService.Stub.asInterface(
             ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
+        final NetworkPolicyEditor policyEditor =
+            new NetworkPolicyEditor(NetworkPolicyManager.from(builder.mContext));
+        policyEditor.read();
+        mPolicy = policyEditor.getPolicy(mNetworkTemplate);
     }
 
     @Override
@@ -115,7 +121,8 @@
 
             long cycleEnd = historyEnd;
             while (cycleEnd > historyStart) {
-                final long cycleStart = cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4);
+                final long cycleStart = Math.max(
+                    historyStart, cycleEnd - (DateUtils.WEEK_IN_MILLIS * 4));
                 recordUsage(cycleStart, cycleEnd);
                 cycleEnd = cycleStart;
             }
@@ -154,7 +161,6 @@
 
     public static abstract class Builder<T extends NetworkCycleDataLoader> {
         private final Context mContext;
-        private NetworkPolicy mPolicy;
         private String mSubId;
         private int mNetworkType;
         private NetworkTemplate mNetworkTemplate;
@@ -163,23 +169,14 @@
             mContext = context;
         }
 
-        public Builder<T> setNetworkPolicy(NetworkPolicy policy) {
-            mPolicy = policy;
-            return this;
-        }
-
         public Builder<T> setSubscriberId(String subId) {
             mSubId = subId;
             return this;
         }
 
-        public Builder<T> setNetworkType(int networkType) {
-            mNetworkType = networkType;
-            return this;
-        }
-
         public Builder<T> setNetworkTemplate(NetworkTemplate template) {
             mNetworkTemplate = template;
+            mNetworkType = DataUsageController.getNetworkType(template);
             return this;
         }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
index 1091e16..36b70df 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/HelpUtilsTest.java
@@ -70,17 +70,17 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        when(mContext.getResources().getString(R.string.config_help_package_name_key))
+        when(mContext.getResources().getString(R.string.config_helpPackageNameKey))
                 .thenReturn(PACKAGE_NAME_KEY);
-        when(mContext.getResources().getString(R.string.config_help_package_name_value))
+        when(mContext.getResources().getString(R.string.config_helpPackageNameValue))
                 .thenReturn(PACKAGE_NAME_VALUE);
-        when(mContext.getResources().getString(R.string.config_help_intent_extra_key))
+        when(mContext.getResources().getString(R.string.config_helpIntentExtraKey))
                 .thenReturn(HELP_INTENT_EXTRA_KEY);
-        when(mContext.getResources().getString(R.string.config_help_intent_name_key))
+        when(mContext.getResources().getString(R.string.config_helpIntentNameKey))
                 .thenReturn(HELP_INTENT_NAME_KEY);
-        when(mContext.getResources().getString(R.string.config_feedback_intent_extra_key))
+        when(mContext.getResources().getString(R.string.config_feedbackIntentExtraKey))
                 .thenReturn(FEEDBACK_INTENT_EXTRA_KEY);
-        when(mContext.getResources().getString(R.string.config_feedback_intent_name_key))
+        when(mContext.getResources().getString(R.string.config_feedbackIntentNameKey))
                 .thenReturn(FEEDBACK_INTENT_NAME_KEY);
         when(mActivity.getPackageManager()).thenReturn(mPackageManager);
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index fc8d9db..88ac8ce 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -156,7 +156,7 @@
         final EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
                 .checkIfKeyguardFeaturesDisabled(mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId);
 
-        assertThat(enforcedAdmin).isEqualTo(new EnforcedAdmin(mAdmin1, mUserId));
+        assertThat(enforcedAdmin).isEqualTo(new EnforcedAdmin(mAdmin1, UserHandle.of(mUserId)));
     }
 
     @Test
@@ -189,12 +189,12 @@
         // Querying the parent should return the policy, since it affects the parent.
         EnforcedAdmin parent = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId);
-        assertThat(parent).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId));
+        assertThat(parent).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
 
         // Querying the child should return that too.
         EnforcedAdmin profile = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mProfileId);
-        assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId));
+        assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
 
         // Querying for some unrelated feature should return nothing. Nothing!
         assertThat(RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
@@ -224,7 +224,7 @@
         // Querying the child should still return the policy.
         EnforcedAdmin profile = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
                 mContext, KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS, mProfileId);
-        assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId));
+        assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
     }
 
     @Test
@@ -251,7 +251,7 @@
         // Querying the child should still return the policy.
         EnforcedAdmin profile = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mProfileId);
-        assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId));
+        assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
     }
 
     /**
@@ -278,7 +278,7 @@
         // Parent should get the policy.
         EnforcedAdmin parent = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId);
-        assertThat(parent).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId));
+        assertThat(parent).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
 
         // Profile should not get the policy.
         EnforcedAdmin profile = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java
index 01f0d78..a92a2dd 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/applications/DefaultAppInfoTest.java
@@ -18,8 +18,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
@@ -72,7 +72,7 @@
     @Test
     public void initInfoWithActivityInfo_shouldLoadInfo() {
         mPackageItemInfo.packageName = "test";
-        mInfo = new DefaultAppInfo(mContext, mPackageManager, mPackageItemInfo);
+        mInfo = new DefaultAppInfo(mContext, mPackageManager, 0 /* uid */, mPackageItemInfo);
         mInfo.loadLabel();
         Drawable icon = mInfo.loadIcon();
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
index f4fd779..7a7f0d4 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/MetricsFeatureProviderTest.java
@@ -15,13 +15,10 @@
  */
 package com.android.settingslib.core.instrumentation;
 
-import static com.google.common.truth.Truth.assertThat;
-
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
 import android.content.Context;
@@ -34,8 +31,6 @@
 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.robolectric.RuntimeEnvironment;
@@ -46,30 +41,20 @@
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class MetricsFeatureProviderTest {
-    private static int CATEGORY = 10;
-    private static boolean SUBTYPE_BOOLEAN = true;
-    private static int SUBTYPE_INTEGER = 1;
-    private static long ELAPSED_TIME = 1000;
-
-    @Mock private LogWriter mockLogWriter;
-    @Mock private VisibilityLoggerMixin mockVisibilityLogger;
+    @Mock
+    private LogWriter mLogWriter;
 
     private Context mContext;
     private MetricsFeatureProvider mProvider;
 
-    @Captor
-    private ArgumentCaptor<Pair> mPairCaptor;
-
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
         mContext = RuntimeEnvironment.application;
         mProvider = new MetricsFeatureProvider();
         List<LogWriter> writers = new ArrayList<>();
-        writers.add(mockLogWriter);
+        writers.add(mLogWriter);
         ReflectionHelpers.setField(mProvider, "mLoggerWriters", writers);
-
-        when(mockVisibilityLogger.elapsedTimeSinceVisible()).thenReturn(ELAPSED_TIME);
     }
 
     @Test
@@ -77,7 +62,7 @@
         mProvider.logDashboardStartIntent(mContext, null /* intent */,
                 MetricsEvent.SETTINGS_GESTURES);
 
-        verifyNoMoreInteractions(mockLogWriter);
+        verifyNoMoreInteractions(mLogWriter);
     }
 
     @Test
@@ -86,7 +71,7 @@
 
         mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
 
-        verify(mockLogWriter).action(
+        verify(mLogWriter).action(
                 eq(mContext),
                 eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
                 anyString(),
@@ -99,32 +84,10 @@
 
         mProvider.logDashboardStartIntent(mContext, intent, MetricsEvent.SETTINGS_GESTURES);
 
-        verify(mockLogWriter).action(
+        verify(mLogWriter).action(
                 eq(mContext),
                 eq(MetricsEvent.ACTION_SETTINGS_TILE_CLICK),
                 anyString(),
                 eq(Pair.create(MetricsEvent.FIELD_CONTEXT, MetricsEvent.SETTINGS_GESTURES)));
     }
-
-    @Test
-    public void action_BooleanLogsElapsedTime() {
-        mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_BOOLEAN);
-        verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_BOOLEAN), mPairCaptor.capture());
-
-        Pair value = mPairCaptor.getValue();
-        assertThat(value.first instanceof Integer).isTrue();
-        assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS);
-        assertThat(value.second).isEqualTo(ELAPSED_TIME);
-    }
-
-    @Test
-    public void action_IntegerLogsElapsedTime() {
-        mProvider.action(mockVisibilityLogger, CATEGORY, SUBTYPE_INTEGER);
-        verify(mockLogWriter).action(eq(CATEGORY), eq(SUBTYPE_INTEGER), mPairCaptor.capture());
-
-        Pair value = mPairCaptor.getValue();
-        assertThat(value.first instanceof Integer).isTrue();
-        assertThat((int) value.first).isEqualTo(MetricsEvent.NOTIFICATION_SINCE_VISIBLE_MILLIS);
-        assertThat(value.second).isEqualTo(ELAPSED_TIME);
-    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
index 1be856a..b6ac467 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/DataUsageControllerTest.java
@@ -24,16 +24,23 @@
 import static org.mockito.Mockito.anyLong;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.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.usage.NetworkStats;
+import android.app.usage.NetworkStatsManager;
 import android.content.Context;
+import android.net.ConnectivityManager;
 import android.net.INetworkStatsSession;
 import android.net.NetworkStatsHistory;
 import android.net.NetworkStatsHistory.Entry;
 import android.net.NetworkTemplate;
 import android.os.RemoteException;
+import android.telephony.TelephonyManager;
 import android.text.format.DateUtils;
+import android.util.FeatureFlagUtils;
 
 import com.android.settingslib.SettingsLibRobolectricTestRunner;
 
@@ -47,8 +54,14 @@
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class DataUsageControllerTest {
 
+    private static final String SUB_ID = "Test Subscriber";
+
     @Mock
     private INetworkStatsSession mSession;
+    @Mock
+    private TelephonyManager mTelephonyManager;
+    @Mock
+    private NetworkStatsManager mNetworkStatsManager;
 
     private Context mContext;
     private DataUsageController mController;
@@ -63,13 +76,14 @@
                 new NetworkStatsHistory(DateUtils.DAY_IN_MILLIS /* bucketDuration */));
         doReturn(mNetworkStatsHistory)
                 .when(mSession).getHistoryForNetwork(any(NetworkTemplate.class), anyInt());
+        doReturn(SUB_ID).when(mTelephonyManager).getSubscriberId(anyInt());
     }
 
     @Test
-    public void getHistoriclUsageLevel_noNetworkSession_shouldReturn0() {
+    public void getHistoricalUsageLevel_noNetworkSession_shouldReturnNegative1() {
         doReturn(null).when(mController).getSession();
 
-        assertThat(mController.getHistoriclUsageLevel(null /* template */)).isEqualTo(0L);
+        assertThat(mController.getHistoricalUsageLevel(null /* template */)).isEqualTo(-1L);
 
     }
 
@@ -77,13 +91,13 @@
     public void getHistoriclUsageLevel_noUsageData_shouldReturn0() {
         doReturn(mSession).when(mController).getSession();
 
-        assertThat(mController.getHistoriclUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
                 .isEqualTo(0L);
 
     }
 
     @Test
-    public void getHistoriclUsageLevel_hasUsageData_shouldReturnTotalUsage() {
+    public void getHistoricalUsageLevel_hasUsageData_shouldReturnTotalUsage() {
         doReturn(mSession).when(mController).getSession();
         final long receivedBytes = 743823454L;
         final long transmittedBytes = 16574289L;
@@ -94,8 +108,57 @@
         when(mNetworkStatsHistory.getValues(eq(0L), anyLong(), anyLong(), nullable(Entry.class)))
                 .thenReturn(entry);
 
-        assertThat(mController.getHistoriclUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+        assertThat(mController.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
                 .isEqualTo(receivedBytes + transmittedBytes);
 
     }
+
+    @Test
+    public void getHistoricalUsageLevel_v2_shouldQuerySummaryForDevice() throws Exception {
+        final Context context = mock(Context.class);
+        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
+        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+        final DataUsageController controller = new DataUsageController(context);
+
+        controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard());
+
+        verify(mNetworkStatsManager).querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
+                eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */);
+    }
+
+    @Test
+    public void getHistoricalUsageLevel_v2NoUsageData_shouldReturn0() throws Exception {
+        final Context context = mock(Context.class);
+        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
+        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+        when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
+                eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */))
+                .thenReturn(mock(NetworkStats.Bucket.class));
+        final DataUsageController controller = new DataUsageController(context);
+
+        assertThat(controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+            .isEqualTo(0L);
+    }
+
+    @Test
+    public void getHistoricalUsageLevel_v2HasUsageData_shouldReturnTotalUsage()
+            throws Exception {
+        final Context context = mock(Context.class);
+        FeatureFlagUtils.setEnabled(context, DataUsageController.DATA_USAGE_V2, true);
+        when(context.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+        when(context.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+        final long receivedBytes = 743823454L;
+        final long transmittedBytes = 16574289L;
+        final NetworkStats.Bucket bucket = mock(NetworkStats.Bucket.class);
+        when(bucket.getRxBytes()).thenReturn(receivedBytes);
+        when(bucket.getTxBytes()).thenReturn(transmittedBytes);
+        when(mNetworkStatsManager.querySummaryForDevice(eq(ConnectivityManager.TYPE_WIFI),
+                eq(SUB_ID), eq(0L) /* startTime */, anyLong() /* endTime */)).thenReturn(bucket);
+        final DataUsageController controller = new DataUsageController(context);
+
+        assertThat(controller.getHistoricalUsageLevel(NetworkTemplate.buildTemplateWifiWildcard()))
+                .isEqualTo(receivedBytes + transmittedBytes);
+    }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
index 3dc110d..0a03631 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleChartDataLoaderTest.java
@@ -22,6 +22,8 @@
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
 import android.os.RemoteException;
 import android.text.format.DateUtils;
 
@@ -39,6 +41,8 @@
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
     @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
     private Context mContext;
 
     private NetworkCycleChartDataLoader mLoader;
@@ -48,19 +52,22 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.NETWORK_STATS_SERVICE))
             .thenReturn(mNetworkStatsManager);
+        when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
+            .thenReturn(mNetworkPolicyManager);
+        when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
     }
 
     @Test
-    public void recordUsage_shouldQueryNetworkSummary() throws RemoteException {
+    public void recordUsage_shouldQueryNetworkSummaryForDevice() throws RemoteException {
         final long end = System.currentTimeMillis();
         final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
         final int networkType = ConnectivityManager.TYPE_MOBILE;
         final String subId = "TestSubscriber";
         mLoader = NetworkCycleChartDataLoader.builder(mContext)
-            .setNetworkType(networkType).setSubscriberId(subId).build();
+            .setSubscriberId(subId).build();
 
         mLoader.recordUsage(start, end);
 
-        verify(mNetworkStatsManager).querySummary(networkType, subId, start, end);
+        verify(mNetworkStatsManager).querySummaryForDevice(networkType, subId, start, end);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
index 53fe451..2314f27 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataForUidLoaderTest.java
@@ -16,12 +16,21 @@
 
 package com.android.settingslib.net;
 
+import static android.app.usage.NetworkStats.Bucket.STATE_FOREGROUND;
+import static android.net.NetworkStats.TAG_NONE;
+
+import static org.mockito.Matchers.any;
+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 static org.mockito.Mockito.when;
 
 import android.app.usage.NetworkStatsManager;
 import android.content.Context;
 import android.net.ConnectivityManager;
+import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
 import android.text.format.DateUtils;
 
 import com.android.settingslib.SettingsLibRobolectricTestRunner;
@@ -38,6 +47,8 @@
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
     @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
     private Context mContext;
 
     private NetworkCycleDataForUidLoader mLoader;
@@ -47,20 +58,42 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.NETWORK_STATS_SERVICE))
             .thenReturn(mNetworkStatsManager);
+        when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
+            .thenReturn(mNetworkPolicyManager);
+        when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
     }
 
     @Test
-    public void recordUsage_shouldQueryNetworkDetailsForUid() {
+    public void recordUsage_shouldQueryNetworkDetailsForUidAndForegroundState() {
         final long end = System.currentTimeMillis();
         final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
         final int networkType = ConnectivityManager.TYPE_MOBILE;
         final String subId = "TestSubscriber";
         final int uid = 1;
-        mLoader = NetworkCycleDataForUidLoader.builder(mContext)
-            .setUid(uid).setNetworkType(networkType).setSubscriberId(subId).build();
+        mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
+            .setUid(uid).setSubscriberId(subId).build());
+        doReturn(1024L).when(mLoader).getTotalUsage(any());
 
         mLoader.recordUsage(start, end);
 
         verify(mNetworkStatsManager).queryDetailsForUid(networkType, subId, start, end, uid);
+        verify(mNetworkStatsManager).queryDetailsForUidTagState(
+            networkType, subId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
+    }
+
+    @Test
+    public void recordUsage_retrieveDetailIsFalse_shouldNotQueryNetworkForegroundState() {
+        final long end = System.currentTimeMillis();
+        final long start = end - (DateUtils.WEEK_IN_MILLIS * 4);
+        final int networkType = ConnectivityManager.TYPE_MOBILE;
+        final String subId = "TestSubscriber";
+        final int uid = 1;
+        mLoader = spy(NetworkCycleDataForUidLoader.builder(mContext)
+            .setRetrieveDetail(false).setUid(uid).setSubscriberId(subId).build());
+        doReturn(1024L).when(mLoader).getTotalUsage(any());
+
+        mLoader.recordUsage(start, end);
+        verify(mNetworkStatsManager, never()).queryDetailsForUidTagState(
+            networkType, subId, start, end, uid, TAG_NONE, STATE_FOREGROUND);
     }
 }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
index be7f1bb..9d60a97 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/net/NetworkCycleDataLoaderTest.java
@@ -30,6 +30,7 @@
 import android.net.INetworkStatsService;
 import android.net.INetworkStatsSession;
 import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
 import android.net.NetworkStatsHistory;
 import android.net.NetworkTemplate;
 import android.os.RemoteException;
@@ -55,6 +56,8 @@
     @Mock
     private NetworkStatsManager mNetworkStatsManager;
     @Mock
+    private NetworkPolicyManager mNetworkPolicyManager;
+    @Mock
     private Context mContext;
     @Mock
     private NetworkPolicy mPolicy;
@@ -62,9 +65,6 @@
     private Iterator<Range<ZonedDateTime>> mIterator;
     @Mock
     private INetworkStatsService mNetworkStatsService;
-    @Mock
-    private NetworkCycleDataLoader.Builder mBuilder;
-
 
     private NetworkCycleDataTestLoader mLoader;
 
@@ -73,7 +73,10 @@
         MockitoAnnotations.initMocks(this);
         when(mContext.getSystemService(Context.NETWORK_STATS_SERVICE))
             .thenReturn(mNetworkStatsManager);
+        when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
+            .thenReturn(mNetworkPolicyManager);
         when(mPolicy.cycleIterator()).thenReturn(mIterator);
+        when(mNetworkPolicyManager.getNetworkPolicies()).thenReturn(new NetworkPolicy[0]);
     }
 
     @Test
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index c09b763..c996620 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -35,6 +35,13 @@
 
     static void dumpProtoLocked(SettingsProvider.SettingsRegistry settingsRegistry,
             ProtoOutputStream proto) {
+        // Config settings
+        SettingsState configSettings = settingsRegistry.getSettingsLocked(
+                SettingsProvider.SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
+        if (configSettings != null) {
+            // TODO(b/113100523): dump configuration settings after they are added
+        }
+
         // Global settings
         SettingsState globalSettings = settingsRegistry.getSettingsLocked(
                 SettingsProvider.SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
@@ -662,6 +669,9 @@
         dumpSetting(s, p,
                 Settings.Global.ANGLE_ENABLED_APP,
                 GlobalSettingsProto.Gpu.ANGLE_ENABLED_APP);
+        dumpSetting(s, p,
+                Settings.Global.GPU_DEBUG_LAYER_APP,
+                GlobalSettingsProto.Gpu.DEBUG_LAYER_APP);
         p.end(gpuToken);
 
         final long hdmiToken = p.start(GlobalSettingsProto.HDMI);
@@ -1143,6 +1153,9 @@
         dumpSetting(s, p,
                 Settings.Global.SMS_SHORT_CODES_UPDATE_METADATA_URL,
                 GlobalSettingsProto.Sms.SHORT_CODES_UPDATE_METADATA_URL);
+        dumpSetting(s, p,
+                Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED,
+                GlobalSettingsProto.Sms.ACCESS_RESTRICTION_ENABLED);
         p.end(smsToken);
 
         final long soundsToken = p.start(GlobalSettingsProto.SOUNDS);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 18ec9c3..e0c4d72 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -180,6 +180,7 @@
     public static final int SETTINGS_TYPE_SYSTEM = SettingsState.SETTINGS_TYPE_SYSTEM;
     public static final int SETTINGS_TYPE_SECURE = SettingsState.SETTINGS_TYPE_SECURE;
     public static final int SETTINGS_TYPE_SSAID = SettingsState.SETTINGS_TYPE_SSAID;
+    public static final int SETTINGS_TYPE_CONFIG = SettingsState.SETTINGS_TYPE_CONFIG;
 
     private static final Bundle NULL_SETTING_BUNDLE = Bundle.forPair(
             Settings.NameValueTable.VALUE, null);
@@ -189,6 +190,13 @@
     private static final Set<String> OVERLAY_ALLOWED_SYSTEM_INSTANT_APP_SETTINGS = new ArraySet<>();
     private static final Set<String> OVERLAY_ALLOWED_SECURE_INSTANT_APP_SETTINGS = new ArraySet<>();
 
+    /**
+     * TODO(b/113100523): Move this to DeviceConfig.java when it is added, and expose it as a System
+     *     API.
+     */
+    private static final Uri CONFIG_CONTENT_URI =
+            Uri.parse("content://" + Settings.AUTHORITY + "/config");
+
     static {
         for (String name : Resources.getSystem().getStringArray(
                 com.android.internal.R.array.config_allowedGlobalInstantAppSettings)) {
@@ -380,6 +388,11 @@
     public Bundle call(String method, String name, Bundle args) {
         final int requestingUserId = getRequestingUserId(args);
         switch (method) {
+            case Settings.CALL_METHOD_GET_CONFIG: {
+                Setting setting = getConfigSetting(name);
+                return packageValueForCallResult(setting, isTrackingGeneration(args));
+            }
+
             case Settings.CALL_METHOD_GET_GLOBAL: {
                 Setting setting = getGlobalSetting(name);
                 return packageValueForCallResult(setting, isTrackingGeneration(args));
@@ -396,6 +409,14 @@
                 return packageValueForCallResult(setting, isTrackingGeneration(args));
             }
 
+            case Settings.CALL_METHOD_PUT_CONFIG: {
+                String value = getSettingValue(args);
+                String tag = getSettingTag(args);
+                final boolean makeDefault = getSettingMakeDefault(args);
+                insertConfigSetting(name, value, tag, makeDefault, requestingUserId, false);
+                break;
+            }
+
             case Settings.CALL_METHOD_PUT_GLOBAL: {
                 String value = getSettingValue(args);
                 String tag = getSettingTag(args);
@@ -418,6 +439,13 @@
                 break;
             }
 
+            case Settings.CALL_METHOD_RESET_CONFIG: {
+                final int mode = getResetModeEnforcingPermission(args);
+                String tag = getSettingTag(args);
+                resetConfigSetting(requestingUserId, mode, tag);
+                break;
+            }
+
             case Settings.CALL_METHOD_RESET_GLOBAL: {
                 final int mode = getResetModeEnforcingPermission(args);
                 String tag = getSettingTag(args);
@@ -725,6 +753,15 @@
     @GuardedBy("mLock")
     private void dumpForUserLocked(int userId, PrintWriter pw) {
         if (userId == UserHandle.USER_SYSTEM) {
+            pw.println("CONFIG SETTINGS (user " + userId + ")");
+            SettingsState configSettings = mSettingsRegistry.getSettingsLocked(
+                    SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
+            if (configSettings != null) {
+                dumpSettingsLocked(configSettings, pw);
+                pw.println();
+                configSettings.dumpHistoricalOperations(pw);
+            }
+
             pw.println("GLOBAL SETTINGS (user " + userId + ")");
             SettingsState globalSettings = mSettingsRegistry.getSettingsLocked(
                     SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
@@ -939,6 +976,69 @@
         });
     }
 
+    private Setting getConfigSetting(String name) {
+        if (DEBUG) {
+            Slog.v(LOG_TAG, "getConfigSetting(" + name + ")");
+        }
+
+        // TODO(b/117663715): Ensure the caller can access the setting.
+        // enforceSettingReadable(name, SETTINGS_TYPE_CONFIG, UserHandle.getCallingUserId());
+
+        // Get the value.
+        synchronized (mLock) {
+            return mSettingsRegistry.getSettingLocked(SETTINGS_TYPE_CONFIG,
+                    UserHandle.USER_SYSTEM, name);
+        }
+    }
+
+    private boolean insertConfigSetting(String name, String value, String tag,
+            boolean makeDefault, int requestingUserId, boolean forceNotify) {
+        if (DEBUG) {
+            Slog.v(LOG_TAG, "insertConfigSetting(" + name + ", " + value  + ", "
+                    + ", " + tag + ", " + makeDefault + ", " + requestingUserId
+                    + ", " + forceNotify + ")");
+        }
+        return mutateConfigSetting(name, value, tag, makeDefault, requestingUserId,
+                MUTATION_OPERATION_INSERT, forceNotify, 0);
+    }
+
+    private void resetConfigSetting(int requestingUserId, int mode, String tag) {
+        if (DEBUG) {
+            Slog.v(LOG_TAG, "resetConfigSetting(" + requestingUserId + ", "
+                    + mode + ", " + tag + ")");
+        }
+        mutateConfigSetting(null, null, tag, false, requestingUserId,
+                MUTATION_OPERATION_RESET, false, mode);
+    }
+
+    private boolean mutateConfigSetting(String name, String value, String tag,
+            boolean makeDefault, int requestingUserId, int operation, boolean forceNotify,
+            int mode) {
+        // TODO(b/117663715): check the new permission when it's added.
+        // enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS);
+
+        // Resolve the userId on whose behalf the call is made.
+        final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId);
+
+        // Perform the mutation.
+        synchronized (mLock) {
+            switch (operation) {
+                case MUTATION_OPERATION_INSERT: {
+                    return mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG,
+                            UserHandle.USER_SYSTEM, name, value, tag, makeDefault,
+                            getCallingPackage(), forceNotify, null);
+                }
+
+                case MUTATION_OPERATION_RESET: {
+                    mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG,
+                            UserHandle.USER_SYSTEM, getCallingPackage(), mode, tag);
+                } return true;
+            }
+        }
+
+        return false;
+    }
+
     private Cursor getAllGlobalSettings(String[] projection) {
         if (DEBUG) {
             Slog.v(LOG_TAG, "getAllGlobalSettings()");
@@ -2132,6 +2232,7 @@
         private static final String SETTINGS_FILE_SYSTEM = "settings_system.xml";
         private static final String SETTINGS_FILE_SECURE = "settings_secure.xml";
         private static final String SETTINGS_FILE_SSAID = "settings_ssaid.xml";
+        private static final String SETTINGS_FILE_CONFIG = "settings_config.xml";
 
         private static final String SSAID_USER_KEY = "userkey";
 
@@ -2303,6 +2404,13 @@
             // Migrate the setting for this user if needed.
             migrateLegacySettingsForUserIfNeededLocked(userId);
 
+            // Ensure config settings loaded if owner.
+            if (userId == UserHandle.USER_SYSTEM) {
+                final int configKey
+                        = makeKey(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM);
+                ensureSettingsStateLocked(configKey);
+            }
+
             // Ensure global settings loaded if owner.
             if (userId == UserHandle.USER_SYSTEM) {
                 final int globalKey = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
@@ -2853,6 +2961,10 @@
             }
         }
 
+        private boolean isConfigSettingsKey(int key) {
+            return getTypeFromKey(key) == SETTINGS_TYPE_CONFIG;
+        }
+
         private boolean isGlobalSettingsKey(int key) {
             return getTypeFromKey(key) == SETTINGS_TYPE_GLOBAL;
         }
@@ -2870,7 +2982,11 @@
         }
 
         private File getSettingsFile(int key) {
-            if (isGlobalSettingsKey(key)) {
+            if (isConfigSettingsKey(key)) {
+                final int userId = getUserIdFromKey(key);
+                return new File(Environment.getUserSystemDirectory(userId),
+                        SETTINGS_FILE_CONFIG);
+            } else if (isGlobalSettingsKey(key)) {
                 final int userId = getUserIdFromKey(key);
                 return new File(Environment.getUserSystemDirectory(userId),
                         SETTINGS_FILE_GLOBAL);
@@ -2892,7 +3008,10 @@
         }
 
         private Uri getNotificationUriFor(int key, String name) {
-            if (isGlobalSettingsKey(key)) {
+            if (isConfigSettingsKey(key)) {
+                return (name != null) ? Uri.withAppendedPath(CONFIG_CONTENT_URI, name)
+                        : CONFIG_CONTENT_URI;
+            } else if (isGlobalSettingsKey(key)) {
                 return (name != null) ? Uri.withAppendedPath(Settings.Global.CONTENT_URI, name)
                         : Settings.Global.CONTENT_URI;
             } else if (isSecureSettingsKey(key)) {
@@ -2908,6 +3027,7 @@
 
         private int getMaxBytesPerPackageForType(int type) {
             switch (type) {
+                case SETTINGS_TYPE_CONFIG:
                 case SETTINGS_TYPE_GLOBAL:
                 case SETTINGS_TYPE_SECURE:
                 case SETTINGS_TYPE_SSAID: {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 389d627..ae2ca3f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -34,7 +34,6 @@
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Settings.Global;
-import android.providers.settings.GlobalSettingsProto;
 import android.providers.settings.SettingsOperationProto;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -67,7 +66,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
-import java.util.Set;
 
 /**
  * This class contains the state for one type of settings. It is responsible
@@ -205,6 +203,7 @@
     public static final int SETTINGS_TYPE_SYSTEM = 1;
     public static final int SETTINGS_TYPE_SECURE = 2;
     public static final int SETTINGS_TYPE_SSAID = 3;
+    public static final int SETTINGS_TYPE_CONFIG = 4;
 
     public static final int SETTINGS_TYPE_MASK = 0xF0000000;
     public static final int SETTINGS_TYPE_SHIFT = 28;
@@ -223,6 +222,9 @@
 
     public static String settingTypeToString(int type) {
         switch (type) {
+            case SETTINGS_TYPE_CONFIG: {
+                return "SETTINGS_CONFIG";
+            }
             case SETTINGS_TYPE_GLOBAL: {
                 return "SETTINGS_GLOBAL";
             }
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
index 95569dc..572a924 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
@@ -645,7 +645,7 @@
                         return;
                     }
                     final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
-                    if (elapsedTimeMillis > WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS) {
+                    if (elapsedTimeMillis >= WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS) {
                         fail("Could not change setting for "
                                 + WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS + " ms");
                     }
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 5c654b4..822c39b 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -24,8 +24,10 @@
 
     <!-- Standard permissions granted to the shell. -->
     <uses-permission android:name="android.permission.SEND_SMS" />
+    <uses-permission android:name="android.permission.READ_SMS" />
     <uses-permission android:name="android.permission.CALL_PHONE" />
     <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
     <uses-permission android:name="android.permission.READ_CALENDAR" />
@@ -54,6 +56,7 @@
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.BROADCAST_STICKY" />
+    <uses-permission android:name="android.permission.MANAGE_ACCESSIBILITY" />
     <!-- Development tool permissions granted to the shell. -->
     <uses-permission android:name="android.permission.SET_DEBUG_APP" />
     <uses-permission android:name="android.permission.SET_PROCESS_LIMIT" />
diff --git a/packages/SystemUI/docs/plugins.md b/packages/SystemUI/docs/plugins.md
index ed91f3d..6892005 100644
--- a/packages/SystemUI/docs/plugins.md
+++ b/packages/SystemUI/docs/plugins.md
@@ -73,7 +73,7 @@
 1. They must be signed with the platform cert
 2. They must include SystemUIPluginLib in LOCAL_JAVA_LIBRARIES (NOT LOCAL_STATIC_JAVA_LIBRARIES)
 
-Basically just copy the [example file](/packages/SystemUI/plugin/ExamplePlugin/Android.mk).
+Basically just copy the [example blueprint file](/packages/SystemUI/plugin/ExamplePlugin/Android.bp).
 
 To declare a plugin, you add a service to your manifest.  Add an intent filter to match the action for the plugin, and set the name to point at the class that implements the plugin interface.
 
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
index b38059d..df5561a 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -18,6 +18,9 @@
 
     srcs: ["src/**/*.java"],
 
+    static_libs: [
+        "PluginCoreLib"
+    ],
 
 }
 
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index b58ea00..f492208 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -14,6 +14,7 @@
 
 package com.android.systemui.plugins;
 
+import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Intent;
 
@@ -36,7 +37,17 @@
     void postStartActivityDismissingKeyguard(PendingIntent intent);
     void postQSRunnableDismissingKeyguard(Runnable runnable);
 
+    void dismissKeyguardThenExecute(OnDismissAction action, @Nullable Runnable cancel,
+            boolean afterKeyguardGone);
+
     interface Callback {
         void onActivityStarted(int resultCode);
     }
+
+    interface OnDismissAction {
+        /**
+         * @return {@code true} if the dismiss should be deferred
+         */
+        boolean onDismiss();
+    }
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
new file mode 100644
index 0000000..ba4eb5f
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.plugins;
+
+import android.hardware.Sensor;
+import android.hardware.TriggerEventListener;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Allows for additional sensors to be retrieved from
+ * {@link com.android.systemui.util.AsyncSensorManager}.
+ */
+@ProvidesInterface(action = SensorManagerPlugin.ACTION, version = SensorManagerPlugin.VERSION)
+public interface SensorManagerPlugin extends Plugin {
+    String ACTION = "com.android.systemui.action.PLUGIN_SENSOR_MANAGER";
+    int VERSION = 1;
+
+    /**
+     * Registers for trigger events from the sensor. Trigger events are one-shot and need to
+     * re-registered in order for them to be fired again.
+     * @param sensor
+     * @param listener
+     * @see android.hardware.SensorManager#requestTriggerSensor(
+     *     android.hardware.TriggerEventListener, android.hardware.Sensor)
+     */
+    void registerTriggerEvent(Sensor sensor, TriggerEventListener listener);
+
+    /**
+     * Unregisters trigger events from the sensor.
+     * @param sensor
+     * @param listener
+     */
+    void unregisterTriggerEvent(Sensor sensor, TriggerEventListener listener);
+
+    interface TriggerEventListener {
+        void onTrigger(TriggerEvent event);
+    }
+
+    class Sensor {
+        public static int TYPE_WAKE_LOCK_SCREEN = 1;
+
+        int mType;
+
+        public int getType() {
+            return mType;
+        }
+
+        public Sensor(int type) {
+            mType = type;
+        }
+    }
+
+    class TriggerEvent {
+        Sensor mSensor;
+        int mVendorType;
+
+        /**
+         * Creates a trigger event
+         * @param sensor The type of sensor, e.g. TYPE_WAKE_LOCK_SCREEN
+         * @param vendorType The vendor type, which should be unique for each type of sensor,
+         *                   e.g. SINGLE_TAP = 1, DOUBLE_TAP = 2, etc.
+         */
+        public TriggerEvent(Sensor sensor, int vendorType) {
+            mSensor = sensor;
+            mVendorType = vendorType;
+        }
+
+        public Sensor getSensor() {
+            return mSensor;
+        }
+
+        public int getVendorType() {
+            return mVendorType;
+        }
+    }
+}
diff --git a/packages/SystemUI/plugin_core/Android.bp b/packages/SystemUI/plugin_core/Android.bp
new file mode 100644
index 0000000..58a8e49
--- /dev/null
+++ b/packages/SystemUI/plugin_core/Android.bp
@@ -0,0 +1,21 @@
+// 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: "PluginCoreLib",
+
+    srcs: ["src/**/*.java"],
+
+}
diff --git a/packages/SystemUI/plugin_core/AndroidManifest.xml b/packages/SystemUI/plugin_core/AndroidManifest.xml
new file mode 100644
index 0000000..df835fd
--- /dev/null
+++ b/packages/SystemUI/plugin_core/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?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.systemui.plugin_core">
+
+    <uses-sdk
+        android:minSdkVersion="28" />
+
+</manifest>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/Plugin.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java
similarity index 100%
rename from packages/SystemUI/plugin/src/com/android/systemui/plugins/Plugin.java
rename to packages/SystemUI/plugin_core/src/com/android/systemui/plugins/Plugin.java
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginFragment.java
similarity index 100%
rename from packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginFragment.java
rename to packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginFragment.java
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginListener.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java
similarity index 100%
rename from packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginListener.java
rename to packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/Dependencies.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Dependencies.java
similarity index 100%
rename from packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/Dependencies.java
rename to packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Dependencies.java
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/DependsOn.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/DependsOn.java
similarity index 100%
rename from packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/DependsOn.java
rename to packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/DependsOn.java
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/ProvidesInterface.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProvidesInterface.java
similarity index 100%
rename from packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/ProvidesInterface.java
rename to packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/ProvidesInterface.java
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/Requirements.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requirements.java
similarity index 100%
rename from packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/Requirements.java
rename to packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requirements.java
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/Requires.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requires.java
similarity index 100%
rename from packages/SystemUI/plugin/src/com/android/systemui/plugins/annotations/Requires.java
rename to packages/SystemUI/plugin_core/src/com/android/systemui/plugins/annotations/Requires.java
diff --git a/packages/SystemUI/res-keyguard/drawable/ic_keyboard_tab_36dp.xml b/packages/SystemUI/res-keyguard/drawable/ic_keyboard_tab_36dp.xml
new file mode 100644
index 0000000..21c9051
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ic_keyboard_tab_36dp.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<vector android:height="36sp" android:viewportHeight="36"
+        android:viewportWidth="36" android:width="36sp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="?android:attr/colorAccent" android:pathData="M18,18m-18,0a18,18 0,1 1,36 0a18,18 0,1 1,-36 0"/>
+    <path android:fillColor="?android:attr/textColorPrimaryInverse" android:pathData="M17.59,13.41L21.17,17H7v2h14.17l-3.59,3.59L19,24l6,-6l-6,-6L17.59,13.41zM26,12v12h2V12H26z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res-keyguard/drawable/ripple_drawable_pin.xml b/packages/SystemUI/res-keyguard/drawable/ripple_drawable_pin.xml
new file mode 100644
index 0000000..51c442a
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/drawable/ripple_drawable_pin.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
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:color="?android:attr/colorControlHighlight"
+        android:radius="40dp"/>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index 41dd0b3..9c41fca 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -57,24 +57,6 @@
                     android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_pin_area"
                     />
-            <ImageButton
-                    android:id="@+id/delete_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_black_24dp"
-                    android:clickable="true"
-                    android:paddingTop="8dip"
-                    android:paddingBottom="8dip"
-                    android:paddingRight="0dp"
-                    android:paddingLeft="0dp"
-                    android:background="@drawable/ripple_drawable"
-                    android:contentDescription="@string/keyboardview_keycode_delete"
-                    android:layout_alignEnd="@+id/pinEntry"
-                    android:layout_alignParentRight="true"
-                    android:tint="@color/pin_delete_color"
-                    android:tintMode="src_in"
-                    />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
@@ -186,10 +168,14 @@
                 android:layout_weight="1"
                 android:orientation="horizontal"
                 >
-            <Space
+            <com.android.keyguard.AlphaOptimizedImageButton
+                    android:id="@+id/delete_button"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
+                    android:background="@drawable/ripple_drawable_pin"
+                    android:contentDescription="@string/keyboardview_keycode_delete"
+                    style="@style/Keyguard.ImageButton.NumPadDelete"
                     />
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key0"
@@ -204,10 +190,8 @@
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_black_24dp"
                     style="@style/Keyguard.ImageButton.NumPadEnter"
-                    android:background="@drawable/ripple_drawable"
+                    android:background="@drawable/ripple_drawable_pin"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
         </LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index a795442..7d8a1f5b 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -42,18 +42,11 @@
                          android:id="@+id/clock_view"
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content" />
-                <View
-                    android:id="@+id/clock_separator"
-                    android:layout_width="@dimen/widget_separator_width"
-                    android:layout_height="@dimen/widget_separator_thickness"
-                    android:layout_below="@id/clock_view"
-                    android:background="#f00"
-                    android:layout_centerHorizontal="true" />
                 <include layout="@layout/keyguard_status_area"
                          android:id="@+id/keyguard_status_area"
                          android:layout_width="match_parent"
                          android:layout_height="wrap_content"
-                         android:layout_below="@id/clock_separator" />
+                         android:layout_below="@id/clock_view" />
             </RelativeLayout>
             <ImageView
                 android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
index 33f7e75..bfb5bf9 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_pin_view.xml
@@ -71,24 +71,6 @@
                     android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_sim_pin_area"
                     />
-            <ImageButton
-                    android:id="@+id/delete_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_black_24dp"
-                    android:clickable="true"
-                    android:paddingTop="8dip"
-                    android:paddingBottom="8dip"
-                    android:paddingRight="0dp"
-                    android:paddingLeft="0dp"
-                    android:background="@drawable/ripple_drawable"
-                    android:contentDescription="@string/keyboardview_keycode_delete"
-                    android:layout_alignEnd="@+id/pinEntry"
-                    android:layout_alignParentRight="true"
-                    android:tint="@color/pin_delete_color"
-                    android:tintMode="src_in"
-                    />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
@@ -196,10 +178,14 @@
                 android:layout_weight="1"
                 android:orientation="horizontal"
                 >
-            <Space
+            <com.android.keyguard.AlphaOptimizedImageButton
+                    android:id="@+id/delete_button"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
+                    android:background="@drawable/ripple_drawable_pin"
+                    android:contentDescription="@string/keyboardview_keycode_delete"
+                    style="@style/Keyguard.ImageButton.NumPadDelete"
                     />
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key0"
@@ -209,15 +195,13 @@
                     androidprv:textView="@+id/simPinEntry"
                     androidprv:digit="0"
                     />
-            <ImageButton
+            <com.android.keyguard.AlphaOptimizedImageButton
                     android:id="@+id/key_enter"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_black_24dp"
                     style="@style/Keyguard.ImageButton.NumPadEnter"
-                    android:background="@drawable/ripple_drawable"
+                    android:background="@drawable/ripple_drawable_pin"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
         </LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
index 4b385fc..9f3ae3a 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_sim_puk_view.xml
@@ -72,24 +72,6 @@
                     android:textColor="?attr/wallpaperTextColor"
                     android:contentDescription="@string/keyguard_accessibility_sim_puk_area"
                     />
-            <ImageButton
-                    android:id="@+id/delete_button"
-                    android:layout_width="wrap_content"
-                    android:layout_height="match_parent"
-                    android:gravity="center_vertical"
-                    android:src="@drawable/ic_backspace_black_24dp"
-                    android:clickable="true"
-                    android:paddingTop="8dip"
-                    android:paddingBottom="8dip"
-                    android:paddingRight="0dp"
-                    android:paddingLeft="0dp"
-                    android:background="@drawable/ripple_drawable"
-                    android:contentDescription="@string/keyboardview_keycode_delete"
-                    android:layout_alignEnd="@+id/pinEntry"
-                    android:layout_alignParentRight="true"
-                    android:tint="@color/pin_delete_color"
-                    android:tintMode="src_in"
-                    />
             <View
                     android:id="@+id/divider"
                     android:layout_width="match_parent"
@@ -197,10 +179,14 @@
                 android:layout_weight="1"
                 android:orientation="horizontal"
                 >
-            <Space
+            <com.android.keyguard.AlphaOptimizedImageButton
+                    android:id="@+id/delete_button"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
+                    android:background="@drawable/ripple_drawable_pin"
+                    android:contentDescription="@string/keyboardview_keycode_delete"
+                    style="@style/Keyguard.ImageButton.NumPadDelete"
                     />
             <com.android.keyguard.NumPadKey
                     android:id="@+id/key0"
@@ -210,15 +196,13 @@
                     androidprv:textView="@+id/pukEntry"
                     androidprv:digit="0"
                     />
-            <ImageButton
+            <com.android.keyguard.AlphaOptimizedImageButton
                     android:id="@+id/key_enter"
                     android:layout_width="0px"
                     android:layout_height="match_parent"
                     android:layout_weight="1"
-                    android:paddingBottom="11sp"
-                    android:src="@drawable/ic_done_black_24dp"
                     style="@style/Keyguard.ImageButton.NumPadEnter"
-                    android:background="@drawable/ripple_drawable"
+                    android:background="@drawable/ripple_drawable_pin"
                     android:contentDescription="@string/keyboardview_keycode_enter"
                     />
         </LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
index dfa4bf9..00f8f86 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_area.xml
@@ -43,6 +43,7 @@
               android:id="@+id/row"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
+              android:layout_marginTop="@dimen/subtitle_clock_padding"
               android:orientation="horizontal"
               android:gravity="center"
     />
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 4ae2d41..32a7147 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -59,19 +59,11 @@
                  android:id="@+id/clock_view"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content" />
-            <View
-                android:id="@+id/clock_separator"
-                android:layout_width="@dimen/widget_separator_width"
-                android:layout_height="@dimen/widget_separator_thickness"
-                android:layout_below="@id/clock_view"
-                android:background="#f00"
-                android:layout_centerHorizontal="true" />
-
             <include layout="@layout/keyguard_status_area"
                 android:id="@+id/keyguard_status_area"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_below="@id/clock_separator" />
+                android:layout_below="@id/clock_view" />
         </RelativeLayout>
 
         <TextView
diff --git a/packages/SystemUI/res-keyguard/values-bs/strings.xml b/packages/SystemUI/res-keyguard/values-bs/strings.xml
index 9984061..1106807 100644
--- a/packages/SystemUI/res-keyguard/values-bs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bs/strings.xml
@@ -85,9 +85,9 @@
     <string name="kg_invalid_puk" msgid="5399287873762592502">"Ponovo unesite ispravan PUK kôd. Ponovljeni pokušaji će trajno onemogućiti SIM karticu."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="5672736555427444330">"PIN-ovi se ne poklapaju"</string>
     <string name="kg_login_too_many_attempts" msgid="6604574268387867255">"Previše puta ste pokušali otključati uređaj crtanjem uzorka"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"Pogrešno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"Pogrešno ste unijeli lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"Pogrešno ste nacrtali svoj uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> sek."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"Pogrešno ste unijeli PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"Pogrešno ste unijeli lozinku <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"Pogrešno ste nacrtali svoj uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. \n\nPokušajte ponovo za <xliff:g id="NUMBER_1">%2$d</xliff:g> s."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati tablet. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, tablet će se vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati telefon. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, telefon će se vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati tablet. Tablet će se sada vratiti na fabričke postavke i svi podaci će se izbrisati."</string>
@@ -100,8 +100,8 @@
     <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"Pokušali ste <xliff:g id="NUMBER_0">%1$d</xliff:g> puta neispravno otključati telefon. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, poslovni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati tablet. Poslovni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"Pokušali ste <xliff:g id="NUMBER">%d</xliff:g> puta neispravno otključati telefon. Poslovni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da tablet otključate koristeći račun e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da telefon otključate koristeći račun e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da tablet otključate koristeći račun e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da telefon otključate koristeći račun e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"PIN za SIM karticu je netačan. Za otključavanje uređaja sada se morate obratiti svom operateru."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
       <item quantity="one">PIN za SIM karticu je netačan. Imate još <xliff:g id="NUMBER_1">%d</xliff:g> pokušaj.</item>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index c2759da..d412252 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -37,7 +37,7 @@
     <string name="keyguard_plugged_in" msgid="3161102098900158923">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज होत आहे"</string>
     <string name="keyguard_plugged_in_charging_fast" msgid="3684592786276709342">"<xliff:g id="PERCENTAGE">%s</xliff:g> • वेगाने चार्ज होत आहे"</string>
     <string name="keyguard_plugged_in_charging_slowly" msgid="509533586841478405">"<xliff:g id="PERCENTAGE">%s</xliff:g> • सावकाश चार्ज होत आहे"</string>
-    <string name="keyguard_low_battery" msgid="9218432555787624490">"आपला चार्जर कनेक्ट करा."</string>
+    <string name="keyguard_low_battery" msgid="9218432555787624490">"तुमचा चार्जर कनेक्ट करा."</string>
     <string name="keyguard_instructions_when_pattern_disabled" msgid="8566679946700751371">"अनलॉक करण्यासाठी मेनू दाबा."</string>
     <string name="keyguard_network_locked_message" msgid="6743537524631420759">"नेटवर्क लॉक केले"</string>
     <string name="keyguard_missing_sim_message_short" msgid="6327533369959764518">"सिम कार्ड नाही"</string>
@@ -84,9 +84,9 @@
     <string name="kg_invalid_puk" msgid="5399287873762592502">"योग्य PUK कोड पुन्हा एंटर करा. पुनःपुन्हा प्रयत्न करणे सिम कायमचे अक्षम करेल."</string>
     <string name="kg_invalid_confirm_pin_hint" product="default" msgid="5672736555427444330">"पिन कोड जुळत नाहीत"</string>
     <string name="kg_login_too_many_attempts" msgid="6604574268387867255">"खूप जास्त पॅटर्न प्रयत्न"</string>
-    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"तुम्ही आपला PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"तुम्ही आपला पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8637788033282252027">"तुम्ही तुमचा PIN <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7724148763268377734">"तुम्ही तुमचा पासवर्ड <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने टाइप केला आहे. \n\n<xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="4820967667848302092">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यरितीने काढला. \n\n <xliff:g id="NUMBER_1">%2$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1629351522209932316">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, हे टॅबलेट रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, हा फोन रीसेट केला जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. हे टॅबलेट रीसेट केले जाईल, जे त्याचा सर्व डेटा हटवेल."</string>
@@ -99,8 +99,8 @@
     <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, ही कार्य प्रोफाइल काढली जाईल, जे सर्व प्रोफाइल डेटा हटवेल."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"तुम्ही टॅबलेट अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. कार्य प्रोफाइल काढली जाईल, जे सर्व प्रोफाइल डेटा हटवेल."</string>
     <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. कार्य प्रोफाइल काढली जाईल, जे सर्व प्रोफाइल डेटा हटवेल."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून आपला टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
-    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"तुम्ही आपला अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून आपला फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा टॅब्लेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
+    <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा अयोग्यपणे काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"सिम पिन कोड चुकीचा आहे तुम्ही आता तुमचे डिव्हाइस अनलॉक करण्‍यासाठी तुमच्या वाहकाशी संपर्क साधावा."</string>
     <plurals name="kg_password_wrong_pin_code" formatted="false" msgid="4314341367727055967">
       <item quantity="one">चुकीचा सिम पिन कोड, तुमच्याकडे <xliff:g id="NUMBER_1">%d</xliff:g> प्रयत्न शिल्लक आहेत.</item>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index 913c3bb..041e990 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -91,14 +91,14 @@
     <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="3921998703529189931">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यो फोन यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
     <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="4694232971224663735">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। यो ट्याब्लेट यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
     <string name="kg_failed_attempts_now_wiping" product="default" msgid="2365964340830006961">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। यो फोन यसमा भएका सबै डेटा मेटिने गरी रिसेट हुनेछ।"</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="1365418870560228936">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले  ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइनेछ।"</string>
-    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="2151286957817486128">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइनेछ।"</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="5464020754932560928">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। यो प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइनेछ।"</string>
-    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="6171564974118059">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइनेछ।"</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="9154513795928824239">"तपाईंले  <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, कार्य प्रोफाइललाई यसको सबै डेटा मेटिने गरी हटाइनेछ।"</string>
-    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, कार्य प्रोफाइललाई यसको सबै डेटा मेटिने गरी हटाइनेछ।"</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"तपाईं <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइनेछ।"</string>
-    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइनेछ।"</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="tablet" msgid="1365418870560228936">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले  ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_erase_user" product="default" msgid="2151286957817486128">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="tablet" msgid="5464020754932560928">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। यो प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+    <string name="kg_failed_attempts_now_erasing_user" product="default" msgid="6171564974118059">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। यस प्रयोगकर्तालाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="tablet" msgid="9154513795928824239">"तपाईंले  <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, कार्य प्रोफाइललाई यसको सबै डेटा मेटिने गरी हटाइने छ।"</string>
+    <string name="kg_failed_attempts_almost_at_erase_profile" product="default" msgid="2162434417489128282">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, कार्य प्रोफाइललाई यसको सबै डेटा मेटिने गरी हटाइने छ।"</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="tablet" msgid="8966727588974691544">"तपाईं <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले ट्याब्लेट अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
+    <string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="8476407539834855">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="956706236554092172">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो ट्याब्लेट अनलक गर्न आग्रह गरिनेछ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
     <string name="kg_failed_attempts_almost_at_login" product="default" msgid="8364140853305528449">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> असफल प्रयासहरूपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो फोन अनलक गर्न आग्रह गरिनेछ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
     <string name="kg_password_wrong_pin_code_pukked" msgid="3389829202093674267">"SIM को PIN कोड गलत छ। तपाईंले अब अाफ्नो यन्त्र खोल्न आफ्नो सेवा प्रदायकलाई सम्पर्क गर्नै पर्ने हुन्छ।"</string>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 787f91e..555f443 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -43,7 +43,7 @@
 
     <!-- Slice header -->
     <dimen name="widget_title_font_size">24dp</dimen>
-    <dimen name="widget_title_bottom_margin">7dp</dimen>
+    <dimen name="widget_title_bottom_margin">14dp</dimen>
     <dimen name="bottom_text_spacing_digital">0dp</dimen>
     <!-- Slice subtitle -->
     <dimen name="widget_label_font_size">16dp</dimen>
@@ -52,19 +52,17 @@
     <!-- Clock without header -->
     <dimen name="widget_big_font_size">64dp</dimen>
     <!-- Clock with header -->
+    <dimen name="widget_small_clock_padding">-25dp</dimen>
     <dimen name="widget_small_font_size">24dp</dimen>
     <dimen name="widget_small_font_stroke">0.6dp</dimen>
-    <!-- Dash between clock and header -->
-    <dimen name="widget_separator_width">12dp</dimen>
-    <dimen name="widget_separator_thickness">1dp</dimen>
-    <dimen name="widget_vertical_padding">26dp</dimen>
-    <dimen name="widget_icon_bottom_padding">14dp</dimen>
+    <dimen name="widget_vertical_padding">32dp</dimen>
     <!-- Subtitle paddings -->
     <dimen name="widget_horizontal_padding">8dp</dimen>
     <dimen name="widget_icon_size">16dp</dimen>
     <dimen name="widget_icon_padding">8dp</dimen>
-    <!-- Space between notification shelf and dash above it -->
-    <dimen name="widget_bottom_separator_padding">28dp</dimen>
+    <dimen name="subtitle_clock_padding">15dp</dimen>
+    <!-- Notification shelf padding when dark -->
+    <dimen name="widget_bottom_separator_padding">-6dp</dimen>
 
     <!-- The y translation to apply at the start in appear animations. -->
     <dimen name="appear_y_translation_start">32dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index b90b4dd..0462347 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -37,8 +37,16 @@
         <item name="android:textColor">?attr/wallpaperTextColor</item>
         <item name="android:paddingBottom">-16dp</item>
     </style>
+    <style name="Keyguard.ImageButton.NumPadDelete" parent="@android:style/Widget.ImageButton">
+        <item name="android:src">@drawable/ic_backspace_black_24dp</item>
+        <item name="android:paddingBottom">11sp</item>
+        <item name="android:tint">@color/pin_delete_color</item>
+        <item name="android:tintMode">src_in</item>
+        <item name="android:src">@drawable/ic_backspace_black_24dp</item>
+    </style>
     <style name="Keyguard.ImageButton.NumPadEnter" parent="@android:style/Widget.ImageButton">
-        <item name="android:tint">@color/background_protected</item>
+        <item name="android:src">@drawable/ic_keyboard_tab_36dp</item>
+        <item name="android:paddingBottom">11sp</item>
     </style>
     <style name="Widget.TextView.NumPadKey.Klondike" parent="Widget.TextView.NumPadKey">
         <item name="android:textSize">12sp</item>
diff --git a/packages/SystemUI/res/drawable/ic_face_unlock.xml b/packages/SystemUI/res/drawable/ic_face_unlock.xml
index 29c2275..b302ed4 100644
--- a/packages/SystemUI/res/drawable/ic_face_unlock.xml
+++ b/packages/SystemUI/res/drawable/ic_face_unlock.xml
@@ -15,8 +15,8 @@
   -->
 
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
+        android:width="24dp"
+        android:height="24dp"
         android:viewportHeight="24.0"
         android:viewportWidth="24.0">
     <path android:fillColor="?attr/wallpaperTextColor"
diff --git a/packages/SystemUI/res/drawable/ic_lock.xml b/packages/SystemUI/res/drawable/ic_lock.xml
new file mode 100644
index 0000000..3fb8c8d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_lock.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32dp"
+        android:height="32dp"
+        android:viewportWidth="32.0"
+        android:viewportHeight="32.0">
+    <path
+        android:pathData="M20.25,6.89C20.25,4.62 18.36,2.75 16,2.75C13.64,2.75 11.75,4.62 11.75,6.89V11.25H20.25V6.89ZM21.75,11.25V6.89C21.75,3.76 19.16,1.25 16,1.25C12.84,1.25 10.25,3.76 10.25,6.89V11.25H10C8.48,11.25 7.25,12.48 7.25,14V26C7.25,27.52 8.48,28.75 10,28.75H22C23.52,28.75 24.75,27.52 24.75,26V14C24.75,12.48 23.52,11.25 22,11.25H21.75ZM10,12.75C9.31,12.75 8.75,13.31 8.75,14V26C8.75,26.69 9.31,27.25 10,27.25H22C22.69,27.25 23.25,26.69 23.25,26V14C23.25,13.31 22.69,12.75 22,12.75H10ZM18,20C18,21.1 17.1,22 16,22C14.9,22 14,21.1 14,20C14,18.9 14.9,18 16,18C17.1,18 18,18.9 18,20Z"
+        android:fillType="evenOdd"
+        android:fillColor="?attr/wallpaperTextColor"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
deleted file mode 100644
index bf0dc95..0000000
--- a/packages/SystemUI/res/drawable/ic_lock_24dp.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24.0dp"
-        android:height="24.0dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-
-    <path
-        android:fillColor="?attr/wallpaperTextColor"
-        android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/>
-</vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_open.xml b/packages/SystemUI/res/drawable/ic_lock_open.xml
new file mode 100644
index 0000000..12a811c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_lock_open.xml
@@ -0,0 +1,26 @@
+<!--
+  ~ Copyright (C) 2018 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="32dp"
+        android:height="32dp"
+        android:viewportWidth="32.0"
+        android:viewportHeight="32.0">
+    <path
+        android:pathData="M21.75,6.89C21.75,4.62 23.64,2.75 26,2.75C28.36,2.75 30.25,4.62 30.25,6.89V12H31.75V6.89C31.75,3.76 29.16,1.25 26,1.25C22.84,1.25 20.25,3.76 20.25,6.89V11.25H10C8.48,11.25 7.25,12.48 7.25,14V26C7.25,27.52 8.48,28.75 10,28.75H22C23.52,28.75 24.75,27.52 24.75,26V14C24.75,12.48 23.52,11.25 22,11.25H21.75V6.89ZM10,12.75C9.31,12.75 8.75,13.31 8.75,14V26C8.75,26.69 9.31,27.25 10,27.25H22C22.69,27.25 23.25,26.69 23.25,26V14C23.25,13.31 22.69,12.75 22,12.75H10ZM18,20C18,21.1 17.1,22 16,22C14.9,22 14,21.1 14,20C14,18.9 14.9,18 16,18C17.1,18 18,18.9 18,20Z"
+        android:fillType="evenOdd"
+        android:fillColor="?attr/wallpaperTextColor"/>
+</vector>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index d0d379c..96a1bab 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -88,7 +88,7 @@
         android:layout_width="@dimen/keyguard_affordance_width"
         android:layout_height="@dimen/keyguard_affordance_height"
         android:layout_gravity="bottom|center_horizontal"
-        android:src="@drawable/ic_lock_24dp"
+        android:src="@drawable/ic_lock"
         android:contentDescription="@string/accessibility_unlock_button"
         android:scaleType="center" />
 
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 7a38899..f138685 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -24,8 +24,7 @@
     android:clipChildren="false"
     android:clipToPadding="false"
     android:orientation="vertical"
-    android:background="@color/notification_guts_bg_color"
-    android:theme="@*android:style/Theme.DeviceDefault.Light">
+    android:background="@color/notification_guts_bg_color">
 
     <!-- Package Info -->
     <RelativeLayout
diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
index 7083269..e44fbcf 100644
--- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
+++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
@@ -21,18 +21,5 @@
     android:layout_height="wrap_content"
     android:layout_weight="1"
     android:clipChildren="true"
-    android:clipToPadding="true"
-    android:paddingStart="@dimen/notification_side_paddings"
-    android:paddingEnd="@dimen/notification_side_paddings"
     android:paddingBottom="@dimen/qs_paged_tile_layout_padding_bottom">
-
-
-    <FrameLayout
-        android:id="@+id/page_decor"
-        android:layout_width="wrap_content"
-        android:layout_height="48dp"
-        android:layout_gravity="bottom">
-
-    </FrameLayout>
-
 </com.android.systemui.qs.PagedTileLayout>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index f0436de..d033057 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -49,11 +49,6 @@
         android:paddingEnd="@dimen/status_bar_padding_end"
         android:orientation="horizontal"
         >
-        <ViewStub
-            android:id="@+id/operator_name"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout="@layout/operator_name" />
         <FrameLayout
             android:layout_height="match_parent"
             android:layout_width="0dp"
@@ -70,6 +65,12 @@
                 android:layout_width="match_parent"
                 android:clipChildren="false"
             >
+                <ViewStub
+                    android:id="@+id/operator_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="match_parent"
+                    android:layout="@layout/operator_name" />
+
                 <com.android.systemui.statusbar.policy.Clock
                     android:id="@+id/clock"
                     android:layout_width="wrap_content"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 157934f..395de19 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Battery laai tans, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> persent."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Sien alle kennisgewings"</string>
@@ -319,6 +319,8 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Onbenoemde toestel"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Gereed om uit te saai"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Geen toestelle beskikbaar nie"</string>
+    <!-- no translation found for quick_settings_cast_no_wifi (2696477881905521882) -->
+    <skip />
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helderheid"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Keer kleure om"</string>
@@ -442,7 +444,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sal alles begin vasvang wat op jou skerm gewys word."</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="8035284146227267681">"Bestuur kennisgewings"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Bestuur"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Kennisgewings onderbreek deur Moenie Steur Nie"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Begin nou"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Geen kennisgewings nie"</string>
@@ -782,6 +784,8 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Aangemeld as <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Geen internet nie"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Maak besonderhede oop."</string>
+    <!-- no translation found for accessibility_quick_settings_not_available (4190068184294019846) -->
+    <skip />
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Maak <xliff:g id="ID_1">%s</xliff:g>-instellings oop."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Wysig volgorde van instellings."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Bladsy <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 492fa8c..fcad97b 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"ባትሪ ኃይል በመሙላት ላይ፣ <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"ሁሉንም ማሳወቂያዎች ይመልከቱ"</string>
@@ -319,6 +319,8 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ያልተሰየመ መሳሪያ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ለመውሰድ ዝግጁ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"ምንም መሣሪያዎች አይገኙም"</string>
+    <!-- no translation found for quick_settings_cast_no_wifi (2696477881905521882) -->
+    <skip />
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ብሩህነት"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ራስ-ሰር"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ቀለማትን ግልብጥ"</string>
@@ -442,7 +444,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> በማያ ገጽዎ ላይ የታየውን ነገር በሙሉ ማንሳት ይጀምራል።"</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="8035284146227267681">"ማሳወቂያዎችን ያስተዳድሩ"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"ያቀናብሩ"</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>
@@ -782,6 +784,8 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"እንደ <xliff:g id="ID_1">%s</xliff:g> ሆነው ገብተዋል"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ምንም በይነመረብ የለም"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"ዝርዝሮችን ክፈት።"</string>
+    <!-- no translation found for accessibility_quick_settings_not_available (4190068184294019846) -->
+    <skip />
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"የ<xliff:g id="ID_1">%s</xliff:g> ቅንብሮችን ክፈት።"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"የቅንብሮድ ቅደም-ተከተል አርትዕ።"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"ገጽ <xliff:g id="ID_1">%1$d</xliff:g> ከ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index fe27bb7..1b55d39 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -178,7 +178,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_charging" msgid="1147587904439319646">"جارٍ شحن البطارية، <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"الاطّلاع على جميع الإشعارات"</string>
@@ -327,6 +327,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"جهاز لا يحمل اسمًا"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"جاهز للإرسال"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"لا يتوفر أي جهاز"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"‏لم يتم الاتصال بشبكة Wi-Fi."</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"السطوع"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"تلقائي"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"قلب الألوان"</string>
@@ -458,7 +459,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> سيبدأ التقاط كل شيء يتم عرضه على الشاشة."</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="8035284146227267681">"إدارة الإشعارات"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"إدارة"</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>
@@ -806,6 +807,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"تم تسجيل الدخول باعتبارك <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"لا يتوفر اتصال إنترنت."</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"فتح التفاصيل."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"غير متاحة بسبب <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"فتح إعدادات <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"تعديل ترتيب الإعدادات."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"الصفحة <xliff:g id="ID_1">%1$d</xliff:g> من <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -846,7 +848,7 @@
     <string name="notification_channel_battery" msgid="5786118169182888462">"البطارية"</string>
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"لقطات الشاشة"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"رسائل عامة"</string>
-    <string name="notification_channel_storage" msgid="3077205683020695313">"سعة التخزين"</string>
+    <string name="notification_channel_storage" msgid="3077205683020695313">"مساحة التخزين"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"تلميحات"</string>
     <string name="instant_apps" msgid="6647570248119804907">"التطبيقات الفورية"</string>
     <string name="instant_apps_title" msgid="8738419517367449783">"التطبيق <xliff:g id="APP">%1$s</xliff:g> قيد التشغيل"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 8cde524..65c5fb5 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"নাম নথকা ডিভাইচ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"কাষ্টৰ বাবে সাজু"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"কোনো ডিভাইচ নাই"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"ৱাই-ফাইৰ সৈতে সংযোগ হৈ থকা নাই"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"উজ্জ্বলতা"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"স্বয়ং"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ৰং ওলোটা কৰক"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"আপোনাৰ স্ক্ৰীণত প্ৰদৰ্শন হোৱা সকলো <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> কেপশ্বাৰ কৰা আৰম্ভ কৰিব।"</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="8035284146227267681">"জনানীসমূহ পৰিচালনা কৰক"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"পৰিচালনা"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> হিচাপে ছাইন ইন হ\'ল"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ইণ্টাৰনেট সংযোগ নাই"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"বিৱৰণসমূহ খোলক।"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g>ৰ বাবে উপলব্ধ নহয়"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g>ৰ ছেটিংসমূহ খোলক।"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ছেটিংসমূহৰ ক্ৰম সম্পাদনা কৰক।"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>ৰ পৃষ্ঠা <xliff:g id="ID_1">%1$d</xliff:g>"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"সঞ্চয়াগাৰ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"ইংগিতবোৰ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"তাৎক্ষণিক এপসমূহ"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> চলি আছে"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"ইনষ্ট\'ল নকৰাকৈয়েই এপটো খোলা হৈছে।"</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ইনষ্ট\'ল নকৰাকৈয়েই এপটো খোলা হৈছে। অধিক জানিবলৈ টিপক।"</string>
     <string name="app_info" msgid="6856026610594615344">"এপ্ সম্পৰ্কীয় তথ্য"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ৱেবলৈ যাওক"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ম\'বাইল ডেটা"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 2342a89..07476aa 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Batareya doldurulur, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> faiz."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Bütün bildirişlərə baxın"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Adsız cihaz"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Yayıma hazırdır"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Heç bir cihaz əlçatan deyil"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi qoşulu deyil"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Parlaqlıq"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AVTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Rəngləri çevirin"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ekranınızda olan hər şeyin şəklini çəkəcək."</string>
     <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="8035284146227267681">"Bildirişləri idarə edin"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"İdarə edin"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> kimi daxil olunub"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"İnternet yoxdur"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Detalları açın."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> səbəbi ilə əlçatan deyil"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ayarlarını açın."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Ayarların sıralanmasını redaktə edin."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> səhifədən <xliff:g id="ID_1">%1$d</xliff:g> səhifə"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 47422b2..db3834b 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -175,7 +175,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_charging" msgid="1147587904439319646">"Baterija se puni, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procenata."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Pogledajte sva obaveštenja"</string>
@@ -321,6 +321,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovani uređaj"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spremno za prebacivanje"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nije dostupan nijedan uređaj"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi nije povezan"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Osvetljenost"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATSKA"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Obrni boje"</string>
@@ -446,7 +447,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> će početi da snima sve što se prikazuje na ekranu."</string>
     <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="8035284146227267681">"Upravljajte obaveštenjima"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljajte"</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>
@@ -788,6 +789,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Prijavljeni ste kao <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nema interneta"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Otvori detalje."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nije dostupno iz sledećeg razloga: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otvori podešavanja za <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Izmeni redosled podešavanja."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. strana od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index de01516..7b19b36 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -178,7 +178,7 @@
     <!-- String.format failed for translation -->
     <!-- no translation found for accessibility_battery_level (7451474187113371965) -->
     <skip />
-    <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Зарадка акумулятара, працэнтаў: <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Паказаць усе апавяшчэнні"</string>
@@ -325,6 +325,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Прылада без назвы"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Гатова для трансляцыі"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Няма даступных прылад"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi не падключаны"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркасць"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АЎТА"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Інвертаваць колеры"</string>
@@ -452,7 +453,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> атрымае доступ да ўсяго, што адлюстроўваецца на вашым экране."</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="8035284146227267681">"Кіраванне апавяшчэннямі"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Кіраваць"</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>
@@ -796,6 +797,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Вы ўвайшлі як <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Не падключана да інтэрнэту"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Паказаць падрабязную інфармацыю."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Прычына недаступнасці: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Адкрыць налады <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Змяніць парадак налад."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Старонка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 29d89ec..74b1c44 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Батерията се зарежда – <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Вижте всички известия"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Устройство без име"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Готово за предаване"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Няма налични устройства"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"не е установена връзка с Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркост"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТ."</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Инвертиране на цветовете"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ще започне да заснема всичко, което се показва на екрана ви."</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="8035284146227267681">"Управление на известията"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Управление"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Влезли сте като <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Няма връзка с интернет"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Отвaряне на страницата с подробности."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Няма достъп, защото <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Отваряне на настройките за <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Редактиране на подредбата на настройките."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Страница <xliff:g id="ID_1">%1$d</xliff:g> от <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index d2f6401..5223a99 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"নামবিহীন ডিভাইস"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"কাস্ট করার জন্য প্রস্তুত"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"কোনো ডিভাইস উপলব্ধ নয়"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"ওয়াই-ফাই কানেক্ট করা নেই"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"উজ্জ্বলতা"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"স্বয়ং"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"বিপরীত রঙ"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> আপনার স্ক্রীনে দেখানো সব কিছু ক্যাপচার করা শুরু করবে।"</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="8035284146227267681">"বিজ্ঞপ্তি পরিচালনা করুন"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"পরিচালনা করুন"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> হিসেবে প্রবেশ করে রয়েছেন"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ইন্টারনেট কানেকশন নেই"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"বিশদ বিবরণ খুলুন৷"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g>-এর জন্য পাওয়া যাবে না"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> সেটিংস খুলুন৷"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ক্রম বা সেটিংস সম্পাদনা করুন৷"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>টির মধ্যে <xliff:g id="ID_1">%1$d</xliff:g> নং পৃষ্ঠা"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"স্টোরেজ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"হিন্ট"</string>
     <string name="instant_apps" msgid="6647570248119804907">"ঝটপট অ্যাপ"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> চলছে"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"অ্যাপটি ইনস্টল না করে চালু করা হয়েছে।"</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"অ্যাপটি ইনস্টল না করে চালু করা হয়েছে। আরও জানতে ট্যাপ করুন।"</string>
     <string name="app_info" msgid="6856026610594615344">"অ্যাপের তথ্য"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ওয়েবে যান"</string>
     <string name="mobile_data" msgid="7094582042819250762">"মোবাইল ডেটা"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index ac0c05e..ca09219 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -175,7 +175,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_charging" msgid="1147587904439319646">"Punjenje baterije, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procenata."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Vidite sva obavještenja"</string>
@@ -321,6 +321,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovani uređaj"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spreman za emitiranje"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nema dostupnih uređaja"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi mreža nije povezana"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Osvjetljenje"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverzija boja"</string>
@@ -446,7 +447,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> će početi snimati sve što se prikaže na ekranu."</string>
     <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="8035284146227267681">"Upravljajte obavještenjima"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljaj"</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>
@@ -790,6 +791,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Prijavljeni ste kao <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nema internetske veze"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Otvori detalje."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nije dostupno jer <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otvori postavke za: <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Urediti raspored postavki."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index b4a2f3b..7b4fdad 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -63,7 +63,7 @@
     <string name="always_use_device" msgid="4015357883336738417">"Obre sempre <xliff:g id="APPLICATION">%1$s</xliff:g> quan es connecti <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
     <string name="always_use_accessory" msgid="3257892669444535154">"Obre sempre <xliff:g id="APPLICATION">%1$s</xliff:g> quan es connecti <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Vols permetre la depuració per USB?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"L\'empremta digital de la clau de RSA de l\'equip és:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"L\'empremta digital de la clau RSA de l\'equip és:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Dona sempre permís des d\'aquest equip"</string>
     <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>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositiu sense nom"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"A punt per emetre"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No hi ha cap dispositiu disponible."</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"La Wi‑Fi no està connectada"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillantor"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÀTICA"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverteix els colors"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> començarà a gravar tot el que es mostri a la pantalla."</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="8035284146227267681">"Gestiona les notificacions"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gestió"</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>
@@ -659,7 +660,7 @@
     <string name="keyboard_key_dpad_left" msgid="1346446024676962251">"Esquerra"</string>
     <string name="keyboard_key_dpad_right" msgid="3317323247127515341">"Dreta"</string>
     <string name="keyboard_key_dpad_center" msgid="2566737770049304658">"Centre"</string>
-    <string name="keyboard_key_tab" msgid="3871485650463164476">"Pestanya"</string>
+    <string name="keyboard_key_tab" msgid="3871485650463164476">"Tabulador"</string>
     <string name="keyboard_key_space" msgid="2499861316311153293">"Espai"</string>
     <string name="keyboard_key_enter" msgid="5739632123216118137">"Retorn"</string>
     <string name="keyboard_key_backspace" msgid="1559580097512385854">"Retrocés"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"S\'ha iniciat la sessió com a <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Sense connexió a Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Obre la informació detallada."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"No està disponible pel motiu següent: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Obre la configuració per a <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edita l\'ordre de la configuració."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pàgina <xliff:g id="ID_1">%1$d</xliff:g> (<xliff:g id="ID_2">%2$d</xliff:g> en total)"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 6d4af4a..f8f79ce 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -176,9 +176,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Zobrazit všechna oznámení"</string>
@@ -325,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nepojmenované zařízení"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Připraveno k vysílání"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nejsou dostupná žádná zařízení"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Není připojena Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jas"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Převrátit barvy"</string>
@@ -452,7 +451,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikace <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> začne zaznamenávat vše, co je zobrazeno na obrazovce."</string>
     <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="8035284146227267681">"Spravovat oznámení"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Spravovat"</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>
@@ -796,6 +795,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Jste přihlášeni jako <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nejste připojeni k internetu"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Otevřít podrobnosti."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nedostupné, protože <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otevřít nastavení aplikace <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Upravit pořadí nastavení."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Stránka <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index ade7db1..7894361 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Batteriet oplades. <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</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">"Underretninger."</string>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Se alle underretninger"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Enhed uden navn"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Klar til at caste"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Der er ingen tilgængelige enheder"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Manglende Wi-Fi-forbindelse"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Lysstyrke"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Byt om på farver"</string>
@@ -362,15 +363,15 @@
     <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> kunne ikke startes."</string>
     <string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> er deaktiveret i sikker tilstand."</string>
     <string name="recents_stack_action_button_label" msgid="6593727103310426253">"Ryd alle"</string>
-    <string name="recents_drag_hint_message" msgid="2649739267073203985">"Træk hertil for at bruge delt skærm"</string>
+    <string name="recents_drag_hint_message" msgid="2649739267073203985">"Træk hertil for at bruge opdelt skærm"</string>
     <string name="recents_swipe_up_onboarding" msgid="3824607135920170001">"Stryg opad for at skifte apps"</string>
     <string name="recents_quick_scrub_onboarding" msgid="2778062804333285789">"Træk til højre for hurtigt at skifte app"</string>
     <string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"Opdel vandret"</string>
     <string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"Opdel lodret"</string>
     <string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"Opdel brugerdefineret"</string>
-    <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"Delt skærm øverst"</string>
-    <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"Delt skærm til venstre"</string>
-    <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"Delt skærm til højre"</string>
+    <string name="recents_accessibility_split_screen_top" msgid="9056056469282256287">"Opdelt skærm øverst"</string>
+    <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"Opdelt skærm til venstre"</string>
+    <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"Opdelt skærm til højre"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7171470775439860480">"Slå Oversigt til/fra"</string>
     <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Opladet"</string>
     <string name="expanded_header_battery_charging" msgid="205623198487189724">"Oplader"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vil begynde at optage alt, hvad der vises på din skærm."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Vis ikke igen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Ryd alt"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Administrer underretninger"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Administrer"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Underretninger 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 underretninger"</string>
@@ -752,7 +753,7 @@
     <item msgid="3327323682209964956">"Vis ikke dette ikon"</item>
   </string-array>
     <string name="other" msgid="4060683095962566764">"Andet"</string>
-    <string name="accessibility_divider" msgid="5903423481953635044">"Adskiller til delt skærm"</string>
+    <string name="accessibility_divider" msgid="5903423481953635044">"Adskiller til opdelt skærm"</string>
     <string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"Vis venstre del i fuld skærm"</string>
     <string name="accessibility_action_divider_left_70" msgid="3612060638991687254">"Venstre 70 %"</string>
     <string name="accessibility_action_divider_left_50" msgid="1248083470322193075">"Venstre 50 %"</string>
@@ -771,8 +772,8 @@
     <string name="accessibility_qs_edit_tile_move" msgid="3108103090006972938">"Flyt <xliff:g id="TILE_NAME">%1$s</xliff:g> til position <xliff:g id="POSITION">%2$d</xliff:g>"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Redigeringsværktøj for Hurtige indstillinger."</string>
     <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"<xliff:g id="ID_1">%1$s</xliff:g>-underretning: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
-    <string name="dock_forced_resizable" msgid="5914261505436217520">"Appen fungerer muligvis ikke i delt skærm."</string>
-    <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen understøtter ikke delt skærm."</string>
+    <string name="dock_forced_resizable" msgid="5914261505436217520">"Appen fungerer muligvis ikke i opdelt skærm."</string>
+    <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"Appen understøtter ikke opdelt skærm."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"Appen fungerer muligvis ikke på sekundære skærme."</string>
     <string name="activity_launch_on_secondary_display_failed_text" msgid="7793821742158306742">"Appen kan ikke åbnes på sekundære skærme."</string>
     <string name="accessibility_quick_settings_settings" msgid="6132460890024942157">"Åbn Indstillinger."</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Logget ind som <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Intet internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Åbn oplysninger."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Ikke tilgængelig på grund af <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Åbn <xliff:g id="ID_1">%s</xliff:g>-indstillinger."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Rediger rækkefølgen af indstillinger."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Side <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 06aac5c..47aaaed 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -323,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unbenanntes Gerät"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Startklar"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Keine Geräte verfügbar"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"WLAN nicht verbunden"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helligkeit"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Farben umkehren"</string>
@@ -446,7 +447,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> nimmt alle auf deinem Bildschirm angezeigten Aktivitäten auf."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Nicht erneut anzeigen"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Alle löschen"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Benachrichtigungen verwalten"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Verwalten"</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>
@@ -786,6 +787,7 @@
     <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>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Aus diesem Grund nicht verfügbar: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Einstellungen für <xliff:g id="ID_1">%s</xliff:g> öffnen."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Reihenfolge der Einstellungen bearbeiten."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Seite <xliff:g id="ID_1">%1$d</xliff:g> von <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -858,10 +860,10 @@
     <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>
-    <string name="auto_saver_text" msgid="6324376061044218113">"Automatisch aktivieren bei einem Akkustand von <xliff:g id="PERCENTAGE">%d</xliff:g>%%"</string>
+    <string name="auto_saver_text" msgid="6324376061044218113">"Automatisch aktivieren bei einem Akkustand von <xliff:g id="PERCENTAGE">%d</xliff:g> %%"</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>
+    <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>
     <string name="open_saver_setting_action" msgid="8314624730997322529">"Einstellungen"</string>
     <string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 1892da6..ea16ba4 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Φόρτιση μπαταρίας, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Δείτε όλες τις ειδοποιήσεις"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Ανώνυμη συσκευή"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Έτοιμο για μετάδοση"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Δεν υπάρχουν διαθέσιμες συσκευές"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Το Wi-Fi δεν είναι συνδεδεμένο"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Φωτεινότητα"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ΑΥΤΟΜΑΤΗ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Αντιστροφή χρωμάτων"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Θα ξεκινήσει η καταγραφή του περιεχομένου που εμφανίζεται στην οθόνη σας από την εφαρμογή <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>."</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="8035284146227267681">"Διαχείριση ειδοποιήσεων"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Διαχείριση"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Σύνδεση ως <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Δεν υπάρχει σύνδεση στο διαδίκτυο"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Άνοιγμα λεπτομερειών."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Μη διαθέσιμα λόγω <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Άνοιγμα ρυθμίσεων <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Επεξεργασία σειράς ρυθμίσεων."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Σελίδα <xliff:g id="ID_1">%1$d</xliff:g> από <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 6503470..b7da383 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ready to cast"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No devices available"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi‑Fi not connected"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invert colours"</string>
@@ -442,8 +443,8 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will start capturing everything that\'s displayed on your screen."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Don\'t show again"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Clear all"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Manage notifications"</string>
-    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications paused by Do not disturb"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Manage"</string>
+    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start now"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No notifications"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profile may be monitored"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"No Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Open details."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Unvailable due to <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit order of settings."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 9e4081c..19e9b64 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ready to cast"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No devices available"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi‑Fi not connected"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invert colours"</string>
@@ -442,8 +443,8 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will start capturing everything that\'s displayed on your screen."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Don\'t show again"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Clear all"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Manage notifications"</string>
-    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications paused by Do not disturb"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Manage"</string>
+    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start now"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No notifications"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profile may be monitored"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"No Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Open details."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Unvailable due to <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit order of settings."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 6503470..b7da383 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ready to cast"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No devices available"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi‑Fi not connected"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invert colours"</string>
@@ -442,8 +443,8 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will start capturing everything that\'s displayed on your screen."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Don\'t show again"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Clear all"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Manage notifications"</string>
-    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications paused by Do not disturb"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Manage"</string>
+    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start now"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No notifications"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profile may be monitored"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"No Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Open details."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Unvailable due to <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit order of settings."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 6503470..b7da383 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Unnamed device"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ready to cast"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No devices available"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi‑Fi not connected"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invert colours"</string>
@@ -442,8 +443,8 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> will start capturing everything that\'s displayed on your screen."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Don\'t show again"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Clear all"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Manage notifications"</string>
-    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications paused by Do not disturb"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Manage"</string>
+    <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifications paused by Do Not Disturb"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Start now"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"No notifications"</string>
     <string name="profile_owned_footer" msgid="8021888108553696069">"Profile may be monitored"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Signed in as <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"No Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Open details."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Unvailable due to <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Open <xliff:g id="ID_1">%s</xliff:g> settings."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit order of settings."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> of <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index 40205b9..97ddf61 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‏‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‎‎‎‏‏‎‎‎‎‎‏‏‏‏‏‎‎‏‎‎‎‎‎‏‏‏‏‎‏‎‏‏‎‎‎‎‏‎Unnamed device‎‏‎‎‏‎"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‏‎‎‏‏‏‏‎‏‎‏‏‏‏‏‎‏‎‏‎‎‏‏‎‎‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎Ready to cast‎‏‎‎‏‎"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‎‏‏‏‎‎‎‏‎‏‎‎‏‏‏‎‏‎‏‏‏‏‏‎‎‎‏‏‎‏‎‏‏‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‏‏‎‎‏‏‏‎‏‎‏‏‏‏‎No devices available‎‏‎‎‏‎"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‏‎‏‎‏‏‎‏‎‏‏‏‏‎‏‎‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‎‏‏‏‏‎‏‎‏‏‎‏‎‎‏‎‎‏‎‎‏‏‎‏‏‎‏‎‎Wi‑Fi not connected‎‏‎‎‏‎"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‏‏‏‏‏‏‏‎‎‎‎‎‏‏‏‏‏‏‎‎‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‏‏‎‎‎‎Brightness‎‏‎‎‏‎"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‏‎‎‏‎‎‏‎‏‎‎‏‏‎‏‏‏‎‏‏‏‏‏‎‎‎‎‏‎‏‎‏‎‎‏‎‏‏‏‎‏‏‏‎‏‎‎‎‎‎‎‎‏‏‎‎‏‎‎AUTO‎‏‎‎‏‎"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‏‎‎‎‎‏‏‏‏‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎Invert colors‎‏‎‎‏‎"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‏‎‏‎‏‎‎‎‏‏‏‏‏‎‏‎‎‏‎‏‏‏‏‏‏‏‎‏‎‎‎‏‏‏‎‎‎‏‎‎‏‏‎‎‎‎‎‎‏‎‎‏‏‎<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>‎‏‎‎‏‏‏‎ will start capturing everything that\'s displayed on your screen.‎‏‎‎‏‎"</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‎‏‏‎‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‎‏‏‏‏‎‎‎‎‎‎‎‎‎‎‎Don\'t show again‎‏‎‎‏‎"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‏‏‎‏‎‎‏‏‎‎‏‎‎‏‏‎‎‎‎‎‎‏‏‏‏‎‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‎‎‎‏‎‎‎‎‏‎‏‎‏‏‎‎‎Clear all‎‏‎‎‏‎"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‎‎‎‏‏‎‎‎‏‎‎‎‎‎‏‎‏‏‎‏‏‏‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎‏‎‎‎‎‏‏‎‎‎‎‏‎Manage notifications‎‏‎‎‏‎"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‏‏‏‏‎‏‎‏‏‏‎‎‏‎‎‏‏‎‏‎‎‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‎‎‏‎Manage‎‏‎‎‏‎"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎‎‎‏‎‏‏‏‏‎‎‏‏‏‎‎‎‎‎‎‎‎‏‎‎‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‎Notifications paused by Do Not Disturb‎‏‎‎‏‎"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‏‏‎‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‏‎‎‎‏‎‎Start now‎‏‎‎‏‎"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‎‏‎‎‏‏‏‎‏‎‎‏‏‏‏‎‎‏‏‎‏‏‎‏‎‏‏‏‎‏‎‎‏‏‏‎‏‎‎‏‏‎‏‏‎‎‎‎‎‎‏‏‎‏‎‏‏‏‎‏‎‎No notifications‎‏‎‎‏‎"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‏‎‎‏‏‎‎‎‏‎‎‏‎‎‎‎‏‎‏‎‎Signed in as ‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‏‎‎‎‏‏‎‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‏‏‎‏‎‎‏‏‏‏‎‏‎No internet‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‏‎‏‏‎‏‏‏‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‎‏‎‏‎‎‏‏‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‎‎‎‏‎‎‏‎‏‎‎Open details.‎‏‎‎‏‎"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‏‎‎‎‏‎‎‏‏‎‎‎‎‏‏‏‎‎‏‏‎‏‎‎‎‎‎‏‎‎‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‏‎‎‎‎‎‏‏‎‎Unvailable due to ‎‏‎‎‏‏‎<xliff:g id="REASON">%s</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‎‏‎‏‏‎‏‎‏‎‏‎‎‏‏‏‎‏‏‏‏‎‎‎‏‎‏‎‎‎‏‏‏‏‎‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‏‎Open ‎‏‎‎‏‏‎<xliff:g id="ID_1">%s</xliff:g>‎‏‎‎‏‏‏‎ settings.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‏‎‎‏‏‎‏‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‎‏‎‎‎‏‎‏‏‏‏‏‎‏‏‎‏‏‎‎‏‎‎‏‏‏‎‎‏‎‎‏‎Edit order of settings.‎‏‎‎‏‎"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‏‎‏‏‎‎‎‏‎‏‏‏‎‏‏‏‏‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‎‏‎‎‎‏‎Page ‎‏‎‎‏‏‎<xliff:g id="ID_1">%1$d</xliff:g>‎‏‎‎‏‏‏‎ of ‎‏‎‎‏‏‎<xliff:g id="ID_2">%2$d</xliff:g>‎‏‎‎‏‏‏‎‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index d4adfdc..35499f0 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ver todas las notificaciones"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sin nombre"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Listo para transmitir"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No hay dispositivos disponibles"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"La red Wi-Fi no está conectada"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invertir colores"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> comenzará la captura de todo lo que se muestre en la pantalla."</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="8035284146227267681">"Administrar notificaciones"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Administrar"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Accediste como <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Sin Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Abrir página de detalles"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"No disponible debido a <xliff:g id="REASON">%s</xliff:g>"</string>
     <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>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 00c179c..54364a5 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ver todas las notificaciones"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sin nombre"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Listo para enviar"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"No hay dispositivos disponibles"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi‑Fi sin conexión"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invertir colores"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> empezará a capturar todo lo que aparezca en la pantalla."</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="8035284146227267681">"Gestionar notificaciones"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gestionar"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Has iniciado sesión como <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Sin Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Abrir detalles."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"No disponible (<xliff:g id="REASON">%s</xliff:g>)"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir ajustes de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Cambiar el orden de los ajustes."</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>
@@ -828,8 +828,8 @@
     <string name="notification_channel_hints" msgid="7323870212489152689">"Sugerencias"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Aplicaciones Instantáneas"</string>
     <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> se está ejecutando"</string>
-    <string name="instant_apps_message" msgid="1183313016396018086">"La aplicación se abre sin necesidad de instalarla."</string>
-    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"La aplicación se abre sin necesidad de instalarla. Toca para obtener más información."</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"La aplicación se ha abierto sin instalarse."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"La aplicación se ha abierto sin instalarse. Toca para obtener más información."</string>
     <string name="app_info" msgid="6856026610594615344">"Información de la aplicación"</string>
     <string name="go_to_web" msgid="1106022723459948514">"Ir a la Web"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Datos móviles"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 246f1f8..90e9334 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Kõikide märguannete kuvamine"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nimeta seade"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Valmis ülekandmiseks"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Ühtegi seadet pole saadaval"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"WiFi-ühendus puudub"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Heledus"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAATNE"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Vaheta värve"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> hakkab jäädvustama kõike, mida ekraanil kuvatakse."</string>
     <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="8035284146227267681">"Märguannete haldamine"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Haldamine"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Sisse logitud kasutajana <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Interneti-ühendus puudub"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Ava üksikasjad."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Põhjuse <xliff:g id="REASON">%s</xliff:g> tõttu pole saadaval"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Ava teenuse <xliff:g id="ID_1">%s</xliff:g> seaded."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Muuda seadete järjestust."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Leht <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index b73946e..c6314e4 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ikusi jakinarazpen guztiak"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Izenik gabeko gailua"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Igortzeko prest"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Ez dago gailurik erabilgarri"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Ez zaude konektatuta Wi-Fi sarera"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Distira"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIKOA"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Alderantzikatu koloreak"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak pantailan bistaratzen den guztia grabatuko du."</string>
     <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="8035284146227267681">"Kudeatu jakinarazpenak"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Kudeatu"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> gisa hasi duzu saioa"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Ez dago Interneteko konexiorik"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Ireki xehetasunak."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Ez dago erabilgarri arrazoi honengatik: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Ireki <xliff:g id="ID_1">%s</xliff:g> ezarpenak."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editatu ezarpenen ordena."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g> orria"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 3997f1a..ca38030 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"دستگاه بدون نام"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"آماده برای فرستادن"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"دستگاهی موجود نیست"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"‏Wi-Fi وصل نیست"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"روشنایی"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"خودکار"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"برگردان رنگ‌ها"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> شروع به ضبط هر چیزی می‌کند که در صفحه‌نمایش شما نمایش داده می‌شود."</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="8035284146227267681">"مدیریت اعلان‌ها"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"مدیریت"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"با <xliff:g id="ID_1">%s</xliff:g> به سیستم وارد شده‌اید"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"عدم اتصال به اینترنت"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"باز کردن جزئیات."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"به‌دلیل <xliff:g id="REASON">%s</xliff:g> دردسترس نیست"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"باز کردن تنظیمات <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ویرایش ترتیب تنظیمات."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"صفحه <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 6e8cb4c..412bee1 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nimetön laite"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Valmis lähetystä varten"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Laitteita ei ole käytettävissä"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fiä ei ole yhdistetty"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kirkkaus"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Käänteiset värit"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> alkaa tallentaa kaiken näytölläsi näkyvän."</string>
     <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="8035284146227267681">"Hallinnoi ilmoituksia"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Muuta asetuksia"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Kirjautunut tilillä <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Ei internetyhteyttä"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Avaa tiedot."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Ei käytettävissä, koska <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Avaa kohteen <xliff:g id="ID_1">%s</xliff:g> asetukset."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Muokkaa asetusten järjestystä."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Sivu <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index f6d66b7..8821178 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Afficher toutes les notifications"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Appareil sans nom"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Prêt à diffuser"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Aucun appareil à proximité"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Non connecté au Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverser les couleurs"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> commencer à enregistrer tout ce qui s\'affiche sur votre écran."</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="8035284146227267681">"Gérer les notifications"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gérer"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Connecté comme <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Aucune connexion Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Ouvrir les détails."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Non disponible pour la raison suivante : <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Ouvrir les paramètres <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Modifier l\'ordre des paramètres."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 326b7c7..e37722a 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Afficher toutes les notifications"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Appareil sans nom"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Prêt à caster"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Aucun appareil disponible."</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi non connecté"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosité"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATIQUE"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverser les couleurs"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> va commencer à capturer tous les contenus affichés à l\'écran."</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="8035284146227267681">"Gérer les notifications"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gérer"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Connecté en tant que <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Aucun accès à Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Ouvrir les détails."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Indisponible pour la raison suivante : <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Ouvrir les paramètres <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Modifier l\'ordre des paramètres."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> sur <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 192c132..80f3c93 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ver todas as notificacións"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sen nome"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Listo para emitir"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Non hai dispositivos dispoñibles"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"A wifi non está conectada"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brillo"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverter cores"</string>
@@ -403,9 +402,9 @@
     <string name="interruption_level_none_twoline" msgid="3957581548190765889">"Silencio\ntotal"</string>
     <string name="interruption_level_priority_twoline" msgid="1564715335217164124">"Só\nprioridade"</string>
     <string name="interruption_level_alarms_twoline" msgid="3266909566410106146">"Só\nalarmas"</string>
-    <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> para rematar a carga)"</string>
-    <string name="keyguard_indication_charging_time_fast" msgid="7767562163577492332">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando rapidamente (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> para rematar a carga)"</string>
-    <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> para rematar a carga)"</string>
+    <string name="keyguard_indication_charging_time" msgid="2056340799276374421">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> para completar a carga)"</string>
+    <string name="keyguard_indication_charging_time_fast" msgid="7767562163577492332">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando rapidamente (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> para completar a carga)"</string>
+    <string name="keyguard_indication_charging_time_slowly" msgid="3769655133567307069">"<xliff:g id="PERCENTAGE">%2$s</xliff:g> • Cargando lentamente (<xliff:g id="CHARGING_TIME_LEFT">%1$s</xliff:g> para completar a carga)"</string>
     <string name="accessibility_multi_user_switch_switcher" msgid="7305948938141024937">"Cambiar usuario"</string>
     <string name="accessibility_multi_user_switch_switcher_with_current" msgid="8434880595284601601">"Cambiar usuario, usuario actual: <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
     <string name="accessibility_multi_user_switch_inactive" msgid="1424081831468083402">"Usuario actual <xliff:g id="CURRENT_USER_NAME">%s</xliff:g>"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> comezará a capturar todo o que apareza na túa pantalla."</string>
     <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="8035284146227267681">"Xestionar notificacións"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Xestionar"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Iniciaches sesión como <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Non hai conexión a Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Abrir detalles."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Opcións non-dispoñibles polo seguinte motivo: <xliff:g id="REASON">%s</xliff:g>"</string>
     <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 a orde das opcións de configuración."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Páxina <xliff:g id="ID_1">%1$d</xliff:g> de <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index f392268..cf5692b 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"બૅટરી ચાર્જ થઈ રહી છે, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"બધી સૂચના જુઓ"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"અનામાંકિત ઉપકરણ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"કાસ્ટ કરવા માટે તૈયાર"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"કોઈ ઉપકરણો ઉપલબ્ધ નથી"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"વાઇ-ફાઇ કનેક્ટ નથી"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"તેજ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"સ્વતઃ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"રંગોને ઉલટાવો"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> તમારી સ્ક્રીન પર જે પ્રદર્શિત થાય છે તે દરેક વસ્તુને કેપ્ચર કરવાનું પ્રારંભ કરશે."</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="8035284146227267681">"સૂચનાઓને મેનેજ કરો"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"મેનેજ કરો"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> તરીકે સાઇન ઇન કર્યું"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"કોઈ ઇન્ટરનેટ નથી"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"વિગતો ખોલો."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g>ને કારણે અનુપલબ્ધ છે"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> સેટિંગ્સ ખોલો."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"સેટિંગ્સનો ક્રમ સંપાદિત કરો."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> માંથી <xliff:g id="ID_1">%1$d</xliff:g> પૃષ્ઠ"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"સ્ટોરેજ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"હિન્ટ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"ઝટપટ ઍપ્લિકેશનો"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> ચાલી રહી છે"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"ઍપ ઇન્સ્ટૉલ કર્યા વિના ખુલી જાય છે."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ઍપ ઇન્સ્ટૉલ કર્યા વિના ખુલી જાય છે. વધુ જાણવા માટે ટૅપ કરો."</string>
     <string name="app_info" msgid="6856026610594615344">"ઍપ્લિકેશન માહિતી"</string>
     <string name="go_to_web" msgid="1106022723459948514">"વેબ પર જાઓ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"મોબાઇલ ડેટા"</string>
@@ -857,10 +856,10 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"મંજૂરી આપો"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"નકારો"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"બૅટરી સેવર શેડ્યૂલ કરવા માટે ટૅપ કરો"</string>
-    <string name="auto_saver_text" msgid="6324376061044218113">"બૅટરીનું સ્તર <xliff:g id="PERCENTAGE">%d</xliff:g>%% પર હોય ત્યારે આપમેળે ચાલુ કરો"</string>
+    <string name="auto_saver_text" msgid="6324376061044218113">"બૅટરીનું સ્તર <xliff:g id="PERCENTAGE">%d</xliff:g>%% પર હોય ત્યારે ઑટોમૅટિક રીતે ચાલુ કરો"</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>
+    <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">"સમજાઈ ગયું"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 8795264..ac34e9a 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"बैटरी चार्ज हो रही है, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"पूरी सूचनाएं देखें"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"अनाम डिवाइस"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"कास्ट करने के लिए तैयार"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"कोई डिवाइस उपलब्ध नहीं"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"वाई-फ़ाई कनेक्ट नहीं है"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"स्क्रीन की रोशनी"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वत:"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"रंग उलटें"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> आपके स्क्रीन पर दिखाई देने वाली हर सामग्री को कैप्चर करना शुरू कर देगी."</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="8035284146227267681">"सूचनाएं प्रबंधित करें"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"प्रबंधित करें"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> के रूप में प्रवेश किया हुआ है"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"इंटरनेट कनेक्शन नहीं है"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"विवरण खोलें."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> की वजह से मौजूद नहीं है"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग खोलें."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"सेटिंग के क्रम को बदलें"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"पेज <xliff:g id="ID_2">%2$d</xliff:g> में से <xliff:g id="ID_1">%1$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index b6fa4f5..5df6999 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -321,6 +321,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Uređaj bez naziva"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Spreman za emitiranje"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nema dostupnih uređaja"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi mreža nije povezana"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Svjetlina"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATSKI"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Zamjena boja"</string>
@@ -446,7 +447,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> počet će snimati sve što se prikazuje na zaslonu."</string>
     <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="8035284146227267681">"Upravljanje obavijestima"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljajte"</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>
@@ -788,6 +789,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Prijavljeni ste kao <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nema interneta"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Otvaranje pojedinosti."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nije dostupno jer <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otvaranje postavki za <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Uređivanje redoslijeda postavki."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Stranica <xliff:g id="ID_1">%1$d</xliff:g> od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -850,7 +852,7 @@
     <string name="running_foreground_services_title" msgid="381024150898615683">"Izvođenje aplikacija u pozadini"</string>
     <string name="running_foreground_services_msg" msgid="6326247670075574355">"Dodirnite da biste vidjeli pojedinosti o potrošnji baterije i podatkovnom prometu"</string>
     <string name="mobile_data_disable_title" msgid="1068272097382942231">"Želite li isključiti mobilne podatke?"</string>
-    <string name="mobile_data_disable_message" msgid="4756541658791493506">"Nećete imati pristup mobilnim podacima ili internetu putem operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem Wi-Fi-ja."</string>
+    <string name="mobile_data_disable_message" msgid="4756541658791493506">"Nećete imati pristup mobilnim podacima ili internetu putem operatera <xliff:g id="CARRIER">%s</xliff:g>. Internet će biti dostupan samo putem Wi-Fija."</string>
     <string name="mobile_data_disable_message_default_carrier" msgid="6078110473451946831">"vaš mobilni operater"</string>
     <string name="touch_filtered_warning" msgid="8671693809204767551">"Budući da aplikacija prekriva zahtjev za dopuštenje, Postavke ne mogu potvrditi vaš odgovor."</string>
     <string name="slice_permission_title" msgid="7465009437851044444">"Želite li dopustiti aplikaciji <xliff:g id="APP_0">%1$s</xliff:g> da prikazuje isječke aplikacije <xliff:g id="APP_2">%2$s</xliff:g>?"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 9076379..f09a8b3 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Név nélküli eszköz"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Küldésre kész"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nem áll rendelkezésre eszköz"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Nem kapcsolódik Wi‑Fi-hálózathoz"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Fényerő"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"automatikus"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Színek invertálása"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"A(z) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> alkalmazás rögzíteni fog mindent, ami megjelenik a képernyőn."</string>
     <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="8035284146227267681">"Az értesítések kezelése"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Kezelés"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Bejelentkezve mint <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nincs internetkapcsolat"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"A részletek megnyitása."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nem áll rendelkezésre a következő ok miatt: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"A(z) <xliff:g id="ID_1">%s</xliff:g> beállításainak megnyitása."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Beállítások sorrendjének szerkesztése."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. oldal, összesen: <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 54401f5..8973ecf 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Անանուն սարք"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Պատրաստ է հեռարձակման"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Հասանելի սարքեր չկան"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi-ը միացված չէ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Պայծառություն"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Ավտոմատ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Շրջել գույները"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ծրագիրը կսկսի հավաքել այն ամենն ինչ ցուցադրվում է ձեր էկրանին:"</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="8035284146227267681">"Կառավարել ծանուցումները"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Կառավարել"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Մուտք է գործել որպես <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Ինտերնետ կապ չկա"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Բացել մանրամասները:"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Անհասանելի է, քանի որ <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Բացել <xliff:g id="ID_1">%s</xliff:g> կարգավորումները:"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Խմբագրել կարգավորումների հերթականությունը:"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Էջ <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 2474158..2e3040c 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Perangkat tanpa nama"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Siap melakukan transmisi"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Perangkat tak tersedia"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi‑Fi tidak terhubung"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATIS"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inversi warna"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan mulai menangkap apa saja yang ditampilkan pada layar Anda."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Jangan tampilkan lagi"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Hapus semua"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Kelola notifikasi"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Kelola"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifikasi dijeda oleh mode Jangan Ganggu"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Mulai sekarang"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Tidak ada notifikasi"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Login sebagai <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Tidak ada internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Buka detail."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Tidak tersedia karena <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Buka setelan <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit urutan setelan."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> dari <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index c2a020b..fd15fc3 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Rafhlaða í hleðslu, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> prósent."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Sjá allar tilkynningar"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Ónefnt tæki"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Tilbúið í útsendingu"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Engin tæki til staðar"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi ekki tengt"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Birtustig"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"SJÁLFVIRKT"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Umsnúa litum"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> mun fanga allt sem birtist á skjánum."</string>
     <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="8035284146227267681">"Stjórna tilkynningum"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Stjórna"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Skráð(ur) inn sem <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Engin nettenging"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Opna upplýsingasíðu."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Ekki tiltækt vegna <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Opna <xliff:g id="ID_1">%s</xliff:g> stillingar."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Breyta röð stillinga."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Blaðsíða <xliff:g id="ID_1">%1$d</xliff:g> af <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index aefaa6d..37fabb8 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Visualizza tutte le notifiche"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo senza nome"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Pronto a trasmettere"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nessun dispositivo disponibile"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Nessuna connessione Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminosità"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverti colori"</string>
@@ -351,8 +350,8 @@
     <string name="quick_settings_night_display_label" msgid="3577098011487644395">"Luminosità notturna"</string>
     <string name="quick_settings_night_secondary_label_on_at_sunset" msgid="8483259341596943314">"Attivata al tramonto"</string>
     <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">"Attiva alle <xliff:g id="TIME">%s</xliff:g>"</string>
-    <string name="quick_settings_secondary_label_until" msgid="2749196569462600150">"Fino alle ore <xliff:g id="TIME">%s</xliff:g>"</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_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>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> inizierà ad acquisire tutto ciò che è visualizzato sul tuo schermo."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Non mostrare più"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Cancella tutto"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Gestisci le notifiche"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gestisci"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Notifiche messe in pausa in base alla modalità Non disturbare"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Avvia adesso"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Nessuna notifica"</string>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Accesso eseguito come <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nessuna connessione a Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Apri i dettagli."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Non disponibile a causa di un problema <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Apri le impostazioni <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Modifica l\'ordine delle impostazioni."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> di <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index b83f5df..0d60e6c 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -33,7 +33,7 @@
     </plurals>
     <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"אין הודעות"</string>
     <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"מתמשך"</string>
-    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"הודעות"</string>
+    <string name="status_bar_latest_events_title" msgid="6594767438577593172">"התראות"</string>
     <string name="battery_low_title" msgid="9187898087363540349">"ייתכן שהסוללה תתרוקן בקרוב"</string>
     <string name="battery_low_percent_format" msgid="2900940511201380775">"נותרו <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
     <string name="battery_low_percent_format_hybrid" msgid="6838677459286775617">"נותרו <xliff:g id="PERCENTAGE">%1$s</xliff:g>, נשארו בערך <xliff:g id="TIME">%2$s</xliff:g> על סמך השימוש במכשיר"</string>
@@ -51,7 +51,7 @@
     <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"סיבוב אוטומטי של המסך"</string>
     <string name="status_bar_settings_mute_label" msgid="554682549917429396">"השתק"</string>
     <string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"אוטומטי"</string>
-    <string name="status_bar_settings_notifications" msgid="397146176280905137">"הודעות"</string>
+    <string name="status_bar_settings_notifications" msgid="397146176280905137">"התראות"</string>
     <string name="bluetooth_tethered" msgid="7094101612161133267">"‏Bluetooth קשור"</string>
     <string name="status_bar_input_method_settings_configure_input_methods" msgid="3504292471512317827">"הגדר שיטות קלט"</string>
     <string name="status_bar_use_physical_keyboard" msgid="7551903084416057810">"מקלדת פיזית"</string>
@@ -176,11 +176,11 @@
     <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_charging" msgid="1147587904439319646">"טעינת סוללה, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
+    <string name="accessibility_notifications_button" msgid="4498000369779421892">"התראות"</string>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"הצגת כל ההודעות"</string>
-    <string name="accessibility_remove_notification" msgid="3603099514902182350">"נקה התראה"</string>
+    <string name="accessibility_remove_notification" msgid="3603099514902182350">"מחיקת התראה"</string>
     <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">"‏TeleTypewriter מופעל"</string>
@@ -195,7 +195,7 @@
     <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"כל האפליקציות האחרונות נסגרו."</string>
     <string name="accessibility_recents_item_open_app_info" msgid="5107479759905883540">"פתח מידע על האפליקציה <xliff:g id="APP">%s</xliff:g>."</string>
     <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"מפעיל את <xliff:g id="APP">%s</xliff:g>."</string>
-    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"הודעה נדחתה."</string>
+    <string name="accessibility_notification_dismissed" msgid="854211387186306927">"התראה נדחתה."</string>
     <string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"לוח התראות."</string>
     <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"הגדרות מהירות."</string>
     <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"מסך נעילה."</string>
@@ -323,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"מכשיר ללא שם"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"מוכן להעביר"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"אין מכשירים זמינים"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"‏אין חיבור ל-Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"בהירות"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"אוטומטי"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"היפוך צבעים"</string>
@@ -342,7 +343,7 @@
       <item quantity="other">‏%d מכשירים</item>
       <item quantity="one">מכשיר אחד</item>
     </plurals>
-    <string name="quick_settings_notifications_label" msgid="4818156442169154523">"הודעות"</string>
+    <string name="quick_settings_notifications_label" msgid="4818156442169154523">"התראות"</string>
     <string name="quick_settings_flashlight_label" msgid="2133093497691661546">"פנס"</string>
     <string name="quick_settings_cellular_detail_title" msgid="3661194685666477347">"חבילת גלישה"</string>
     <string name="quick_settings_cellular_detail_data_usage" msgid="1964260360259312002">"שימוש בנתונים"</string>
@@ -450,7 +451,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> יתחיל להקליט את כל התוכן המוצג במסך שלך."</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="8035284146227267681">"ניהול התראות"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"ניהול"</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>
@@ -542,7 +543,7 @@
     <string name="stream_ring" msgid="8213049469184048338">"צלצול"</string>
     <string name="stream_music" msgid="9086982948697544342">"מדיה"</string>
     <string name="stream_alarm" msgid="5209444229227197703">"שעון מעורר"</string>
-    <string name="stream_notification" msgid="2563720670905665031">"הודעה"</string>
+    <string name="stream_notification" msgid="2563720670905665031">"התראה"</string>
     <string name="stream_bluetooth_sco" msgid="2055645746402746292">"Bluetooth"</string>
     <string name="stream_dtmf" msgid="2447177903892477915">"‏טון זוגי מרובה תדרים (DTMF)"</string>
     <string name="stream_accessibility" msgid="301136219144385106">"נגישות"</string>
@@ -614,8 +615,8 @@
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"פקדים של הודעות הפעלה"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"פועל"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"כבוי"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"בעזרת פקדים של הודעות הפעלה, תוכל להגדיר רמת חשיבות מ-0 עד 5 להודעות אפליקציה. \n\n"<b>"רמה 5"</b>" \n- הצג בראש רשימת ההודעות \n- אפשר הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 4"</b>" \n- מנע הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 3"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n\n"<b>"רמה 2"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n\n"<b>"רמה 1"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n- הסתר ממסך הנעילה ומשורת הסטטוס \n- הצג בתחתית רשימת ההודעות \n\n"<b>"רמה 0"</b>" \n- חסום את כל ההודעות מהאפליקציה"</string>
-    <string name="notification_header_default_channel" msgid="7506845022070889909">"הודעות"</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"בעזרת פקדים של התראות הפעלה, אפשר להגדיר רמת חשיבות מ-0 עד 5 להתראות אפליקציה. \n\n"<b>"רמה 5"</b>" \n- הצגה בראש רשימת ההודעות \n- אפשר הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 4"</b>" \n- מנע הפרעה במסך מלא \n- תמיד אפשר הצצה \n\n"<b>"רמה 3"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n\n"<b>"רמה 2"</b>" \n- מנע הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n\n"<b>"רמה 1"</b>" \n- מניעת הפרעה במסך מלא \n- אף פעם אל תאפשר הצצה \n- אף פעם אל תאפשר קול ורטט \n- הסתרה ממסך הנעילה ומשורת הסטטוס \n- הצגה בתחתית רשימת ההתראות \n\n"<b>"רמה 0"</b>" \n- חסימה את כל ההתראות מהאפליקציה"</string>
+    <string name="notification_header_default_channel" msgid="7506845022070889909">"התראות"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"ההודעות האלה לא יוצגו לך יותר"</string>
     <string name="notification_channel_minimized" msgid="1664411570378910931">"ההודעות האלה ימוזערו"</string>
     <string name="inline_blocking_helper" msgid="3055064577771478591">"הודעות אלה בדרך כלל נדחות על ידיך. \nלהמשיך להציג אותן?"</string>
@@ -642,7 +643,7 @@
     <string name="notification_done" msgid="5279426047273930175">"סיום"</string>
     <string name="inline_undo" msgid="558916737624706010">"ביטול"</string>
     <string name="notification_menu_accessibility" msgid="2046162834248888553">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="MENU_DESCRIPTION">%2$s</xliff:g>"</string>
-    <string name="notification_menu_gear_description" msgid="2204480013726775108">"בקרת הודעות"</string>
+    <string name="notification_menu_gear_description" msgid="2204480013726775108">"בקרת התראות"</string>
     <string name="notification_menu_snooze_description" msgid="3653669438131034525">"אפשרויות של דחיית הודעות לטיפול בהמשך"</string>
     <string name="notification_menu_snooze_action" msgid="1112254519029621372">"הפעלת נודניק"</string>
     <string name="snooze_undo" msgid="6074877317002985129">"ביטול"</string>
@@ -693,7 +694,7 @@
     <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>
+    <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"התראות"</string>
     <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"מקשי קיצור במקלדת"</string>
     <string name="keyboard_shortcut_group_system_switch_input" msgid="8413348767825486492">"החלפה של פריסת מקלדת"</string>
     <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"אפליקציות"</string>
@@ -782,7 +783,7 @@
     <string name="accessibility_qs_edit_tile_add" msgid="3520406665865985109">"הוספת <xliff:g id="TILE_NAME">%1$s</xliff:g> למיקום <xliff:g id="POSITION">%2$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_move" msgid="3108103090006972938">"העברת <xliff:g id="TILE_NAME">%1$s</xliff:g> למיקום <xliff:g id="POSITION">%2$d</xliff:g>"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"עורך הגדרות מהירות."</string>
-    <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"הודעת <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
+    <string name="accessibility_desc_notification_icon" msgid="8352414185263916335">"התראות <xliff:g id="ID_1">%1$s</xliff:g>: <xliff:g id="ID_2">%2$s</xliff:g>"</string>
     <string name="dock_forced_resizable" msgid="5914261505436217520">"ייתכן שהיישום לא יפעל עם מסך מפוצל."</string>
     <string name="dock_non_resizeble_failed_to_dock_text" msgid="3871617304250207291">"האפליקציה אינה תומכת במסך מפוצל."</string>
     <string name="forced_resizable_secondary_display" msgid="4230857851756391925">"ייתכן שהאפליקציה לא תפעל במסך משני."</string>
@@ -794,6 +795,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"מחובר בתור <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"אין אינטרנט"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"פתיחת פרטים."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"לא זמין כי <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"פתיחת הגדרות של <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"עריכת סדר ההגדרות."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"דף <xliff:g id="ID_1">%1$d</xliff:g> מתוך <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index e5b0a2b..c651f9e 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"通知をすべて表示"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"名前のないデバイス"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"キャスト準備完了"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"利用可能なデバイスがありません"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi に接続されていません"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"画面の明るさ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"色を反転"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>で、画面に表示されているコンテンツのキャプチャを開始します。"</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="8035284146227267681">"通知を管理する"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> としてログインします"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"インターネットに接続されていません"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"詳細情報を開きます。"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"利用できない理由: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> の設定を開きます。"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"設定の順序を編集します。"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"ページ <xliff:g id="ID_1">%1$d</xliff:g>/<xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 19e9f47..f91ffb0 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"ბატარეა იტენება, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"ყველა შეტყობინების ნახვა"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"უსახელო მოწყობილობა"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"მზად არის სამაუწყებლოდ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"მოწყობილობები მიუწვდომელია"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi არ არის დაკავშირებული"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"განათება"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ავტომატურად"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ფერების შებრუნება"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> დაიწყებს იმ ყველაფრის აღბეჭდვას, რაც თქვენს ეკრანზე ჩანს."</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="8035284146227267681">"შეტყობინებების მართვა"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"მართვა"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"შესული ხართ, როგორც <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ინტერნეტ-კავშირი არ არის"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"დეტალების გახსნა."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"მიუწვდომელია, რადგან <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> პარამეტრების გახსნა."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"პარამეტრების მიმდევრობის რედაქტირება."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"გვერდი <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>-დან"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 15f8cd5..b79ea7b 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Батарея зарядталуда, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Барлық хабарландыруды қарау"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Атаусыз құрылғы"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Трансляциялауға дайын"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Құрылғылар қол жетімді емес"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi желісіне жалғанбаған"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Жарықтығы"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Авто"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Түстерді инверсиялау"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экранда көрсетілгеннің барлығын түсіре бастайды."</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="8035284146227267681">"Хабарландыруларды басқару"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Басқару"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> ретінде кірдіңіз"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Интернетпен байланыс жоқ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Мәліметтерді ашу."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Қолжетімді емес, өйткені <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> параметрлерін ашу."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Параметрлер тәртібін өзгерту."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ішінен <xliff:g id="ID_1">%1$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index af8d4ce..0731a5e 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ឧបករណ៍​​ដែល​មិន​មាន​ឈ្មោះ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ត្រៀម​រួចរាល់​ដើម្បី​ចាត់​ថ្នាក់"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"មិន​មាន​ឧបករណ៍​ដែល​អាច​ប្រើ​បាន"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"មិនមាន​ការតភ្ជាប់ Wi-Fi ទេ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ពន្លឺ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ស្វ័យប្រវត្តិ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ដាក់​​​បញ្ច្រាស​ពណ៌"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> នឹង​ចាប់ផ្ដើម​ចាប់​យក​អ្វីៗ​គ្រប់យ៉ាង​ដែល​បង្ហាញ​លើ​អេក្រង់​របស់​អ្នក។"</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="8035284146227267681">"គ្រប់គ្រងការជូនដំណឹង"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"គ្រប់គ្រង"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"បានចូលជា <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"គ្មាន​អ៊ីនធឺណិតទេ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"បើកព័ត៌មានលម្អិត"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"មិនអាច​ប្រើបានទេ ដោយសារ <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"បើការកំណត់ <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"កែលំដាប់ការកំណត់"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"ទំព័រ <xliff:g id="ID_1">%1$d</xliff:g> នៃ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index ac36e73..c4c642f 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"ಬ್ಯಾಟರಿ ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ನೋಡಿ"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ಹೆಸರಿಸದಿರುವ ಸಾಧನ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ಬಿತ್ತರಿಸಲು ಸಿದ್ದವಾಗಿದೆ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"ಯಾವುದೇ ಸಾಧನಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"ವೈ-ಫೈ ಸಂಪರ್ಕಗೊಂಡಿಲ್ಲ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ಪ್ರಕಾಶಮಾನ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ಸ್ವಯಂ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ಬಣ್ಣಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"ನಿಮ್ಮ ಪರದೆಯ ಮೇಲೆ ಪ್ರದರ್ಶಿಸಲಾಗುವ ಎಲ್ಲವನ್ನೂ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಯು ಸೆರೆಹಿಡಿಯಲು ಪ್ರಾರಂಭಿಸುತ್ತದೆ."</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="8035284146227267681">"ಅಧಿಸೂಚನೆಗಳನ್ನು ನಿರ್ವಹಿಸಿ"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"ನಿರ್ವಹಿಸಿ"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> ಅವರಂತೆ ಸೈನ್ ಇನ್ ಮಾಡಲಾಗಿದೆ"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ಇಂಟರ್ನೆಟ್ ಇಲ್ಲ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"ವಿವರಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> ಕಾರಣದಿಂದಾಗಿ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ತೆರೆಯಿರಿ."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ಸೆಟ್ಟಿಂಗ್‌ಗಳ ಕ್ರಮವನ್ನು ಎಡಿಟ್ ಮಾಡಿ."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ರಲ್ಲಿ <xliff:g id="ID_1">%1$d</xliff:g> ಪುಟ"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"ಸಂಗ್ರಹಣೆ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"ಸುಳಿವುಗಳು"</string>
     <string name="instant_apps" msgid="6647570248119804907">"ತತ್‌ಕ್ಷಣ ಆಪ್‌ಗಳು"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> ರನ್ ಆಗುತ್ತಿದೆ"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡದೆ ಆ್ಯಪ್‌ ತೆರೆಯಲಾಗಿದೆ."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ಇನ್‌ಸ್ಟಾಲ್‌ ಮಾಡದೆ ಆ್ಯಪ್‌ ತೆರೆಯಲಾಗಿದೆ. ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="app_info" msgid="6856026610594615344">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ವೆಬ್‌ಗೆ ಹೋಗಿ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ಮೊಬೈಲ್ ಡೇಟಾ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 1e2ab42..9014880 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"모든 알림 보기"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"이름이 없는 기기"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"전송 준비 완료"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"사용 가능한 기기가 없습니다."</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi가 연결되어 있지 않음"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"밝기"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"자동"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"색상 반전"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에서 화면에 표시된 모든 것을 캡처하기 시작합니다."</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="8035284146227267681">"알림 관리"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"관리"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g>(으)로 로그인됨"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"인터넷 연결 없음"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"세부정보 열기"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"다음 이유로 사용할 수 없음: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> 설정 열기"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"설정 순서 수정"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>페이지 중 <xliff:g id="ID_1">%1$d</xliff:g>페이지"</string>
@@ -856,14 +856,10 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"허용"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"거부"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"탭하여 배터리 세이버 예약"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for auto_saver_text (6324376061044218113) -->
-    <skip />
+    <string name="auto_saver_text" msgid="6324376061044218113">"배터리가 <xliff:g id="PERCENTAGE">%d</xliff:g>%%가 되면 자동으로 켜기"</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"사용 안함"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"배터리 세이버 예약 사용 설정됨"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for auto_saver_enabled_text (874711029884777579) -->
-    <skip />
+    <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">"확인"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 585e290..51cb1b1 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Батарея кубатталууда, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Бардык эскертмелерди көрүү"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Аты жок түзмөк"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Тышкы экранга чыгарууга даяр"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Жеткиликтүү түзмөктөр жок"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi туташкан жок"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Жарыктыгы"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТО"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Түстөрдү инверсиялоо"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> экранга чыккан нерсенин баарын сүрөткө тарта баштайт."</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="8035284146227267681">"Эскертмелерди башкаруу"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Башкаруу"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> аккаунту менен кирди"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Интернет жок"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Чоо-жайын ачуу."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> себебине байланыштуу жеткиликсиз"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> жөндөөлөрүн ачуу."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Жөндөөлөрдүн иретин өзгөртүү."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ичинен <xliff:g id="ID_1">%1$d</xliff:g>-бет"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 0952df4..d442258 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"​ອຸ​ປະ​ກອນບໍ່​ມີ​ຊື່"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"​ພ້ອ​ມ​ສົ່ງ​ສັນ​ຍານ​ແລ້ວ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"​ບໍ່​ມີ​ອຸ​ປະ​ກອນ​ທີ່​ສາ​ມາດ​ໃຊ້​ໄດ້"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"ບໍ່ໄດ້ເຊື່ອມຕໍ່ Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ຄວາມແຈ້ງ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ອັດຕະໂນມັດ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ສະຫຼັບສີ"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ​ຈະ​ເລີ່ມ​ບັນ​ທຶກ​ທຸກ​ຢ່າງ​ທີ່​ສະ​ແດງ​ຜົນ​ໃນ​ໜ້າ​ຈໍ​ທ່ານ."</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="8035284146227267681">"ຈັດການການແຈ້ງເຕືອນ"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"ຈັດການ"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"ເຂົ້າສູ່ລະບົບເປັນ <xliff:g id="ID_1">%s</xliff:g> ແລ້ວ"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ບໍ່ມີອິນເຕີເນັດ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"ເປີດລາຍລະອຽດ."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"ບໍ່ສາມາດໃຊ້ໄດ້ເນື່ອງຈາກ <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"ເປີດການຕັ້ງຄ່າ <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ແກ້ໄຂລຳດັບການຕັ້ງຄ່າ."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g> ຈາກທັງໝົດ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index ac6cfc7..e26df8b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -65,7 +65,7 @@
     <string name="always_use_device" msgid="4015357883336738417">"Visada atidaryti „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kai prijungiamas (-a) <xliff:g id="USB_DEVICE">%2$s</xliff:g>"</string>
     <string name="always_use_accessory" msgid="3257892669444535154">"Visada atidaryti „<xliff:g id="APPLICATION">%1$s</xliff:g>“, kai prijungiamas (-a) <xliff:g id="USB_ACCESSORY">%2$s</xliff:g>"</string>
     <string name="usb_debugging_title" msgid="4513918393387141949">"Leisti USB derinimą?"</string>
-    <string name="usb_debugging_message" msgid="2220143855912376496">"Šio kompiuterio RSA rakto kontrolinis kodas yra:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
+    <string name="usb_debugging_message" msgid="2220143855912376496">"Šio kompiuterio RSA rakto piršto antspaudas yra:\n<xliff:g id="FINGERPRINT">%1$s</xliff:g>"</string>
     <string name="usb_debugging_always" msgid="303335496705863070">"Visada leisti iš šio kompiuterio"</string>
     <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>
@@ -95,8 +95,8 @@
     <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefonas"</string>
     <string name="accessibility_voice_assist_button" msgid="487611083884852965">"Voice Assist"</string>
     <string name="accessibility_unlock_button" msgid="128158454631118828">"Atrakinti"</string>
-    <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Laukiama kontrolinio kodo"</string>
-    <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Atrakinti nenaudojant kontrolinio kodo"</string>
+    <string name="accessibility_waiting_for_fingerprint" msgid="4808860050517462885">"Laukiama piršto antspaudo"</string>
+    <string name="accessibility_unlock_without_fingerprint" msgid="7541705575183694446">"Atrakinti nenaudojant piršto antspaudo"</string>
     <string name="accessibility_scanning_face" msgid="769545173211758586">"Nuskaitomas veidas"</string>
     <string name="accessibility_send_smart_reply" msgid="7766727839703044493">"Siųsti"</string>
     <string name="unlock_label" msgid="8779712358041029439">"atrakinti"</string>
@@ -107,8 +107,8 @@
     <string name="cancel" msgid="6442560571259935130">"Atšaukti"</string>
     <string name="accessibility_biometric_dialog_help_area" msgid="8953787076940186847">"Pagalbos pranešimo sritis"</string>
     <string name="biometric_dialog_confirm" msgid="6468457350041712674">"Patvirtinkite"</string>
-    <string name="fingerprint_dialog_touch_sensor" msgid="8511557690663181761">"Palieskite kontrolinio kodo jutiklį"</string>
-    <string name="accessibility_fingerprint_dialog_fingerprint_icon" msgid="3125122495414253226">"Kontrolinio kodo piktograma"</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>
     <string name="accessibility_face_dialog_face_icon" msgid="2658119009870383490">"Veido piktograma"</string>
     <string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"Suderinamumo priartinimo mygtukas."</string>
@@ -176,7 +176,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_charging" msgid="1147587904439319646">"Įkraunamas akumuliatorius, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> proc."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Žr. visus pranešimus"</string>
@@ -323,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Įrenginys be pavadinimo"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Paruošta perduoti"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nėra pasiekiamų įrenginių"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"„Wi-Fi“ neprijungtas"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Šviesumas"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATINIS"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Pakeisti spalvas"</string>
@@ -450,7 +451,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"„<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ pradės fiksuoti viską, kas rodoma jūsų ekrane."</string>
     <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="8035284146227267681">"Pranešimų tvarkymas"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Tvarkyti"</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>
@@ -794,6 +795,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Prisijungta kaip <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nėra interneto ryšio"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Atidaryti išsamią informaciją."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nepasiekiama dėl <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Atidaryti „<xliff:g id="ID_1">%s</xliff:g>“ nustatymus."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Redaguoti nustatymų tvarką."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g> psl. iš <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -866,10 +868,10 @@
     <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>
-    <string name="auto_saver_text" msgid="6324376061044218113">"Įjunkite automatiškai akumuliatoriaus įkrovai pasiekus <xliff:g id="PERCENTAGE">%d</xliff:g> proc."</string>
+    <string name="auto_saver_text" msgid="6324376061044218113">"Įjunkite automatiškai akumuliatoriaus įkrovai pasiekus <xliff:g id="PERCENTAGE">%d</xliff:g>%%."</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> proc."</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>
     <string name="open_saver_setting_action" msgid="8314624730997322529">"Nustatymai"</string>
     <string name="auto_saver_okay_action" msgid="2701221740227683650">"Supratau"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Pat. „SysUI“ krūvą"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 01e2e39..6f5e230 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -175,7 +175,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_charging" msgid="1147587904439319646">"Notiek akumulatora uzlāde, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procenti."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Skatīt visus paziņojumus"</string>
@@ -321,6 +321,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nenosaukta ierīce"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Gatavs apraidei"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nav pieejamu ierīču."</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Nav izveidots savienojums ar Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Spilgtums"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMĀTISKI"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invertēt krāsas"</string>
@@ -446,7 +447,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sāks uzņemt visu, kas tiks rādīts jūsu ekrānā."</string>
     <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="8035284146227267681">"Pārvaldīt paziņojumus"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Pārvaldīt"</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>
@@ -788,6 +789,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Pierakstījies kā <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nav piekļuves internetam"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Atvērt detalizēto informāciju."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nav pieejams šāda iemesla dēļ: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Atvērt <xliff:g id="ID_1">%s</xliff:g> iestatījumus."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Rediģēt iestatījumu secību."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. lpp. no <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -860,14 +862,10 @@
     <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>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for auto_saver_text (6324376061044218113) -->
-    <skip />
+    <string name="auto_saver_text" msgid="6324376061044218113">"Ieslēgt automātiski, kad akumulatora uzlādes līmenis ir <xliff:g id="PERCENTAGE">%d</xliff:g>%%"</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.format failed for translation -->
-    <!-- no translation found for auto_saver_enabled_text (874711029884777579) -->
-    <skip />
+    <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>
     <string name="open_saver_setting_action" msgid="8314624730997322529">"Iestatījumi"</string>
     <string name="auto_saver_okay_action" msgid="2701221740227683650">"Labi"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 8b4b458..d13193b7 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Полнење на батеријата, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Видете ги сите известувања"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Неименуван уред"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Подготвено за емитување"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Нема достапни уреди"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi не е поврзано"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Осветленост"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Автоматски"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Преврти ги боите"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ќе започне да презема сѐ што се прикажува на вашиот екран."</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="8035284146227267681">"Управувајте со известувањата"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Управувајте"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Најавени сте како <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Нема интернет"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Отворете ги деталите."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Недостапно бидејќи <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Отворете ги поставките на <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Уредете го редоследот на поставките."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Страница <xliff:g id="ID_1">%1$d</xliff:g> од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index fc32b88..a5cad4e 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"ബാറ്ററി ചാർജുചെയ്യുന്നു, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"എല്ലാ അറിയിപ്പുകളും കാണുക"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"പേരിടാത്ത ഉപകരണം"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"കാസ്‌റ്റ് ചെയ്യാൻ തയ്യാറാണ്"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"ഉപകരണങ്ങളൊന്നും ലഭ്യമല്ല"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"വൈഫൈ കണക്റ്റ് ചെയ്‌തിട്ടില്ല"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"തെളിച്ചം"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"യാന്ത്രികം"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"നിറം മാറ്റുക"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"നിങ്ങളുടെ സ്ക്രീനിൽ പ്രദർശിപ്പിച്ചിരിക്കുന്ന എല്ലാ കാര്യങ്ങളും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ക്യാപ്‌ചർ ചെയ്യുന്നത് ആരംഭിക്കും."</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="8035284146227267681">"അറിയിപ്പുകൾ മാനേജ് ചെയ്യുക"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"മാനേജ് ചെയ്യുക"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> ആയി സൈൻ ഇൻ ചെയ്‌തു"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ഇന്റർനെറ്റ് ഇല്ല"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"വിശദാംശങ്ങൾ തുറക്കുക."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> എന്ന കാരണത്താൽ ലഭ്യമല്ല"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ക്രമീകരണം തുറക്കുക."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ക്രമീകരണ ക്രമം എഡിറ്റുചെയ്യുക."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"പേജ് <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"സ്റ്റോറേജ്"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"സൂചനകൾ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"ഇൻസ്റ്റന്റ് ആപ്പ്"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> റണ്‍ ചെയ്യുന്നു"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"ഇൻസ്‌റ്റാൾ ചെയ്യാതെ ആപ്പ് തുറന്നു."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ഇൻസ്‌റ്റാൾ ചെയ്യാതെ ആപ്പ് തുറന്നു. കൂടുതലറിയാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="app_info" msgid="6856026610594615344">"ആപ്പ് വിവരം"</string>
     <string name="go_to_web" msgid="1106022723459948514">"വെബിൽ പോവുക"</string>
     <string name="mobile_data" msgid="7094582042819250762">"മൊബൈൽ ഡാറ്റ"</string>
@@ -860,7 +859,7 @@
     <string name="auto_saver_text" msgid="6324376061044218113">"ബാറ്ററി <xliff:g id="PERCENTAGE">%d</xliff:g>%% ആകുമ്പോൾ സ്വമേധയാ ഓണാക്കുക"</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>
+    <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">"മനസ്സിലായി"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"SysUI ഹീപ്പ് ഡമ്പ് ചെയ്യുക"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 331e9b7..978fc0e 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -172,7 +172,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_charging" msgid="1147587904439319646">"Тэжээлийг цэнэглэж байна, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Бүх мэдэгдлийг харах"</string>
@@ -317,6 +317,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Нэргүй төхөөрөмж"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Дамжуулахад бэлэн"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Төхөөрөмж байхгүй"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi-д холбогдоогүй байна"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Тодрол"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОМАТ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Өнгийг урвуулах"</string>
@@ -440,7 +441,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> таны дэлгэц дээр гаргасан бүх зүйлийн зургийг авч эхэлнэ."</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="8035284146227267681">"Мэдэгдлийг удирдах"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Удирдах"</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>
@@ -780,6 +781,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g>-р нэвтэрсэн"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Интернэт алга"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Дэлгэрэнгүй мэдээллийг нээнэ үү."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g>-н улмаас боломжгүй байна"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> тохиргоог нээнэ үү."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Тохиргооны дарааллыг өөрчилнө үү."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>-н <xliff:g id="ID_1">%1$d</xliff:g>-р хуудас"</string>
@@ -852,10 +854,10 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Зөвшөөрөх"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Татгалзах"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Тэжээл хэмнэгч онцлогийг хуваарилахын тулд товших"</string>
-    <string name="auto_saver_text" msgid="6324376061044218113">"Батерей <xliff:g id="PERCENTAGE">%d</xliff:g>%% болох үед автоматаар асаах"</string>
+    <string name="auto_saver_text" msgid="6324376061044218113">"Батарей <xliff:g id="PERCENTAGE">%d</xliff:g>%% болох үед автоматаар асаах"</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>
+    <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">"Ойлголоо"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 33761ca..103ca46 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -57,7 +57,7 @@
     <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>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"निनावी डिव्हाइस"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"कास्ट करण्यास तयार"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"कोणतेही डिव्हाइसेस उपलब्ध नाहीत"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"वाय-फाय कनेक्ट केलेले नाही"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"चमक"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वयंचलित"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"रंगांचा क्रम उलटा लावा"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> आपल्‍या स्‍क्रीनवर प्रदर्शित होणारी प्रत्‍येक गोष्‍ट कॅप्‍चर करणे प्रारंभ करेल."</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="8035284146227267681">"सूचना व्यवस्थापित करा"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"व्यवस्थापित करा"</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>
@@ -485,7 +486,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>
@@ -495,7 +496,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>
@@ -576,8 +577,8 @@
     <string name="status_bar_airplane" msgid="7057575501472249002">"विमान मोड"</string>
     <string name="add_tile" msgid="2995389510240786221">"टाइल जोडा"</string>
     <string name="broadcast_tile" msgid="3894036511763289383">"प्रसारण टाइल"</string>
-    <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"तुम्ही त्यापूर्वी हे बंद केल्याशिय आपला पुढील <xliff:g id="WHEN">%1$s</xliff:g> होणारा अलार्म ऐकणार नाही"</string>
-    <string name="zen_alarm_warning" msgid="444533119582244293">"तुम्ही आपला <xliff:g id="WHEN">%1$s</xliff:g> वाजता होणारा पुढील अलार्म ऐकणार नाही"</string>
+    <string name="zen_alarm_warning_indef" msgid="3482966345578319605">"तुम्ही त्यापूर्वी हे बंद केल्याशिय तुमचा पुढील <xliff:g id="WHEN">%1$s</xliff:g> होणारा अलार्म ऐकणार नाही"</string>
+    <string name="zen_alarm_warning" msgid="444533119582244293">"तुम्ही तुमचा <xliff:g id="WHEN">%1$s</xliff:g> वाजता होणारा पुढील अलार्म ऐकणार नाही"</string>
     <string name="alarm_template" msgid="3980063409350522735">"<xliff:g id="WHEN">%1$s</xliff:g> वाजता"</string>
     <string name="alarm_template_far" msgid="4242179982586714810">"<xliff:g id="WHEN">%1$s</xliff:g> रोजी"</string>
     <string name="accessibility_quick_settings_detail" msgid="2579369091672902101">"द्रुत सेटिंग्ज, <xliff:g id="TITLE">%s</xliff:g>."</string>
@@ -597,7 +598,7 @@
     <string name="show_brightness" msgid="6613930842805942519">"द्रुत सेटिंग्जमध्‍ये चमक दर्शवा"</string>
     <string name="experimental" msgid="6198182315536726162">"प्रायोगिक"</string>
     <string name="enable_bluetooth_title" msgid="5027037706500635269">"ब्लूटूथ सुरू करायचे?"</string>
-    <string name="enable_bluetooth_message" msgid="9106595990708985385">"आपला कीबोर्ड तुमच्या टॅबलेटसह कनेक्ट करण्यासाठी, तुम्ही प्रथम ब्लूटूथ चालू करणे आवश्यक आहे."</string>
+    <string name="enable_bluetooth_message" msgid="9106595990708985385">"तुमचा कीबोर्ड तुमच्या टॅबलेटसह कनेक्ट करण्यासाठी, तुम्ही प्रथम ब्लूटूथ चालू करणे आवश्यक आहे."</string>
     <string name="enable_bluetooth_confirmation_ok" msgid="6258074250948309715">"चालू करा"</string>
     <string name="show_silently" msgid="6841966539811264192">"सूचना शांतपणे दर्शवा"</string>
     <string name="block" msgid="2734508760962682611">"सर्व सूचना ब्लॉक करा"</string>
@@ -606,7 +607,7 @@
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"पॉवर सूचना नियंत्रणे"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"चालू"</string>
     <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"बंद"</string>
-    <string name="power_notification_controls_description" msgid="4372459941671353358">"पॉवर सूचना नियंत्रणांच्या साहाय्याने तुम्ही अॅप सूचनांसाठी 0 ते 5 असे महत्त्व स्तर सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दाखवा \n- पूर्ण स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>\n" - पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n\n"<b>"स्तर 1"</b>\n"- पूर्ण स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अॅपमधील सर्व सूचना ब्लॉक करा"</string>
+    <string name="power_notification_controls_description" msgid="4372459941671353358">"पॉवर सूचना नियंत्रणांच्या साहाय्याने तुम्ही अॅप सूचनांसाठी 0 ते 5 असे महत्त्व स्तर सेट करू शकता. \n\n"<b>"स्तर 5"</b>" \n- सूचना सूचीच्या शीर्षस्थानी दाखवा \n- फुल स्क्रीन व्यत्ययास अनुमती द्या \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 4"</b>\n" - फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- नेहमी डोकावून पहा \n\n"<b>"स्तर 3"</b>" \n- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n\n"<b>"स्तर 2"</b>" \n- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n\n"<b>"स्तर 1"</b>\n"- फुल स्क्रीन व्यत्ययास प्रतिबंधित करा \n- कधीही डोकावून पाहू नका \n- कधीही ध्वनी किंवा व्हायब्रेट करू नका \n- लॉक स्क्रीन आणि स्टेटस बार मधून लपवा \n- सूचना सूचीच्या तळाशी दर्शवा \n\n"<b>"स्तर 0"</b>" \n- अॅपमधील सर्व सूचना ब्लॉक करा"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"सूचना"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"आता तुम्हाला या सूचना दिसणार नाहीत"</string>
     <string name="notification_channel_minimized" msgid="1664411570378910931">"या सूचना लहान केल्या जातील"</string>
@@ -753,16 +754,16 @@
   </string-array>
     <string name="other" msgid="4060683095962566764">"अन्य"</string>
     <string name="accessibility_divider" msgid="5903423481953635044">"विभाजित-स्क्रीन विभाजक"</string>
-    <string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"डावी पूर्ण स्क्रीन"</string>
+    <string name="accessibility_action_divider_left_full" msgid="2801570521881574972">"डावी फुल स्क्रीन"</string>
     <string name="accessibility_action_divider_left_70" msgid="3612060638991687254">"डावी 70%"</string>
     <string name="accessibility_action_divider_left_50" msgid="1248083470322193075">"डावी 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="543324403127069386">"डावी 30%"</string>
-    <string name="accessibility_action_divider_right_full" msgid="4639381073802030463">"उजवी पूर्ण स्क्रीन"</string>
-    <string name="accessibility_action_divider_top_full" msgid="5357010904067731654">"शीर्ष पूर्ण स्क्रीन"</string>
+    <string name="accessibility_action_divider_right_full" msgid="4639381073802030463">"उजवी फुल स्क्रीन"</string>
+    <string name="accessibility_action_divider_top_full" msgid="5357010904067731654">"शीर्ष फुल स्क्रीन"</string>
     <string name="accessibility_action_divider_top_70" msgid="5090779195650364522">"शीर्ष 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="6385859741925078668">"शीर्ष 50%"</string>
     <string name="accessibility_action_divider_top_30" msgid="6201455163864841205">"शीर्ष 10"</string>
-    <string name="accessibility_action_divider_bottom_full" msgid="301433196679548001">"तळाशी पूर्ण स्क्रीन"</string>
+    <string name="accessibility_action_divider_bottom_full" msgid="301433196679548001">"तळाशी फुल स्क्रीन"</string>
     <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"स्थिती <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. संपादित करण्यासाठी दोनदा टॅप करा."</string>
     <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g> . जोडण्यासाठी दोनदा टॅप करा."</string>
     <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"<xliff:g id="TILE_NAME">%1$s</xliff:g> हलवा"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> म्हणून साइन इन केले"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"इंटरनेट नाही"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"तपशील उघडा."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> मुळे उपलब्ध नाही"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> सेटिंग्ज उघडा."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"सेटिंग्जचा क्रम संपादित करा."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"पृष्ठ <xliff:g id="ID_2">%2$d</xliff:g> पैकी <xliff:g id="ID_1">%1$d</xliff:g>"</string>
@@ -799,11 +801,11 @@
     <string name="pip_skip_to_next" msgid="1948440006726306284">"डावलून पुढे जा"</string>
     <string name="pip_skip_to_prev" msgid="1955311326688637914">"डावलून मागे जा"</string>
     <string name="thermal_shutdown_title" msgid="4458304833443861111">"तापल्‍यामुळे फोन बंद झाला"</string>
-    <string name="thermal_shutdown_message" msgid="9006456746902370523">"आपला फोन आता व्‍यवस्थित चालू आहे"</string>
-    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"आपला फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. आपला फोन आता व्‍यवस्थित चालू आहे.\n\nतुम्ही असे केल्यास आपला फोन खूप तापेल:\n	•संसाधन केंद्रित अॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अॅप यासारखे)\n	•मोठ्या फायली डाउनलोड किंवा अपलोड करणे\n	•उच्च तापमानामध्ये आपला फोन वापरणे"</string>
+    <string name="thermal_shutdown_message" msgid="9006456746902370523">"तुमचा फोन आता व्‍यवस्थित चालू आहे"</string>
+    <string name="thermal_shutdown_dialog_message" msgid="566347880005304139">"तुमचा फोन खूप तापलाय, म्हणून तो थंड होण्यासाठी बंद झाला आहे. तुमचा फोन आता व्‍यवस्थित चालू आहे.\n\nतुम्ही असे केल्यास तुमचा फोन खूप तापेल:\n	•संसाधन केंद्रित अॅप वापरणे (गेमिंग, व्हिडिओ किंवा नेव्हिगेशन अॅप यासारखे)\n	•मोठ्या फायली डाउनलोड किंवा अपलोड करणे\n	•उच्च तापमानामध्ये तुमचा फोन वापरणे"</string>
     <string name="high_temp_title" msgid="4589508026407318374">"फोन ऊष्ण होत आहे"</string>
     <string name="high_temp_notif_message" msgid="5642466103153429279">"फोन थंड होत असताना काही वैशिष्‍ट्ये मर्यादित असतात"</string>
-    <string name="high_temp_dialog_message" msgid="6840700639374113553">"आपला फोन स्वयंचलितपणे थंड होईल. तुम्ही अद्यापही आपला फोन वापरू शकता परंतु तो कदाचित धीमेपणे कार्य करेल.\n\nआपला फोन एकदा थंड झाला की, तो सामान्यपणे कार्य करेल."</string>
+    <string name="high_temp_dialog_message" msgid="6840700639374113553">"तुमचा फोन स्वयंचलितपणे थंड होईल. तुम्ही अद्यापही तुमचा फोन वापरू शकता परंतु तो कदाचित धीमेपणे कार्य करेल.\n\nतुमचा फोन एकदा थंड झाला की, तो सामान्यपणे कार्य करेल."</string>
     <string name="lockscreen_shortcut_left" msgid="2182769107618938629">"डावा शॉर्टकट"</string>
     <string name="lockscreen_shortcut_right" msgid="3328683699505226536">"उजवा शॉर्टकट"</string>
     <string name="lockscreen_unlock_left" msgid="2043092136246951985">"डावा शॉर्टकट देखील अनलॉक करतो"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"स्टोरेज"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"सूचना"</string>
     <string name="instant_apps" msgid="6647570248119804907">"इन्सटंट अ‍ॅप्स"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> रन होत आहे"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"इंस्टॉल केल्याशिवाय अॅप उघडले."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"इंस्टॉल केल्याशिवाय अॅप उघडले. अधिक जाणून घेण्यासाठी टॅप करा."</string>
     <string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string>
     <string name="go_to_web" msgid="1106022723459948514">"वेबवर जा"</string>
     <string name="mobile_data" msgid="7094582042819250762">"मोबाइल डेटा"</string>
diff --git a/packages/SystemUI/res/values-mr/strings_tv.xml b/packages/SystemUI/res/values-mr/strings_tv.xml
index aac2d5e..8ed1558 100644
--- a/packages/SystemUI/res/values-mr/strings_tv.xml
+++ b/packages/SystemUI/res/values-mr/strings_tv.xml
@@ -22,5 +22,5 @@
     <string name="notification_channel_tv_pip" msgid="134047986446577723">"चित्रा-मध्‍ये-चित्र"</string>
     <string name="pip_notification_unknown_title" msgid="6289156118095849438">"(शीर्षक नसलेला कार्यक्रम)"</string>
     <string name="pip_close" msgid="3480680679023423574">"PIP बंद करा"</string>
-    <string name="pip_fullscreen" msgid="8604643018538487816">"पूर्ण स्क्रीन"</string>
+    <string name="pip_fullscreen" msgid="8604643018538487816">"फुल स्क्रीन"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index d6a71ef..7a6a1e3 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Peranti tidak bernama"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Bersedia untuk menghantar"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Tiada peranti tersedia"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi tidak disambungkan"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Kecerahan"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Terbalikkan warna"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> akan mula mengabadikan semua yang dipaparkan pada skrin anda.."</string>
     <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="8035284146227267681">"Urus pemberitahuan"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Urus"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Dilog masuk sebagai <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Tiada Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Buka butiran."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Tidak tersedia disebabkan <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Buka tetapan <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edit susunan tetapan."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Halaman <xliff:g id="ID_1">%1$d</xliff:g> daripada <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 2a6e3c2..62970aa 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"ဘက်ထရီအားသွင်းနေသည်၊ <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"သတိပေးချက်များအားလုံးကို ကြည့်ရန်"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"အမည်မတပ် ကိရိယာ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ကာစ်တ် လုပ်ရန် အသင့် ရှိနေပြီ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"ကိရိယာများ မရှိ"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi ချိတ်ဆက်ထားခြင်းမရှိပါ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"အလင်းတောက်ပမှု"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"အလိုအလျောက်"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"အရောင်များ ပြောင်းပြန်လုပ်ရန်"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> က သင်၏ မျက်နှာပြင် ပေါ်မှာ ပြသထားသည့် အရာတိုင်းကို စတင် ဖမ်းယူမည်။"</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="8035284146227267681">"အကြောင်းကြားချက်များကို စီမံရန်"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"စီမံရန်"</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>
@@ -605,7 +606,7 @@
     <string name="do_not_silence_block" msgid="4070647971382232311">"အသံ မတိတ်ပါနှင့် သို့မဟုတ် မပိတ်ဆို့ပါနှင့်"</string>
     <string name="tuner_full_importance_settings" msgid="3207312268609236827">"ပါဝါအကြောင်းကြားချက် ထိန်းချုပ်မှုများ"</string>
     <string name="tuner_full_importance_settings_on" msgid="7545060756610299966">"ဖွင့်ပါ"</string>
-    <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ပိတ်ပါ"</string>
+    <string name="tuner_full_importance_settings_off" msgid="8208165412614935229">"ပိတ်ထားသည်"</string>
     <string name="power_notification_controls_description" msgid="4372459941671353358">"ပါဝါအကြောင်းကြားချက် ထိန်းချုပ်မှုများကိုအသုံးပြုပြီး အက်ပ်တစ်ခု၏ အကြောင်းကြားချက် အရေးပါမှု ၀ မှ ၅ အထိသတ်မှတ်ပေးနိုင်သည်။ \n\n"<b>"အဆင့် ၅"</b>" \n- အကြောင်းကြားချက်စာရင်း၏ ထိပ်ဆုံးတွင် ပြသည် \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်းကို ခွင့်ပြုသည် \n- အမြဲတမ်း ခေတ္တပြပါမည် \n\n"<b>"အဆင့် ၄"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- အမြဲတမ်း ခေတ္တပြပါမည် \n\n"<b>"အဆင့် ၃"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n\n"<b>"အဆင့် ၂"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n- အသံမြည်ခြင်းနှင့် တုန်ခါခြင်းများ ဘယ်တော့မှ မပြုလုပ်ပါ \n\n"<b>"အဆင့် ၁"</b>" \n- မျက်နှာပြင်အပြည့် ကြားဖြတ်ဖော်ပြခြင်း မရှိစေရန် ကာကွယ်ပေးသည် \n- ဘယ်တော့မှ ခေတ္တပြခြင်း မရှိပါ \n- အသံမြည်ခြင်းနှင့် တုန်ခါခြင်းများ ဘယ်တော့မှ မပြုလုပ်ပါ \n- လော့ခ်ချထားသည့် မျက်နှာပြင်နှင့် အခြေအနေဘားတန်းတို့တွင် မပြပါ \n- အကြောင်းကြားချက်စာရင်း အောက်ဆုံးတွင်ပြသည် \n\n"<b>"အဆင့် ၀"</b>" \n- အက်ပ်မှ အကြောင်းကြားချက်များ အားလုံးကို ပိတ်ဆို့သည်"</string>
     <string name="notification_header_default_channel" msgid="7506845022070889909">"အကြောင်းကြားချက်များ"</string>
     <string name="notification_channel_disabled" msgid="344536703863700565">"ဤအကြောင်းကြားချက်များကို မြင်ရတော့မည် မဟုတ်ပါ"</string>
@@ -707,7 +708,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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> အဖြစ် လက်မှတ်ထိုးဝင်ထားသည်။"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"အင်တာနက် မရှိပါ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"အသေးစိတ်များကို ဖွင့်ပါ။"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> ကြောင့် မရနိုင်ပါ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ဆက်တင်များကို ဖွင့်ပါ။"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ဆက်တင်များ၏ အစီအစဉ်ကို တည်းဖြတ်ပါ။"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"စာမျက်နှာ <xliff:g id="ID_2">%2$d</xliff:g> အနက်မှ စာမျက်နှာ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index d90eba3..81ff8e2 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Enhet uten navn"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Klar til å caste"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Ingen enheter er tilgjengelige"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi er ikke tilkoblet"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Lysstyrke"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverter farger"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tar opp alt som vies på skjermen din."</string>
     <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="8035284146227267681">"Administrer varsler"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Administrer"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Logget på som <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Ingen Internett-tilkobling"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Åpne informasjonen."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Utilgjengelig fordi <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Åpne <xliff:g id="ID_1">%s</xliff:g>-innstillingene."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Endre rekkefølgen på innstillingene."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Side <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 4e3cddd..4f2845e 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"बेनाम उपकरण"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"प्रसारण गर्न तयार"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"कुनै उपकरणहरू उपलब्ध छैन"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi जडान गरिएको छैन"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"उज्यालपन"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"स्वतः"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"रंग उल्टाउनुहोस्"</string>
@@ -434,7 +435,7 @@
       <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>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ले आफ्नो स्क्रीनमा प्रदर्शित हुने सबै खिच्न शुरू गर्नेछ।"</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="8035284146227267681">"सूचनाहरू व्यवस्थापन गर्नुहोस्"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"व्यवस्थित गर्नुहोस्"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> को रूपमा साइन इन गरियो"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"इन्टरनेट छैन"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"विवरणहरूलाई खोल्नुहोस्।"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> का कारण उपलब्ध छैन"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> सम्बन्धी सेटिङहरूलाई खोल्नुहोस्।"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"सेटिङहरूको क्रमलाई सम्पादन गर्नुहोस्।"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> मध्ये पृष्ठ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 9dda44e..60ca532 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Batterij wordt opgeladen, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> procent."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Alle meldingen bekijken"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Naamloos apparaat"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Klaar om te casten"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Geen apparaten beschikbaar"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wifi niet verbonden"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Helderheid"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATISCH"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Kleuren omkeren"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> gaat alles vastleggen dat wordt weergegeven op je scherm."</string>
     <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="8035284146227267681">"Meldingen beheren"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Beheren"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Ingelogd als <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Geen internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Details openen."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Niet beschikbaar vanwege <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g>-instellingen openen."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Volgorde van instellingen bewerken."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> van <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 91c62bb..a78f5cd 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ନାମହୀନ ଡିଭାଇସ୍‍"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"କାଷ୍ଟ୍ ପାଇଁ ପ୍ରସ୍ତୁତ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"କୌଣସି ଡିଭାଇସ୍ ଉପଲବ୍ଧ ନାହିଁ"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"ୱାଇ-ଫାଇ ସଂଯୋଜିତ ହୋଇନାହିଁ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ଉଜ୍ଜ୍ୱଳତା"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ସ୍ୱଚାଳିତ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ରଙ୍ଗ ପୂର୍ବପରି କରନ୍ତୁ"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ଆପଣଙ୍କ ସ୍କ୍ରୀନ୍‌ରେ ପ୍ରଦର୍ଶିତ ହେଉଥିବା ସମସ୍ତ ବସ୍ତୁକୁ କ୍ୟାପଚର୍ କରିବା ଆରମ୍ଭ ହୋଇଯିବ।"</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="8035284146227267681">"ବିଜ୍ଞପ୍ତି ପରିଚାଳନା କରନ୍ତୁ"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"ପରିଚାଳନା କରନ୍ତୁ"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> ଭାବରେ ସାଇନ୍‌ ଇନ୍‌ କରିଛନ୍ତି"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"କୌଣସି ଇଣ୍ଟରନେଟ୍‌ କନେକ୍ସନ୍ ନାହିଁ"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"ବିବରଣୀ ଖୋଲନ୍ତୁ"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> ଯୋଗୁଁ ଉପଲବ୍ଧ ନାହିଁ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ସେଟିଙ୍ଗ ଖୋଲନ୍ତୁ।"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ସେଟିଙ୍ଗର କ୍ରମ ସଂଶୋଧନ କରନ୍ତୁ।"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"ପୃଷ୍ଠା <xliff:g id="ID_1">%1$d</xliff:g> ମୋଟ <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"ଷ୍ଟୋରେଜ୍‌"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"ହିଣ୍ଟ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"ଇନଷ୍ଟାଣ୍ଟ ଆପ୍‌"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> ଚାଲୁଛି"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"ଇନ୍‍ଷ୍ଟଲ୍‍ ନହୋଇ ଆପ୍‍ ଖୋଲିଛି।"</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ଇନ୍‍ଷ୍ଟଲ୍‍ ନହୋଇ ଆପ୍‍ ଖୋଲିଛି। ଅଧିକ ଜାଣିବା ପାଇଁ ଟାପ୍‍ କରନ୍ତୁ।"</string>
     <string name="app_info" msgid="6856026610594615344">"ଆପ୍‍ ସୂଚନା"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ୱେବକୁ ଯାଆନ୍ତୁ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ମୋବାଇଲ୍‌ ଡାଟା"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 96fb641..7e9a916 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"ਬਿਨਾਂ ਨਾਮ ਦਾ ਡੀਵਾਈਸ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ਜੋੜਨ ਲਈ ਤਿਆਰ"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"ਕੋਈ ਡਿਵਾਈਸਾਂ ਉਪਲਬਧ ਨਹੀਂ"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"ਵਾਈ-ਫਾਈ ਕਨੈਕਟ ਨਹੀਂ ਕੀਤਾ ਗਿਆ"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ਚਮਕ"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ਆਟੋ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"ਰੰਗ ਉਲਟੋ"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਉਹ ਸਭ ਕੁਝ ਕੈਪਚਰ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰ ਦੇਵੇਗਾ, ਜੋ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਤੇ ਡਿਸਪਲੇ ਕੀਤਾ ਜਾਂਦਾ ਹੈ।"</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="8035284146227267681">"ਸੂਚਨਾਵਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> ਵਜੋਂ ਸਾਈਨ ਇਨ ਕੀਤਾ"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ਇੰਟਰਨੈੱਟ ਨਹੀਂ।"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"ਵੇਰਵੇ ਖੋਲ੍ਹੋ।"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> ਦੇ ਕਾਰਨ ਅਣਉਪਲਬਧ ਹੈ"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ।"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ਸੈਟਿੰਗਾਂ ਦੇ ਕ੍ਰਮ ਦਾ ਸੰਪਾਦਨ ਕਰੋ।"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> ਦਾ <xliff:g id="ID_1">%1$d</xliff:g> ਪੰਨਾ"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"ਸਟੋਰੇਜ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"ਸੰਕੇਤ"</string>
     <string name="instant_apps" msgid="6647570248119804907">"ਤਤਕਾਲ ਐਪਾਂ"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> ਚੱਲ ਰਹੀ ਹੈ"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"ਸਥਾਪਤ ਕੀਤੇ ਬਿਨਾਂ ਐਪ ਖੋਲ੍ਹੀ ਗਈ।"</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ਸਥਾਪਤ ਕੀਤੇ ਬਿਨਾਂ ਐਪ ਖੋਲ੍ਹੀ ਗਈ। ਹੋਰ ਜਾਣਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ਵੈੱਬ \'ਤੇ ਜਾਓ"</string>
     <string name="mobile_data" msgid="7094582042819250762">"ਮੋਬਾਈਲ ਡਾਟਾ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 28d24bf..22ef98c 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -323,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Urządzenie bez nazwy"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Gotowy do działania"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Brak dostępnych urządzeń"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Brak połączenia z Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jasność"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATYCZNA"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Odwróć kolory"</string>
@@ -450,7 +451,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> będzie zapisywać wszystko, co wyświetli się na ekranie."</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="8035284146227267681">"Zarządzanie powiadomieniami"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Zarządzaj"</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>
@@ -794,6 +795,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Jesteś zalogowany jako <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Brak internetu"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Otwórz szczegóły."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Niedostępne z powodu: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otwórz ustawienia: <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Edytuj kolejność ustawień."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Strona <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index ab0f5f2..f26d1ba 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ver todas as notificações"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sem nome"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Pronto para transmitir"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Não há dispositivos disponíveis"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi não conectado"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverter cores"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> começará a capturar tudo o que for exibido na tela."</string>
     <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="8035284146227267681">"Gerenciar notificações"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gerenciar"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Login efetuado como <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Abrir detalhes."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Indisponível devido a <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar ordem das configurações."</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>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index fb0675a..e6ed4dc 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sem nome"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Pronto para transmitir"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Sem dispositivos disponíveis"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi não ligado"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMÁTICO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverter cores"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"O(a) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vai começar a captar tudo o que é apresentado no ecrã."</string>
     <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="8035284146227267681">"Gerir notificações"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gerir"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Sessão iniciada como <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Abrir os detalhes."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Indisponível devido a <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir as definições de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar a ordem das definições."</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>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index ab0f5f2..f26d1ba 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Ver todas as notificações"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispositivo sem nome"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Pronto para transmitir"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Não há dispositivos disponíveis"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi não conectado"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brilho"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverter cores"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> começará a capturar tudo o que for exibido na tela."</string>
     <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="8035284146227267681">"Gerenciar notificações"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gerenciar"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Login efetuado como <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Sem Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Abrir detalhes."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Indisponível devido a <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Abrir configurações de <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editar ordem das configurações."</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>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 9b5f5e1..c553f6e 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -175,9 +175,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Vedeți toate notificările"</string>
@@ -323,6 +321,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Dispozitiv nedenumit"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Pregătit pentru proiecție"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Niciun dispozitiv disponibil"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Rețeaua Wi-Fi nu este conectată"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Luminozitate"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMAT"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inversați culorile"</string>
@@ -448,7 +447,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> va începe să captureze tot ceea ce se afișează pe ecran."</string>
     <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="8035284146227267681">"Gestionați notificările"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Gestionați"</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>
@@ -790,6 +789,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Conectat(ă) ca <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Fără conexiune la internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Deschideți detaliile."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Indisponibile deoarece <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Deschideți setările <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Editați ordinea setărilor."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Pagina <xliff:g id="ID_1">%1$d</xliff:g> din <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 8069317..07aa66a 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -176,9 +176,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Показать все уведомления"</string>
@@ -325,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Безымянное устройство"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Готово к передаче"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Нет доступных устройств"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Нет подключения к сети Wi-Fi."</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яркость"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТОНАСТРОЙКА"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Обратные цвета"</string>
@@ -452,7 +451,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Приложение <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> получит доступ к изображению на экране устройства."</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="8035284146227267681">"Настроить уведомления"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Настроить"</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>
@@ -796,6 +795,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Выполнен вход под именем <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Нет подключения к Интернету."</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Показать подробности."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Недоступно. <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Открыть настройки <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Изменить порядок быстрых настроек."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Страница <xliff:g id="ID_1">%1$d</xliff:g> из <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -868,14 +868,10 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Да"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Нет"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Нажмите, чтобы настроить режим энергосбережения"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for auto_saver_text (6324376061044218113) -->
-    <skip />
+    <string name="auto_saver_text" msgid="6324376061044218113">"Включать автоматически при заряде батареи ниже <xliff:g id="PERCENTAGE">%d</xliff:g> %%."</string>
     <string name="no_auto_saver_action" msgid="8086002101711328500">"Отмена"</string>
     <string name="auto_saver_enabled_title" msgid="6726474226058316862">"Автоматический переход в режим энергосбережения включен"</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for auto_saver_enabled_text (874711029884777579) -->
-    <skip />
+    <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">"ОК"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Передача SysUI"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 8802833..aac62a2 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"බැටරිය ආරෝපණය කරමින්, සියයට <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"සියලු දැනුම්දීම් බලන්න"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"නම් නොකළ උපාංගය"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"කාස්ට් කිරීමට සුදානම්"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"උපාංග නොතිබේ"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi සම්බන්ධ නොවීය"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"දීප්තිමත් බව"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"ස්වයංක්‍රීය"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"වර්ණ යටිකුරු කරන්න"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"ඔබගේ තීරයේ දර්ශනය වන සෑම දෙයම <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ලබාගැනීම ආරම්භ කරන ලදි."</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="8035284146227267681">"දැනුම් දීම් කළමනාකරණය කරන්න"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"කළමනාකරණය කරන්න"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> ලෙස පුරන්න"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"අන්තර්ජාලය නැත"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"විස්තර විවෘත කරන්න."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> හේතුවෙන් ලබා ගත නොහැකිය"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> සැකසීම් විවෘත කරන්න."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"සැකසීම්වල අනුපිළිවෙළ සංංස්කරණය කරන්න."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g> න් <xliff:g id="ID_1">%1$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 233a81b..58e176a 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -176,9 +176,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Zobraziť všetky upozornenia"</string>
@@ -325,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nepomenované zariadenie"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Pripravené na prenášanie"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nie sú k dispozícii žiadne zariadenia"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Sieť Wi‑Fi nie je pripojená"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Jas"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTOMATICKY"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Inverzia farieb"</string>
@@ -452,7 +451,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikácia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> začne zaznamenávať všetok obsah zobrazený na vašej obrazovke."</string>
     <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="8035284146227267681">"Spravovať upozornenia"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Spravovať"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Upozornenia sú pozastavené režimom Nerušiť"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Spustiť"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Žiadne upozornenia"</string>
@@ -796,6 +795,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Prihlásený používateľ <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Žiadny internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Otvoriť podrobnosti"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nedostupné z nasledujúceho dôvodu: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Otvoriť nastavenia <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Upraviť poradie nastavení"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Strana <xliff:g id="ID_1">%1$d</xliff:g> z <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index c7e661a..1323fcd 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -176,9 +176,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Prikaži vsa obvestila"</string>
@@ -325,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Neimenovana naprava"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Pripravljeno za predvajanje"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Na voljo ni nobene naprave"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Povezava Wi-Fi ni vzpostavljena"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Svetlost"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"SAMODEJNO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Obrni barve"</string>
@@ -452,7 +451,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Aplikacija <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> bo začela zajemati vse, kar je prikazano na zaslonu."</string>
     <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="8035284146227267681">"Upravljanje obvestil"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Upravljanje"</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>
@@ -796,6 +795,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Prijavljeni ste kot <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Brez internetne povezave"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Odpri podrobnosti."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Ni na voljo zaradi tega razloga: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Odpri nastavitve za <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Uredi vrstni red nastavitev."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. stran od <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -868,14 +868,10 @@
     <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>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for auto_saver_text (6324376061044218113) -->
-    <skip />
+    <string name="auto_saver_text" msgid="6324376061044218113">"Samodejno vklopi, ko je energija akumulatorja na <xliff:g id="PERCENTAGE">%d</xliff:g> %%"</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.format failed for translation -->
-    <!-- no translation found for auto_saver_enabled_text (874711029884777579) -->
-    <skip />
+    <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>
     <string name="open_saver_setting_action" msgid="8314624730997322529">"Nastavitve"</string>
     <string name="auto_saver_okay_action" msgid="2701221740227683650">"V redu"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Izvoz kopice SysUI"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index f4d3d2a..8f08665 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Bateria po ngarkohet, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> për qind."</string>
+    <string name="accessibility_battery_level_charging" msgid="1147587904439319646">"Bateria po ngarkohet, <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Shiko të gjitha njoftimet"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Pajisje e paemërtuar"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Gati për transmetim"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Nuk ofrohet për përdorim asnjë pajisje"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi nuk është lidhur"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ndriçimi"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"Automatike"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Shkëmbe ngjyrat"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> do të fillojë të regjistrojë çdo gjë që shfaqet në ekran."</string>
     <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="8035284146227267681">"Menaxho njoftimet"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Menaxho"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Identifikuar si <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Nuk ka internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Hap detajet."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Nuk ofrohet për shkak se <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Hap cilësimet e <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Modifiko rendin e cilësimeve."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Faqja <xliff:g id="ID_1">%1$d</xliff:g> nga <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 5825231..609f332 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -175,7 +175,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_charging" msgid="1147587904439319646">"Батерија се пуни, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Погледајте сва обавештења"</string>
@@ -321,6 +321,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Неименовани уређај"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Спремно за пребацивање"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Није доступан ниједан уређај"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi није повезан"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Осветљеност"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АУТОМАТСКА"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Обрни боје"</string>
@@ -446,7 +447,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ће почети да снима све што се приказује на екрану."</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="8035284146227267681">"Управљајте обавештењима"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Управљајте"</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>
@@ -788,6 +789,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Пријављени сте као <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Нема интернета"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Отвори детаље."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Није доступно из следећег разлога: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Отвори подешавања за <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Измени редослед подешавања."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>. страна од <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 7040ec2..72ae99b 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Namnlös enhet"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Redo att casta"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Inga tillgängliga enheter"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Inte ansluten till Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ljusstyrka"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Invertera färger"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> tar en bild av allt som visas på skärmen."</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="8035284146227267681">"Hantera aviseringar"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Hantera"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Inloggad som <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Inget internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Visa information."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Inte tillgänglig på grund av <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Öppna <xliff:g id="ID_1">%s</xliff:g>-inställningarna."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Ändra ordning på inställningarna."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Sida <xliff:g id="ID_1">%1$d</xliff:g> av <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 0633e8a..a73d0e7 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Kifaa hakina jina"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Tayari kutuma"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Hakuna vifaa vilivyopatikana"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi haijaunganishwa"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ung\'avu"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"KIOTOMATIKI"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Pindua rangi"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> itaanza kupiga picha kila kitu kinachoonyeshwa kwenye skrini yako."</string>
     <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="8035284146227267681">"Dhibiti arifa"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Dhibiti"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Umeingia katika akaunti ya <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Hakuna intaneti"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Fungua maelezo."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Haipatikani kutokana na <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Fungua mipangilio ya <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Badilisha orodha ya mipangilio."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Ukurasa wa <xliff:g id="ID_1">%1$d</xliff:g> kati ya <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 469e797..02457d9 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"பெயரிடப்படாத சாதனம்"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"திரையிடத் தயார்"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"சாதனங்கள் இல்லை"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"வைஃபை இணைக்கப்படவில்லை"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ஒளிர்வு"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"தானியங்கு"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"வண்ணங்களை மாற்று"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"திரையில் காட்டப்படும் அனைத்தையும் <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> படமெடுக்கும்."</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="8035284146227267681">"அறிவிப்புகளை நிர்வகி"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"அறிவிப்புகளை நிர்வகி"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> என்ற பெயரில் உள்நுழைந்துள்ளீர்கள்"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"இணைய இணைப்பு இல்லை"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"விவரங்களைத் திற."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> என்பதால் தற்போது முடக்கப்பட்டுள்ளது"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> அமைப்புகளைத் திற."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"அமைப்புகளின் வரிசை முறையைத் திருத்து."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"பக்கம் <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"சேமிப்பிடம்"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"குறிப்புகள்"</string>
     <string name="instant_apps" msgid="6647570248119804907">"இன்ஸ்டண்ட் ஆப்ஸ்"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> இயங்குகிறது"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"நிறுவ வேண்டிய தேவையில்லாமல் ஆப்ஸ் திறக்கப்பட்டது."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"நிறுவ வேண்டிய தேவையில்லாமல் ஆப்ஸ் திறக்கப்பட்டது. மேலும் அறியத் தட்டவும்."</string>
     <string name="app_info" msgid="6856026610594615344">"பயன்பாட்டுத் தகவல்"</string>
     <string name="go_to_web" msgid="1106022723459948514">"இணையத்திற்குச் செல்"</string>
     <string name="mobile_data" msgid="7094582042819250762">"மொபைல் டேட்டா"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 5d869f1..a6d7699 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"బ్యాటరీ ఛార్జ్ అవుతోంది, <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"అన్ని నోటిఫికేషన్‌లను చూడండి"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"పేరులేని పరికరం"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"ప్రసారం చేయడానికి సిద్ధంగా ఉంది"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"పరికరాలు ఏవీ అందుబాటులో లేవు"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi‑Fi కనెక్ట్ కాలేదు"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ప్రకాశం"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"స్వయంచాలకం"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"రంగులను తారుమారు చేయి"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> మీ స్క్రీన్‌పై కనిపించే ప్రతిదాన్ని క్యాప్చర్ చేయడం ప్రారంభిస్తుంది."</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="8035284146227267681">"నోటిఫికేషన్‌లను నిర్వహించండి"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"నిర్వహించండి"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> వలె సైన్ ఇన్ చేసారు"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ఇంటర్నెట్ లేదు"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"వివరాలను తెరవండి."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> కారణంగా అందుబాటులో లేదు"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> సెట్టింగ్‌లను తెరవండి."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"సెట్టింగ్‌ల క్రమాన్ని సవరించండి."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_2">%2$d</xliff:g>లో <xliff:g id="ID_1">%1$d</xliff:g>వ పేజీ"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"నిల్వ"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"సూచనలు"</string>
     <string name="instant_apps" msgid="6647570248119804907">"తక్షణ యాప్‌లు"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> అమలవుతోంది"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"ఇన్‌స్టాల్ చేయకుండా యాప్ తెరవబడింది."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"ఇన్‌స్టాల్ చేయకుండా యాప్ తెరవబడింది. మరింత తెలుసుకోవడానికి నొక్కండి."</string>
     <string name="app_info" msgid="6856026610594615344">"యాప్ సమాచారం"</string>
     <string name="go_to_web" msgid="1106022723459948514">"వెబ్‌కు వెళ్లు"</string>
     <string name="mobile_data" msgid="7094582042819250762">"మొబైల్ డేటా"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 408c5a0..8c78687 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"อุปกรณ์ที่ไม่มีชื่อ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"พร้อมที่จะส่ง"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"ไม่มีอุปกรณ์ที่สามารถใช้ได้"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"ไม่ได้เชื่อมต่อ Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"ความสว่าง"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"อัตโนมัติ"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"สลับสี"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> จะเริ่มจับภาพทุกอย่างที่แสดงบนหน้าจอ"</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="8035284146227267681">"จัดการการแจ้งเตือน"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"จัดการ"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"ลงชื่อเข้าใช้เป็น <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"ไม่มีอินเทอร์เน็ต"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"เปิดรายละเอียด"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"ไม่พร้อมใช้งานเนื่องจาก<xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"เปิดการตั้งค่า <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"แก้ไขลำดับการตั้งค่า"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"หน้า <xliff:g id="ID_1">%1$d</xliff:g> จาก <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 8da4946..21cf1f2 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Walang pangalang device"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Handang mag-cast"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Walang available na mga device"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Hindi nakakonekta sa Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Brightness"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AUTO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"I-invert ang mga kulay"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"Sisimulan ng i-capture ng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ang lahat ng ipinapakita sa iyong screen."</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="8035284146227267681">"Pamahalaan ang mga notification"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Pamahalaan"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Naka-sign in bilang <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Walang internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Buksan ang mga detalye."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Hindi available dahil sa <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Buksan ang mga setting ng <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"I-edit ang pagkakasunud-sunod ng mga setting."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Page <xliff:g id="ID_1">%1$d</xliff:g> ng <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index de8ed9d..fb200ec 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Adsız cihaz"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Yayın için hazır"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Kullanılabilir cihaz yok"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Kablosuz ağ bağlı değil"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Parlaklık"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OTOMATİK"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Renkleri çevir"</string>
@@ -372,7 +373,7 @@
     <string name="recents_accessibility_split_screen_left" msgid="8987144699630620019">"Ekranı sola doğru böl"</string>
     <string name="recents_accessibility_split_screen_right" msgid="275069779299592867">"Ekranı sağa doğru böl"</string>
     <string name="quick_step_accessibility_toggle_overview" msgid="7171470775439860480">"Genel bakışı aç/kapat"</string>
-    <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Ödeme alındı"</string>
+    <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Şarj oldu"</string>
     <string name="expanded_header_battery_charging" msgid="205623198487189724">"Şarj oluyor"</string>
     <string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"Tam şarj olmasına <xliff:g id="CHARGING_TIME">%s</xliff:g> kaldı"</string>
     <string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"Şarj olmuyor"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, ekranınızda görüntülenen her şeyi kaydetmeye başlayacak."</string>
     <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="8035284146227267681">"Bildirimleri yönet"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Yönet"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> olarak oturum açıldı"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"İnternet yok"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Ayrıntıları aç."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> nedeniyle kullanılamıyor"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ayarlarını aç."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Ayarların sırasını düzenle."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Sayfa <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 6c2e661..82b56a2 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -176,9 +176,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Переглянути всі сповіщення"</string>
@@ -325,6 +323,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Пристрій без назви"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Готово до трансляції"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Немає пристроїв"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi не під’єднано"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Яскравість"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"АВТО"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Інвертувати кольори"</string>
@@ -452,7 +451,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> отримає доступ до всіх даних, які відображаються на вашому екрані."</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="8035284146227267681">"Керувати сповіщеннями"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Керувати"</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>
@@ -796,6 +795,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Ви ввійшли як <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Немає Інтернету"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Відкрити деталі."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Недоступно, оскільки <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Відкрити налаштування <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Змінити порядок налаштувань."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Сторінка <xliff:g id="ID_1">%1$d</xliff:g> з <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -868,10 +868,10 @@
     <string name="slice_permission_allow" msgid="2340244901366722709">"Дозволити"</string>
     <string name="slice_permission_deny" msgid="7683681514008048807">"Відмовити"</string>
     <string name="auto_saver_title" msgid="1217959994732964228">"Торкніться, щоб увімкнути автоматичний режим економії заряду акумулятора"</string>
-    <string name="auto_saver_text" msgid="6324376061044218113">"Вмикати автоматично, коли рівень знижується до <xliff:g id="PERCENTAGE">%d</xliff:g>%%"</string>
+    <string name="auto_saver_text" msgid="6324376061044218113">"Вмикати автоматично, коли заряд акумулятора знижується до <xliff:g id="PERCENTAGE">%d</xliff:g>%%"</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>
+    <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>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 88391b0..b02ceae 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"بیٹری چارجنگ، <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"تمام اطلاعات دیکھیں"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"بغیر نام والا آلہ"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"کاسٹ کرنے کیلئے تیار"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"کوئی آلات دستیاب نہیں ہیں"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"‏Wi-Fi سے منسلک نہیں ہے"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"چمکیلا پن"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"خودکار"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"رنگ پلٹیں"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> آپ کی اسکرین پر ڈسپلے ہونے والی ہر چیز کو کیپچر کرنا شروع کر دیگی۔"</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="8035284146227267681">"اطلاعات کا نظم کریں"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"نظم کریں"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> کے بطور سائن ان ہے"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"انٹرنیٹ نہیں ہے"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"تفصیلات کھولیں۔"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g> کی وجہ سے دستیاب نہیں ہے"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> ترتیبات کھولیں۔"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"ترتیبات کی ترتیب میں ترمیم کریں۔"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"صفحہ <xliff:g id="ID_1">%1$d</xliff:g> از <xliff:g id="ID_2">%2$d</xliff:g>"</string>
@@ -825,12 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"اسٹوریج"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"اشارات"</string>
     <string name="instant_apps" msgid="6647570248119804907">"فوری ایپس"</string>
-    <!-- no translation found for instant_apps_title (8738419517367449783) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (1183313016396018086) -->
-    <skip />
-    <!-- no translation found for instant_apps_message_with_help (6179830437630729747) -->
-    <skip />
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> چل رہی ہے"</string>
+    <string name="instant_apps_message" msgid="1183313016396018086">"انسٹال کیے بغیر کھلنے والی ایپ۔"</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"انسٹال کیے بغیر کھلنے والی ایپ۔ مزید جاننے کے لیے تھپتھپائيں۔"</string>
     <string name="app_info" msgid="6856026610594615344">"ایپ کی معلومات"</string>
     <string name="go_to_web" msgid="1106022723459948514">"ویب پر جائیں"</string>
     <string name="mobile_data" msgid="7094582042819250762">"موبائل ڈیٹا"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 37d31c2..a128e7f 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -127,7 +127,7 @@
     <string name="accessibility_data_one_bar" msgid="1415625833238273628">"Ma’lumotlar bitta panelda."</string>
     <string name="accessibility_data_two_bars" msgid="6166018492360432091">"Ma’lumotlar ikkita panelda."</string>
     <string name="accessibility_data_three_bars" msgid="9167670452395038520">"Ma’lumotlar uchta panelda."</string>
-    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Ma’lumot uzatish signali to‘liq."</string>
+    <string name="accessibility_data_signal_full" msgid="2708384608124519369">"Internet signali butun."</string>
     <string name="accessibility_wifi_name" msgid="7202151365171148501">"Ulangan: <xliff:g id="WIFI">%s</xliff:g>."</string>
     <string name="accessibility_bluetooth_name" msgid="8441517146585531676">"Ulangan: <xliff:g id="BLUETOOTH">%s</xliff:g>."</string>
     <string name="accessibility_cast_name" msgid="4026393061247081201">"Bunga ulangan: <xliff:g id="CAST">%s</xliff:g>."</string>
@@ -162,7 +162,7 @@
     <string name="data_connection_roaming" msgid="6037232010953697354">"Rouming"</string>
     <string name="data_connection_edge" msgid="871835227939216682">"EDGE"</string>
     <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
-    <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM karta yo‘q."</string>
+    <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM karta solinmagan."</string>
     <string name="accessibility_cell_data" msgid="5326139158682385073">"Mobil internet"</string>
     <string name="accessibility_cell_data_on" msgid="5927098403452994422">"Mobil internet yoniq"</string>
     <string name="cell_data_off_content_description" msgid="4356113230238585072">"Mobil internet yoqilmagan"</string>
@@ -174,9 +174,7 @@
     <string name="carrier_network_change_mode" msgid="8149202439957837762">"Mobil tarmoqni o‘zgartirish"</string>
     <string name="accessibility_battery_details" msgid="7645516654955025422">"Batareya quvvati sarfi haqida ma’lumot"</string>
     <string name="accessibility_battery_level" msgid="7451474187113371965">"Batareya <xliff:g id="NUMBER">%d</xliff:g> foiz."</string>
-    <!-- String.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Barcha bildirishnomalarni ko‘rish"</string>
@@ -300,7 +298,7 @@
     <string name="quick_settings_rotation_locked_landscape_label" msgid="8553157770061178719">"Eniga"</string>
     <string name="quick_settings_ime_label" msgid="7073463064369468429">"Kiritish usuli"</string>
     <string name="quick_settings_location_label" msgid="5011327048748762257">"Joylashuv"</string>
-    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Joylashuv xizmati o‘chiq"</string>
+    <string name="quick_settings_location_off_label" msgid="7464544086507331459">"Joylashuvni aniqlash xizmati yoqilmagan"</string>
     <string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media qurilma"</string>
     <string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
     <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Favqulodda chaqiruvlar"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Nomsiz qurilma"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Tarqatish uchun tayyor"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Qurilmalar topilmadi"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Wi-Fi tarmoqqa ulanmagan"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Yorqinlik"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"AVTOMATIC"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Teskari ranglar"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ilovasi qurilma ekranidagi har qanday tasvirni ko‘rishni boshlaydi."</string>
     <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="8035284146227267681">"Bildirishnomalarni boshqarish"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Boshqarish"</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>
@@ -782,8 +781,9 @@
     <string name="accessibility_quick_settings_collapse" msgid="1792625797142648105">"Tezkor sozlamalarni yopish."</string>
     <string name="accessibility_quick_settings_alarm_set" msgid="1863000242431528676">"Signal o‘rnatildi."</string>
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"<xliff:g id="ID_1">%s</xliff:g> sifatida kirgansiz"</string>
-    <string name="data_connection_no_internet" msgid="4503302451650972989">"Internetga ulanmagan"</string>
+    <string name="data_connection_no_internet" msgid="4503302451650972989">"Internetga ulanmagansiz"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Tafsilotlarini ko‘rsatish."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Mavjud emas, sababi: <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"<xliff:g id="ID_1">%s</xliff:g> sozlamalarini ochish."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Sozlamalar tartibini o‘zgartirish."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"<xliff:g id="ID_1">%1$d</xliff:g>-sahifa, jami: <xliff:g id="ID_2">%2$d</xliff:g> ta sahifa"</string>
@@ -827,9 +827,9 @@
     <string name="notification_channel_storage" msgid="3077205683020695313">"Xotira"</string>
     <string name="notification_channel_hints" msgid="7323870212489152689">"Maslahatlar"</string>
     <string name="instant_apps" msgid="6647570248119804907">"Darhol ochiladigan ilovalar"</string>
-    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> ishlamoqda"</string>
+    <string name="instant_apps_title" msgid="8738419517367449783">"<xliff:g id="APP">%1$s</xliff:g> ishlayapti"</string>
     <string name="instant_apps_message" msgid="1183313016396018086">"Ilova o‘rnatilmasdan ochildi."</string>
-    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Ilova o‘rnatilmasdan ochildi. Batafsil axborot oolish uchun bu yerga bosing."</string>
+    <string name="instant_apps_message_with_help" msgid="6179830437630729747">"Ilova o‘rnatilmasdan ochildi. Batafsil axborot uchun bu yerga bosing."</string>
     <string name="app_info" msgid="6856026610594615344">"Ilova haqida"</string>
     <string name="go_to_web" msgid="1106022723459948514">"Brauzerga o‘tish"</string>
     <string name="mobile_data" msgid="7094582042819250762">"Mobil internet"</string>
@@ -856,10 +856,10 @@
     <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>
-    <string name="auto_saver_text" msgid="6324376061044218113">"Batareya quvvati <xliff:g id="PERCENTAGE">%d</xliff:g>%% ga tushganda avtomatik yoqish"</string>
+    <string name="auto_saver_text" msgid="6324376061044218113">"Batareya quvvati <xliff:g id="PERCENTAGE">%d</xliff:g>%% ga tushganida avtomatik yoqish"</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 tushganda, quvvat tejash rejimi avtomatik ravishda yoqiladi."</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>
     <string name="open_saver_setting_action" msgid="8314624730997322529">"Sozlamalar"</string>
     <string name="auto_saver_okay_action" msgid="2701221740227683650">"OK"</string>
     <string name="heap_dump_tile_name" msgid="9141031328971226374">"Dump SysUI Heap"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index f476790..c7b9178 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"Đang sạc pin, <xliff:g id="BATTERY_PERCENTAGE">%d</xliff:g> phần trăm."</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"Xem tất cả thông báo"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Thiết bị không có tên"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Sẵn sàng truyền"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Không có thiết bị nào"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"Chưa kết nối với Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Độ sáng"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"TỰ ĐỘNG"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Đảo ngược màu"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ bắt đầu chụp mọi thứ hiển thị trên màn hình."</string>
     <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="8035284146227267681">"Quản lý thông báo"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Quản lý"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Đã đăng nhập là <xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Không có Internet"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Mở chi tiết."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Không sử dụng được do <xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Mở cài đặt <xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Chỉnh sửa thứ tự cài đặt."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Trang <xliff:g id="ID_1">%1$d</xliff:g> / <xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index aaa4c63..0bfcdcf 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"正在充电,已完成百分之<xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"查看所有通知"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"未命名设备"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"已准备好投射"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"没有可用设备"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"未连接到 WLAN 网络"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自动"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"反色"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>将开始截取您的屏幕上显示的所有内容。"</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="8035284146227267681">"管理通知"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"目前登录的用户名为<xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"未连接到互联网"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"打开详情页面。"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g>,因此目前无法使用"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"打开<xliff:g id="ID_1">%s</xliff:g>设置。"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"修改设置顺序。"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"第 <xliff:g id="ID_1">%1$d</xliff:g> 页,共 <xliff:g id="ID_2">%2$d</xliff:g> 页"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index aad4b4f..cf93802 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -174,9 +174,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.format failed for translation -->
-    <!-- no translation found for accessibility_battery_level_charging (1147587904439319646) -->
-    <skip />
+    <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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"睇所有通知"</string>
@@ -321,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"未命名的裝置"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"放送準備完成"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"沒有可用裝置"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"未連線至 Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"反轉顏色"</string>
@@ -444,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 將開始擷取您的螢幕上顯示的內容。"</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="8035284146227267681">"管理通知"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</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>
@@ -784,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"已登入為<xliff:g id="ID_1">%s</xliff:g>。"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"沒有互聯網連線"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"開啟詳細資料頁面。"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g>,所以宜家用唔到"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"開啟<xliff:g id="ID_1">%s</xliff:g>設定頁面。"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"編輯設定次序。"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁 (共 <xliff:g id="ID_2">%2$d</xliff:g> 頁)"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 6b88545..c5a2f90 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -174,7 +174,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_charging" msgid="1147587904439319646">"充電中,已完成百分之 <xliff:g id="BATTERY_PERCENTAGE">%d</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>
     <string name="accessibility_overflow_action" msgid="5681882033274783311">"查看所有通知"</string>
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"未命名的裝置"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"可以開始投放了"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"沒有可用裝置"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"未連線至 Wi-Fi"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"亮度"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"自動"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"反轉顏色"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> 將開始擷取你的螢幕上顯示的內容。"</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="8035284146227267681">"管理通知"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"管理"</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>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"以「<xliff:g id="ID_1">%s</xliff:g>」的身分登入"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"沒有網際網路連線"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"開啟詳細資料。"</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"<xliff:g id="REASON">%s</xliff:g>,因此目前無法使用"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"開啟「<xliff:g id="ID_1">%s</xliff:g>」設定。"</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"編輯設定順序。"</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"第 <xliff:g id="ID_1">%1$d</xliff:g> 頁,共 <xliff:g id="ID_2">%2$d</xliff:g> 頁"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 085c3b3..2fc207a 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -319,6 +319,7 @@
     <string name="quick_settings_cast_device_default_name" msgid="5367253104742382945">"Idivayisi engenalo igama"</string>
     <string name="quick_settings_cast_device_default_description" msgid="2484573682378634413">"Ilungele ukusakaza"</string>
     <string name="quick_settings_cast_detail_empty_text" msgid="311785821261640623">"Ayikho idivayisi etholakalayo"</string>
+    <string name="quick_settings_cast_no_wifi" msgid="2696477881905521882">"I-Wi-Fi ayixhunyiwe"</string>
     <string name="quick_settings_brightness_dialog_title" msgid="8599674057673605368">"Ukugqama"</string>
     <string name="quick_settings_brightness_dialog_auto_brightness_label" msgid="5064982743784071218">"OKUZENZAKALELAYO"</string>
     <string name="quick_settings_inversion_label" msgid="8790919884718619648">"Faka imibala"</string>
@@ -442,7 +443,7 @@
     <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> izoqala ukuthwebula yonke into eboniswa kusikrini sakho."</string>
     <string name="media_projection_remember_text" msgid="3103510882172746752">"Ungabonisi futhi"</string>
     <string name="clear_all_notifications_text" msgid="814192889771462828">"Sula konke"</string>
-    <string name="manage_notifications_text" msgid="8035284146227267681">"Phatha izaziso"</string>
+    <string name="manage_notifications_text" msgid="2386728145475108753">"Phatha"</string>
     <string name="dnd_suppressing_shade_text" msgid="1904574852846769301">"Izaziso zimiswe okwesikhashana ukungaphazamisi"</string>
     <string name="media_projection_action_text" msgid="8470872969457985954">"Qala manje"</string>
     <string name="empty_shade_text" msgid="708135716272867002">"Azikho izaziso"</string>
@@ -782,6 +783,7 @@
     <string name="accessibility_quick_settings_user" msgid="1567445362870421770">"Ungene ngemvume njengo-<xliff:g id="ID_1">%s</xliff:g>"</string>
     <string name="data_connection_no_internet" msgid="4503302451650972989">"Ayikho i-inthanethi"</string>
     <string name="accessibility_quick_settings_open_details" msgid="4230931801728005194">"Vula imininingwane."</string>
+    <string name="accessibility_quick_settings_not_available" msgid="4190068184294019846">"Ayitholakali ngenxa ye-<xliff:g id="REASON">%s</xliff:g>"</string>
     <string name="accessibility_quick_settings_open_settings" msgid="7806613775728380737">"Vula izilungiselelo ze-<xliff:g id="ID_1">%s</xliff:g>."</string>
     <string name="accessibility_quick_settings_edit" msgid="7839992848995240393">"Hlela uhlelo lwezilungiselelo."</string>
     <string name="accessibility_quick_settings_page" msgid="5032979051755200721">"Ikhasi <xliff:g id="ID_1">%1$d</xliff:g> kwangu-<xliff:g id="ID_2">%2$d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 2fbf42f..6378309 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -137,15 +137,9 @@
     <integer name="quick_settings_brightness_dialog_short_timeout">2000</integer>
     <integer name="quick_settings_brightness_dialog_long_timeout">4000</integer>
 
-    <!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? -->
-    <bool name="config_show4GForLTE">true</bool>
-
     <!-- Show indicator for Wifi on but not connected. -->
     <bool name="config_showWifiIndicatorWhenEnabled">false</bool>
 
-    <!-- Should "LTE"/"4G" be shown instead of "LTE+"/"4G+" when on NETWORK_TYPE_LTE_CA? -->
-    <bool name="config_hideLtePlus">false</bool>
-
     <!-- The number of milliseconds before the heads up notification auto-dismisses. -->
     <integer name="heads_up_notification_decay">5000</integer>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 7c355c9..ab7dec9 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -645,10 +645,6 @@
     <dimen name="keyguard_affordance_height">56dp</dimen>
     <dimen name="keyguard_affordance_width">56dp</dimen>
 
-    <!-- The width/height of the phone/camera/unlock icon drawable on keyguard. -->
-    <dimen name="keyguard_affordance_icon_height">24dp</dimen>
-    <dimen name="keyguard_affordance_icon_width">24dp</dimen>
-
     <dimen name="keyguard_indication_margin_bottom">65dp</dimen>
 
     <!-- The text size for battery level -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index e1c71fa..42e19aa 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -761,6 +761,8 @@
     <string name="quick_settings_cast_device_default_description">Ready to cast</string>
     <!-- QuickSettings: Cast detail panel, text when there are no items [CHAR LIMIT=NONE] -->
     <string name="quick_settings_cast_detail_empty_text">No devices available</string>
+    <!-- QuickSettings: Cast unavailable, text when not connected to WiFi [CHAR LIMIT=NONE] -->
+    <string name="quick_settings_cast_no_wifi">Wi\u2011Fi not connected</string>
     <!-- QuickSettings: Brightness dialog title [CHAR LIMIT=NONE] -->
     <string name="quick_settings_brightness_dialog_title">Brightness</string>
     <!-- QuickSettings: Brightness dialog auto brightness button [CHAR LIMIT=NONE] -->
@@ -1999,6 +2001,9 @@
     <!-- accessibility label for quick settings items that open a details page [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_open_details">Open details.</string>
 
+    <!-- accessibility label for quick settings items that are currently disabled. Must have a reason [CHAR LIMIT=NONE] -->
+    <string name="accessibility_quick_settings_not_available">Unvailable due to <xliff:g name="reason" id="reason" example="Wifi not available">%s</xliff:g></string>
+
     <!-- accessibility label for quick settings items that open a details page [CHAR LIMIT=NONE] -->
     <string name="accessibility_quick_settings_open_settings">Open <xliff:g name="page" example="Bluetooth">%s</xliff:g> settings.</string>
 
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 8442dd1..6446367 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -279,7 +279,7 @@
         <item name="android:fontFamily">sans-serif</item>
     </style>
 
-    <style name="BaseBrightnessDialogContainer">
+    <style name="BaseBrightnessDialogContainer" parent="@style/Theme.SystemUI">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>
     </style>
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index defc49b..31a538c 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -21,10 +21,10 @@
     ],
 
     static_libs: [
-        "SystemUIPluginLib"
+        "PluginCoreLib"
     ],
 
-    // Enforce that the library is build agains java 7 so that there are
+    // Enforce that the library is built against java 7 so that there are
     // no compatibility issues with launcher
     java_version: "1.7",
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginEnabler.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginEnabler.java
new file mode 100644
index 0000000..74fd13f
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginEnabler.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.shared.plugins;
+
+import android.content.ComponentName;
+
+/**
+ * Enables and disables plugins.
+ */
+public interface PluginEnabler {
+    void setEnabled(ComponentName component, boolean enabled);
+    boolean isEnabled(ComponentName component);
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java
index 9857894..c3815e4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInitializer.java
@@ -25,10 +25,16 @@
     Looper getBgLooper();
 
     /**
-     * This Runnable is run on the bg looper during initialization of {@link PluginManagerImpl}.
-     * It can be null.
+     * Called from the bg looper during initialization of {@link PluginManagerImpl}.
      */
-    Runnable getBgInitCallback();
+    void onPluginManagerInit();
 
     String[] getWhitelistedPlugins(Context context);
+
+    PluginEnabler getPluginEnabler(Context context);
+
+    /**
+     * Called from {@link PluginManagerImpl#handleWtfs()}.
+     */
+    void handleWtfs();
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
index e80c079..8cc6091 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstanceManager.java
@@ -159,10 +159,8 @@
         // plugin, if the plugin causing a crash cannot be identified, they are all disabled
         // assuming one of them must be bad.
         Log.w(TAG, "Disabling plugin " + info.mPackage + "/" + info.mClass);
-        mPm.setComponentEnabledSetting(
-                new ComponentName(info.mPackage, info.mClass),
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
+        mManager.getPluginEnabler().setEnabled(new ComponentName(info.mPackage, info.mClass),
+                false);
     }
 
     public <T> boolean dependsOn(Plugin p, Class<T> cls) {
@@ -280,8 +278,7 @@
             if (pkgName != null) {
                 intent.setPackage(pkgName);
             }
-            List<ResolveInfo> result =
-                    mPm.queryIntentServices(intent, 0);
+            List<ResolveInfo> result = mPm.queryIntentServices(intent, 0);
             if (DEBUG) Log.d(TAG, "Found " + result.size() + " plugins");
             if (result.size() > 1 && !mAllowMultiple) {
                 // TODO: Show warning.
@@ -306,6 +303,10 @@
                 Log.w(TAG, "Plugin cannot be loaded on production build: " + component);
                 return null;
             }
+            if (!mManager.getPluginEnabler().isEnabled(component)) {
+                if (DEBUG) Log.d(TAG, "Plugin is not enabled, aborting load: " + component);
+                return null;
+            }
             String pkg = component.getPackageName();
             String cls = component.getClassName();
             try {
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 7f1d161..87f2934 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
@@ -41,12 +41,11 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
 import com.android.systemui.shared.plugins.PluginInstanceManager.PluginContextWrapper;
 import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo;
-import com.android.systemui.plugins.annotations.ProvidesInterface;
 
 import dalvik.system.PathClassLoader;
 
@@ -74,11 +73,12 @@
     private final PluginInstanceManagerFactory mFactory;
     private final boolean isDebuggable;
     private final PluginPrefs mPluginPrefs;
+    private final PluginEnabler mPluginEnabler;
+    private final PluginInitializer mPluginInitializer;
     private ClassLoaderFilter mParentClassLoader;
     private boolean mListening;
     private boolean mHasOneShot;
     private Looper mLooper;
-    private boolean mWtfsSet;
 
     public PluginManagerImpl(Context context, PluginInitializer initializer) {
         this(context, new PluginInstanceManagerFactory(), Build.IS_DEBUGGABLE,
@@ -87,28 +87,36 @@
 
     @VisibleForTesting
     PluginManagerImpl(Context context, PluginInstanceManagerFactory factory, boolean debuggable,
-            UncaughtExceptionHandler defaultHandler, PluginInitializer initializer) {
+            UncaughtExceptionHandler defaultHandler, final PluginInitializer initializer) {
         mContext = context;
         mFactory = factory;
         mLooper = initializer.getBgLooper();
         isDebuggable = debuggable;
         mWhitelistedPlugins.addAll(Arrays.asList(initializer.getWhitelistedPlugins(mContext)));
         mPluginPrefs = new PluginPrefs(mContext);
+        mPluginEnabler = initializer.getPluginEnabler(mContext);
+        mPluginInitializer = initializer;
 
         PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler(
                 defaultHandler);
         Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler);
 
-        Runnable bgRunnable = initializer.getBgInitCallback();
-        if (bgRunnable != null) {
-            new Handler(mLooper).post(bgRunnable);
-        }
+        new Handler(mLooper).post(new Runnable() {
+            @Override
+            public void run() {
+                initializer.onPluginManagerInit();
+            }
+        });
     }
 
     public String[] getWhitelistedPlugins() {
         return mWhitelistedPlugins.toArray(new String[0]);
     }
 
+    public PluginEnabler getPluginEnabler() {
+        return mPluginEnabler;
+    }
+
     public <T extends Plugin> T getOneShotPlugin(Class<T> cls) {
         ProvidesInterface info = cls.getDeclaredAnnotation(ProvidesInterface.class);
         if (info == null) {
@@ -202,9 +210,7 @@
             Uri uri = intent.getData();
             ComponentName component = ComponentName.unflattenFromString(
                     uri.toString().substring(10));
-            mContext.getPackageManager().setComponentEnabledSetting(component,
-                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                    PackageManager.DONT_KILL_APP);
+            getPluginEnabler().setEnabled(component, false);
             mContext.getSystemService(NotificationManager.class).cancel(component.getClassName(),
                     SystemMessage.NOTE_PLUGIN);
         } else {
@@ -296,16 +302,7 @@
     }
 
     public void handleWtfs() {
-        if (!mWtfsSet) {
-            mWtfsSet = true;
-            Log.setWtfHandler(new Log.TerribleFailureHandler() {
-                @Override
-                public void onTerribleFailure(String tag, Log.TerribleFailure what,
-                        boolean system) {
-                    throw new CrashWhilePluginActiveException(what);
-                }
-            });
-        }
+        mPluginInitializer.handleWtfs();
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -388,7 +385,7 @@
         }
     }
 
-    private class CrashWhilePluginActiveException extends RuntimeException {
+    public static class CrashWhilePluginActiveException extends RuntimeException {
         public CrashWhilePluginActiveException(Throwable throwable) {
             super(throwable);
         }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
index 19e8673..114d69e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/BackgroundTaskLoader.java
@@ -27,6 +27,7 @@
 /**
  * Background task resource loader
  */
+@Deprecated
 class BackgroundTaskLoader implements Runnable {
     static String TAG = "BackgroundTaskLoader";
     static boolean DEBUG = false;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java
index 898d64a..7e0f8fe 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/FilteredTaskList.java
@@ -27,6 +27,7 @@
 /**
  * A list of filtered tasks.
  */
+@Deprecated
 class FilteredTaskList {
 
     private final ArrayList<Task> mTasks = new ArrayList<>();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java
index 852463f..f02bc5a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/HighResThumbnailLoader.java
@@ -34,6 +34,7 @@
 /**
  * Loader class that loads full-resolution thumbnails when appropriate.
  */
+@Deprecated
 public class HighResThumbnailLoader implements
         TaskCallbacks, BackgroundTaskLoader.OnIdleChangedListener {
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
index f69e911..8b3ae42 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java
@@ -45,6 +45,7 @@
  *   3) executePlan() will actually load and fill in the icons and thumbnails according to the load
  *      options specified, such that we can transition into the Recents activity seamlessly
  */
+@Deprecated
 public class RecentsTaskLoadPlan {
 
     /** The set of conditions to preload tasks. */
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
index 996c837..b50aa76 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java
@@ -42,6 +42,7 @@
 /**
  * Recents task loader
  */
+@Deprecated
 public class RecentsTaskLoader {
     private static final String TAG = "RecentsTaskLoader";
     private static final boolean DEBUG = false;
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 b51004b..368e503 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
@@ -16,6 +16,7 @@
 
 package com.android.systemui.shared.recents.model;
 
+import android.app.ActivityManager;
 import android.app.ActivityManager.TaskDescription;
 import android.content.ComponentName;
 import android.content.Intent;
@@ -31,13 +32,14 @@
 import java.util.Objects;
 
 /**
- * A task represents the top most task in the system's task stack.
+ * A task in the recent tasks list.
  */
 public class Task {
 
     public static final String TAG = "Task";
 
     /* Task callbacks */
+    @Deprecated
     public interface TaskCallbacks {
         /* Notifies when a task has been bound */
         void onTaskDataLoaded(Task task, ThumbnailData thumbnailData);
@@ -65,6 +67,21 @@
 
         private int mHashCode;
 
+        public TaskKey(ActivityManager.RecentTaskInfo t) {
+            ComponentName sourceComponent = t.origActivity != null
+                    // Activity alias if there is one
+                    ? t.origActivity
+                    // The real activity if there is no alias (or the target if there is one)
+                    : t.realActivity;
+            this.id = t.taskId;
+            this.windowingMode = t.configuration.windowConfiguration.getWindowingMode();
+            this.baseIntent = t.baseIntent;
+            this.sourceComponent = sourceComponent;
+            this.userId = t.userId;
+            this.lastActiveTime = t.lastActiveTime;
+            updateHashCode();
+        }
+
         public TaskKey(int id, int windowingMode, Intent intent,
                 ComponentName sourceComponent, int userId, long lastActiveTime) {
             this.id = id;
@@ -125,7 +142,8 @@
     /**
      * The temporary sort index in the stack, used when ordering the stack.
      */
-    public int temporarySortIndexInStack;
+    @Deprecated
+    int temporarySortIndexInStack;
 
     /**
      * The icon is the task description icon (if provided), which falls back to the activity icon,
@@ -134,6 +152,7 @@
     public Drawable icon;
     public ThumbnailData thumbnail;
     @ViewDebug.ExportedProperty(category="recents")
+    @Deprecated
     public String title;
     @ViewDebug.ExportedProperty(category="recents")
     public String titleDescription;
@@ -142,6 +161,7 @@
     @ViewDebug.ExportedProperty(category="recents")
     public int colorBackground;
     @ViewDebug.ExportedProperty(category="recents")
+    @Deprecated
     public boolean useLightOnPrimaryColor;
 
     /**
@@ -153,10 +173,13 @@
      * The state isLaunchTarget will be set for the correct task upon launching Recents.
      */
     @ViewDebug.ExportedProperty(category="recents")
+    @Deprecated
     public boolean isLaunchTarget;
     @ViewDebug.ExportedProperty(category="recents")
+    @Deprecated
     public boolean isStackTask;
     @ViewDebug.ExportedProperty(category="recents")
+    @Deprecated
     public boolean isSystemApp;
     @ViewDebug.ExportedProperty(category="recents")
     public boolean isDockable;
@@ -165,6 +188,7 @@
      * Resize mode. See {@link ActivityInfo#resizeMode}.
      */
     @ViewDebug.ExportedProperty(category="recents")
+    @Deprecated
     public int resizeMode;
 
     @ViewDebug.ExportedProperty(category="recents")
@@ -173,12 +197,31 @@
     @ViewDebug.ExportedProperty(category="recents")
     public boolean isLocked;
 
+    @Deprecated
     private ArrayList<TaskCallbacks> mCallbacks = new ArrayList<>();
 
     public Task() {
         // Do nothing
     }
 
+    public Task(TaskKey key) {
+        this.key = key;
+        this.taskDescription = new TaskDescription();
+    }
+
+    public Task(TaskKey key, int colorPrimary, int colorBackground,
+            boolean isDockable, boolean isLocked, TaskDescription taskDescription,
+            ComponentName topActivity) {
+        this.key = key;
+        this.colorPrimary = colorPrimary;
+        this.colorBackground = colorBackground;
+        this.taskDescription = taskDescription;
+        this.isDockable = isDockable;
+        this.isLocked = isLocked;
+        this.topActivity = topActivity;
+    }
+
+    @Deprecated
     public Task(TaskKey key, Drawable icon, ThumbnailData thumbnail, String title,
             String titleDescription, int colorPrimary, int colorBackground, boolean isLaunchTarget,
             boolean isStackTask, boolean isSystemApp, boolean isDockable,
@@ -206,6 +249,7 @@
     /**
      * Copies the metadata from another task, but retains the current callbacks.
      */
+    @Deprecated
     public void copyFrom(Task o) {
         this.key = o.key;
         this.icon = o.icon;
@@ -228,6 +272,7 @@
     /**
      * Add a callback.
      */
+    @Deprecated
     public void addCallback(TaskCallbacks cb) {
         if (!mCallbacks.contains(cb)) {
             mCallbacks.add(cb);
@@ -237,11 +282,13 @@
     /**
      * Remove a callback.
      */
+    @Deprecated
     public void removeCallback(TaskCallbacks cb) {
         mCallbacks.remove(cb);
     }
 
     /** Updates the task's windowing mode. */
+    @Deprecated
     public void setWindowingMode(int windowingMode) {
         key.setWindowingMode(windowingMode);
         int callbackCount = mCallbacks.size();
@@ -251,6 +298,7 @@
     }
 
     /** Notifies the callback listeners that this task has been loaded */
+    @Deprecated
     public void notifyTaskDataLoaded(ThumbnailData thumbnailData, Drawable applicationIcon) {
         this.icon = applicationIcon;
         this.thumbnail = thumbnailData;
@@ -261,6 +309,7 @@
     }
 
     /** Notifies the callback listeners that this task has been unloaded */
+    @Deprecated
     public void notifyTaskDataUnloaded(Drawable defaultApplicationIcon) {
         icon = defaultApplicationIcon;
         thumbnail = null;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java
index 5f3dcd1..d378189 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskFilter.java
@@ -21,6 +21,7 @@
 /**
  * An interface for a task filter to query whether a particular task should show in a stack.
  */
+@Deprecated
 public interface TaskFilter {
     /** Returns whether the filter accepts the specified task */
     boolean acceptTask(SparseArray<Task> taskIdMap, Task t, int index);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
index 23582d4..342cb75 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskKeyCache.java
@@ -34,7 +34,7 @@
      * Gets a specific entry in the cache with the specified key, regardless of whether the cached
      * value is valid or not.
      */
-    final synchronized V get(TaskKey key) {
+    public final synchronized V get(TaskKey key) {
         return getCacheEntry(key.id);
     }
 
@@ -42,7 +42,7 @@
      * Returns the value only if the key is valid (has not been updated since the last time it was
      * in the cache)
      */
-    final synchronized V getAndInvalidateIfModified(TaskKey key) {
+    public final synchronized V getAndInvalidateIfModified(TaskKey key) {
         TaskKey lastKey = mKeys.get(key.id);
         if (lastKey != null) {
             if ((lastKey.windowingMode != key.windowingMode) ||
@@ -59,7 +59,7 @@
     }
 
     /** Puts an entry in the cache for a specific key. */
-    final synchronized void put(TaskKey key, V value) {
+    public final synchronized void put(TaskKey key, V value) {
         if (key == null || value == null) {
             Log.e(TAG, "Unexpected null key or value: " + key + ", " + value);
             return;
@@ -70,14 +70,14 @@
 
 
     /** Removes a cache entry for a specific key. */
-    final synchronized void remove(TaskKey key) {
+    public final synchronized void remove(TaskKey key) {
         // Remove the key after the cache value because we need it to make the callback
         removeCacheEntry(key.id);
         mKeys.remove(key.id);
     }
 
     /** Removes all the entries in the cache. */
-    final synchronized void evictAll() {
+    public final synchronized void evictAll() {
         evictAllCache();
         mKeys.clear();
     }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java
index fbb6ace..6b9b9f5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskResourceLoadQueue.java
@@ -21,6 +21,7 @@
 /**
  * A Task load queue
  */
+@Deprecated
 class TaskResourceLoadQueue {
 
     private final ConcurrentLinkedQueue<Task> mQueue = new ConcurrentLinkedQueue<>();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java
index c731ac9..fd92bca 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/TaskStack.java
@@ -33,6 +33,7 @@
 /**
  * The task stack contains a list of multiple tasks.
  */
+@Deprecated
 public class TaskStack {
 
     private static final String TAG = "TaskStack";
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java
index 2de7f74..26f6b59 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/utilities/AnimationProps.java
@@ -34,6 +34,7 @@
  * The generic set of animation properties to animate a {@link View}. The animation can have
  * different interpolators, start delays and durations for each of the different properties.
  */
+@Deprecated
 public class AnimationProps {
 
     private static final Interpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java
index 45728c4..30bea32 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/view/AnimateableViewBounds.java
@@ -27,6 +27,7 @@
 /**
  * An outline provider that has a clip and outline that can be animated.
  */
+@Deprecated
 public class AnimateableViewBounds extends ViewOutlineProvider {
 
     private static final float MIN_ALPHA = 0.1f;
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/KeyguardManagerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/KeyguardManagerCompat.java
new file mode 100644
index 0000000..c42e7e3
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/KeyguardManagerCompat.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.shared.system;
+
+import android.app.KeyguardManager;
+import android.content.Context;
+
+public class KeyguardManagerCompat {
+    private final KeyguardManager mKeyguardManager;
+
+    public KeyguardManagerCompat(Context context) {
+        mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
+    }
+
+    public boolean isDeviceLocked(int userId) {
+        return mKeyguardManager.isDeviceLocked(userId);
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
index d38cc0f..69aea2c 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
@@ -24,8 +24,6 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-import sun.misc.Resource;
-
 public class NavigationBarCompat {
     /**
      * Touch slopes and thresholds for quick step operations. Drag slop is the point where the
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java
new file mode 100644
index 0000000..a529903
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.shared.system;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+
+public class RecentTaskInfoCompat {
+
+    private ActivityManager.RecentTaskInfo mInfo;
+
+    public RecentTaskInfoCompat(ActivityManager.RecentTaskInfo info) {
+        mInfo = info;
+    }
+
+    public int getUserId() {
+        return mInfo.userId;
+    }
+
+    public boolean supportsSplitScreenMultiWindow() {
+        return mInfo.supportsSplitScreenMultiWindow;
+    }
+
+    public ComponentName getTopActivity() {
+        return mInfo.topActivity;
+    }
+
+    public ActivityManager.TaskDescription getTaskDescription() {
+        return mInfo.taskDescription;
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RotationWatcher.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RotationWatcher.java
index 5a28a5e..7c8c23e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RotationWatcher.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RotationWatcher.java
@@ -48,7 +48,7 @@
         if (!mIsWatching) {
             try {
                 WindowManagerGlobal.getWindowManagerService().watchRotation(mWatcher,
-                        mContext.getDisplay().getDisplayId());
+                        mContext.getDisplayId());
                 mIsWatching = true;
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to set rotation watcher", e);
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java
new file mode 100644
index 0000000..eaf8d9b
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskDescriptionCompat.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.shared.system;
+
+import android.app.ActivityManager;
+
+public class TaskDescriptionCompat {
+
+    private ActivityManager.TaskDescription mTaskDescription;
+
+    public TaskDescriptionCompat(ActivityManager.TaskDescription td) {
+        mTaskDescription = td;
+    }
+
+    public int getPrimaryColor() {
+        return mTaskDescription != null
+                ? mTaskDescription.getPrimaryColor()
+                : 0;
+    }
+
+    public int getBackgroundColor() {
+        return mTaskDescription != null
+                ? mTaskDescription.getBackgroundColor()
+                : 0;
+    }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java
index b2b140e..de2a3e4 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/WindowCallbacksCompat.java
@@ -17,7 +17,7 @@
 
 import android.graphics.Canvas;
 import android.graphics.Rect;
-import android.view.DisplayListCanvas;
+import android.graphics.RecordingCanvas;
 import android.view.View;
 import android.view.ViewRootImpl;
 import android.view.WindowCallbacks;
@@ -55,7 +55,7 @@
         }
 
         @Override
-        public void onPostDraw(DisplayListCanvas canvas) {
+        public void onPostDraw(RecordingCanvas canvas) {
             WindowCallbacksCompat.this.onPostDraw(canvas);
         }
     };
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
index 265a961..34df15f 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardHostView.java
@@ -29,13 +29,13 @@
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.KeyEvent;
-import android.view.accessibility.AccessibilityEvent;
 import android.widget.FrameLayout;
 
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
 import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 import com.android.settingslib.Utils;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 
 import java.io.File;
 
@@ -50,13 +50,6 @@
  */
 public class KeyguardHostView extends FrameLayout implements SecurityCallback {
 
-    public interface OnDismissAction {
-        /**
-         * @return true if the dismiss should be deferred
-         */
-        boolean onDismiss();
-    }
-
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager = null;
     protected ViewMediatorCallback mViewMediatorCallback;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index a3862eb..a543d17 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -102,7 +102,8 @@
                         findViewById(R.id.key9)
                 },
                 new View[]{
-                        null, findViewById(R.id.key0), findViewById(R.id.key_enter)
+                        findViewById(R.id.delete_button), findViewById(R.id.key0),
+                        findViewById(R.id.key_enter)
                 },
                 new View[]{
                         null, mEcaView, null
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 2daa33b..112e067 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -373,11 +373,11 @@
             mPendingLockCheck.cancel(false);
             mPendingLockCheck = null;
         }
+        displayDefaultSecurityMessage();
     }
 
     @Override
     public void onResume(int reason) {
-        displayDefaultSecurityMessage();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 6d1313c..db78667 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -28,7 +28,6 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import androidx.core.graphics.ColorUtils;
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.util.ArraySet;
@@ -41,6 +40,8 @@
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import androidx.core.graphics.ColorUtils;
+
 import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.ViewClippingUtil;
 import com.android.systemui.Dependency;
@@ -64,7 +65,6 @@
 
     private TextView mLogoutView;
     private KeyguardClockSwitch mClockView;
-    private View mClockSeparator;
     private TextView mOwnerInfo;
     private KeyguardSliceView mKeyguardSlice;
     private Runnable mPendingMarqueeStart;
@@ -75,8 +75,8 @@
     private boolean mWasPulsing;
     private float mDarkAmount = 0;
     private int mTextColor;
-    private float mWidgetPadding;
     private int mLastLayoutHeight;
+    private int mSmallClockPadding;
 
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
@@ -175,14 +175,12 @@
         }
         mOwnerInfo = findViewById(R.id.owner_info);
         mKeyguardSlice = findViewById(R.id.keyguard_status_area);
-        mClockSeparator = findViewById(R.id.clock_separator);
         mVisibleInDoze = Sets.newArraySet(mClockView, mKeyguardSlice);
         mTextColor = mClockView.getCurrentTextColor();
 
         int clockStroke = getResources().getDimensionPixelSize(R.dimen.widget_small_font_stroke);
         mClockView.getPaint().setStrokeWidth(clockStroke);
         mClockView.addOnLayoutChangeListener(this);
-        mClockSeparator.addOnLayoutChangeListener(this);
         mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged);
         onSliceContentChanged();
 
@@ -199,26 +197,18 @@
     }
 
     /**
-     * Moves clock and separator, adjusting margins when slice content changes.
+     * Moves clock, adjusting margins when slice content changes.
      */
     private void onSliceContentChanged() {
         boolean smallClock = mKeyguardSlice.hasHeader() || mPulsing;
-        float clockScale = smallClock ? mSmallClockScale : 1;
-
         RelativeLayout.LayoutParams layoutParams =
                 (RelativeLayout.LayoutParams) mClockView.getLayoutParams();
-        int height = mClockView.getHeight();
-        layoutParams.bottomMargin = (int) -(height - (clockScale * height));
+        layoutParams.bottomMargin = smallClock ? mSmallClockPadding : 0;
         mClockView.setLayoutParams(layoutParams);
-
-        layoutParams = (RelativeLayout.LayoutParams) mClockSeparator.getLayoutParams();
-        layoutParams.topMargin = smallClock ? (int) mWidgetPadding : 0;
-        layoutParams.bottomMargin = layoutParams.topMargin;
-        mClockSeparator.setLayoutParams(layoutParams);
     }
 
     /**
-     * Animate clock and its separator when necessary.
+     * Animate clock when necessary.
      */
     @Override
     public void onLayoutChange(View view, int left, int top, int right, int bottom,
@@ -258,25 +248,6 @@
                 mClockView.setStyle(style);
                 mClockView.invalidate();
             }
-        } else if (view == mClockSeparator) {
-            boolean hasSeparator = hasHeader && !mPulsing;
-            float alpha = hasSeparator ? 1 : 0;
-            mClockSeparator.animate().cancel();
-            if (shouldAnimate) {
-                boolean isAwake = mDarkAmount != 0;
-                mClockSeparator.setY(oldTop + heightOffset);
-                mClockSeparator.animate()
-                        .setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
-                        .setDuration(duration)
-                        .setListener(isAwake ? null : new KeepAwakeAnimationListener(getContext()))
-                        .setStartDelay(delay)
-                        .y(top)
-                        .alpha(alpha)
-                        .start();
-            } else {
-                mClockSeparator.setY(top);
-                mClockSeparator.setAlpha(alpha);
-            }
         }
     }
 
@@ -291,7 +262,8 @@
 
     @Override
     public void onDensityOrFontScaleChanged() {
-        mWidgetPadding = getResources().getDimension(R.dimen.widget_vertical_padding);
+        mSmallClockPadding = getResources()
+                .getDimensionPixelSize(R.dimen.widget_small_clock_padding);
         if (mClockView != null) {
             mClockView.setTextSize(TypedValue.COMPLEX_UNIT_PX,
                     getResources().getDimensionPixelSize(R.dimen.widget_big_font_size));
@@ -352,6 +324,7 @@
             }
         }
         mOwnerInfo.setText(info);
+        updateDark();
     }
 
     @Override
@@ -434,7 +407,6 @@
         updateDozeVisibleViews();
         mKeyguardSlice.setDarkAmount(mDarkAmount);
         mClockView.setTextColor(blendedTextColor);
-        mClockSeparator.setBackgroundColor(blendedTextColor);
     }
 
     private void layoutOwnerInfo() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index f1b53fe..c7685f8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -41,7 +41,6 @@
 import android.app.trust.TrustManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -49,13 +48,14 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.database.ContentObserver;
+import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricSourceType;
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
 import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
 import android.media.AudioManager;
-import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.CancellationSignal;
 import android.os.Handler;
@@ -250,51 +250,6 @@
     private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
     private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
 
-    private class SettingObserver extends ContentObserver {
-        private final Uri FACE_UNLOCK_KEYGUARD_ENABLED =
-                Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED);
-
-        private final ContentResolver mContentResolver;
-
-        /**
-         * Creates a content observer.
-         *
-         * @param handler The handler to run {@link #onChange} on, or null if none.
-         */
-        public SettingObserver(Handler handler) {
-            super(handler);
-            mContentResolver = mContext.getContentResolver();
-            updateContentObserver();
-        }
-
-        public void updateContentObserver() {
-            mContentResolver.unregisterContentObserver(this);
-            mContentResolver.registerContentObserver(FACE_UNLOCK_KEYGUARD_ENABLED,
-                    false /* notifyForDescendents */,
-                    this,
-                    UserHandle.USER_CURRENT);
-
-            // Update the value immediately
-            onChange(true /* selfChange */, FACE_UNLOCK_KEYGUARD_ENABLED);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            if (FACE_UNLOCK_KEYGUARD_ENABLED.equals(uri)) {
-                    mFaceSettingEnabledForUser =
-                            Settings.Secure.getIntForUser(
-                                    mContentResolver,
-                                    Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED,
-                                    1 /* default */,
-                                    UserHandle.USER_CURRENT) != 0;
-                    updateBiometricListeningState();
-            }
-        }
-    }
-
-    private final SettingObserver mSettingObserver;
-    private boolean mFaceSettingEnabledForUser;
-
     private final Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
@@ -400,6 +355,18 @@
         }
     };
 
+    private boolean mFaceSettingEnabledForUser;
+    private BiometricManager mBiometricManager;
+    private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
+            new IBiometricEnabledOnKeyguardCallback.Stub() {
+        @Override
+        public void onChanged(BiometricSourceType type, boolean enabled) throws RemoteException {
+            if (type == BiometricSourceType.FACE) {
+                mFaceSettingEnabledForUser = enabled;
+            }
+        }
+    };
+
     private OnSubscriptionsChangedListener mSubscriptionListener =
             new OnSubscriptionsChangedListener() {
         @Override
@@ -1165,7 +1132,7 @@
     private CancellationSignal mFingerprintCancelSignal;
     private CancellationSignal mFaceCancelSignal;
     private FingerprintManager mFpm;
-    private FaceManager mFaceAuthenticationManager;
+    private FaceManager mFaceManager;
 
     /**
      * When we receive a
@@ -1434,7 +1401,6 @@
         mSubscriptionManager = SubscriptionManager.from(context);
         mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
         mStrongAuthTracker = new StrongAuthTracker(context);
-        mSettingObserver = new SettingObserver(mHandler);
 
         // Since device can't be un-provisioned, we only need to register a content observer
         // to update mDeviceProvisioned when we are...
@@ -1504,17 +1470,21 @@
         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
             mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
         }
-
         if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
-            mFaceAuthenticationManager =
-                    (FaceManager) context.getSystemService(Context.FACE_SERVICE);
+            mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
         }
+
+        if (mFpm != null || mFaceManager != null) {
+            mBiometricManager = context.getSystemService(BiometricManager.class);
+            mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
+        }
+
         updateBiometricListeningState();
         if (mFpm != null) {
             mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
         }
-        if (mFaceAuthenticationManager != null) {
-            mFaceAuthenticationManager.addLockoutResetCallback(mFaceLockoutResetCallback);
+        if (mFaceManager != null) {
+            mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
         }
 
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
@@ -1629,7 +1599,7 @@
                 mFaceCancelSignal.cancel();
             }
             mFaceCancelSignal = new CancellationSignal();
-            mFaceAuthenticationManager.authenticate(null, mFaceCancelSignal, 0,
+            mFaceManager.authenticate(null, mFaceCancelSignal, 0,
                     mFaceAuthenticationCallback, null);
             setFaceRunningState(BIOMETRIC_STATE_RUNNING);
         }
@@ -1641,9 +1611,9 @@
     }
 
     public boolean isUnlockWithFacePossible(int userId) {
-        return mFaceAuthenticationManager != null && mFaceAuthenticationManager.isHardwareDetected()
+        return mFaceManager != null && mFaceManager.isHardwareDetected()
                 && !isFaceDisabled(userId)
-                && mFaceAuthenticationManager.hasEnrolledTemplates(userId);
+                && mFaceManager.hasEnrolledTemplates(userId);
     }
 
     private void stopListeningForFingerprint() {
@@ -1765,7 +1735,6 @@
      * Handle {@link #MSG_USER_SWITCH_COMPLETE}
      */
     private void handleUserSwitchComplete(int userId) {
-        mSettingObserver.updateContentObserver();
         for (int i = 0; i < mCallbacks.size(); i++) {
             KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
             if (cb != null) {
@@ -2437,7 +2406,7 @@
             pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
             pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
         }
-        if (mFaceAuthenticationManager != null && mFaceAuthenticationManager.isHardwareDetected()) {
+        if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
             final int userId = ActivityManager.getCurrentUser();
             final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
             pw.println("  Face authentication state (user=" + userId + ")");
@@ -2449,6 +2418,7 @@
             pw.println("    possible=" + isUnlockWithFacePossible(userId));
             pw.println("    strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
             pw.println("    trustManaged=" + getUserTrustIsManaged(userId));
+            pw.println("    enabledByUser=" + mFaceSettingEnabledForUser);
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
index 45f1686..08691ec 100644
--- a/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
+++ b/packages/SystemUI/src/com/android/keyguard/NumPadKey.java
@@ -54,7 +54,7 @@
             if (mTextView != null && mTextView.isEnabled()) {
                 mTextView.append(Character.forDigit(mDigit, 10));
             }
-            userActivity();;
+            userActivity();
         }
     };
 
@@ -118,7 +118,7 @@
 
         a = context.obtainStyledAttributes(attrs, android.R.styleable.View);
         if (!a.hasValueOrEmpty(android.R.styleable.View_background)) {
-            setBackground(mContext.getDrawable(R.drawable.ripple_drawable));
+            setBackground(mContext.getDrawable(R.drawable.ripple_drawable_pin));
         }
         a.recycle();
         setContentDescription(mDigitText.getText().toString());
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
index e58538d..e1b8dc8 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
@@ -29,46 +29,69 @@
 
     @Override
     public void startPendingIntentDismissingKeyguard(PendingIntent intent) {
-        if (mActualStarter == null) return;
+        if (mActualStarter == null) {
+            return;
+        }
         mActualStarter.startPendingIntentDismissingKeyguard(intent);
     }
 
     @Override
     public void startActivity(Intent intent, boolean dismissShade) {
-        if (mActualStarter == null) return;
+        if (mActualStarter == null) {
+            return;
+        }
         mActualStarter.startActivity(intent, dismissShade);
     }
 
     @Override
     public void startActivity(Intent intent, boolean onlyProvisioned, boolean dismissShade) {
-        if (mActualStarter == null) return;
+        if (mActualStarter == null) {
+            return;
+        }
         mActualStarter.startActivity(intent, onlyProvisioned, dismissShade);
     }
 
     @Override
     public void startActivity(Intent intent, boolean dismissShade, Callback callback) {
-        if (mActualStarter == null) return;
+        if (mActualStarter == null) {
+            return;
+        }
         mActualStarter.startActivity(intent, dismissShade, callback);
     }
 
     @Override
     public void postStartActivityDismissingKeyguard(Intent intent, int delay) {
-        if (mActualStarter == null) return;
+        if (mActualStarter == null) {
+            return;
+        }
         mActualStarter.postStartActivityDismissingKeyguard(intent, delay);
     }
 
     @Override
     public void postStartActivityDismissingKeyguard(PendingIntent intent) {
-        if (mActualStarter == null) return;
+        if (mActualStarter == null) {
+            return;
+        }
         mActualStarter.postStartActivityDismissingKeyguard(intent);
     }
 
     @Override
     public void postQSRunnableDismissingKeyguard(Runnable runnable) {
-        if (mActualStarter == null) return;
+        if (mActualStarter == null) {
+            return;
+        }
         mActualStarter.postQSRunnableDismissingKeyguard(runnable);
     }
 
+    @Override
+    public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancel,
+            boolean afterKeyguardGone) {
+        if (mActualStarter == null) {
+            return;
+        }
+        mActualStarter.dismissKeyguardThenExecute(action, cancel, afterKeyguardGone);
+    }
+
     public void setActivityStarterImpl(ActivityStarter starter) {
         mActualStarter = starter;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index fe1fe1a..494880e 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -48,16 +48,22 @@
 import com.android.systemui.power.EnhancedEstimatesImpl;
 import com.android.systemui.power.PowerNotificationWarnings;
 import com.android.systemui.power.PowerUI;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.notification.AppOpsListener;
 import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment;
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
 import com.android.systemui.statusbar.phone.LightBarController;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.ManagedProfileController;
 import com.android.systemui.statusbar.phone.ManagedProfileControllerImpl;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl;
+import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.AccessibilityController;
 import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
@@ -178,7 +184,8 @@
                 getDependency(ActivityStarter.class));
 
         mProviders.put(AsyncSensorManager.class, () ->
-                new AsyncSensorManager(mContext.getSystemService(SensorManager.class)));
+                new AsyncSensorManager(mContext.getSystemService(SensorManager.class),
+                        getDependency(PluginManager.class)));
 
         mProviders.put(BluetoothController.class, () ->
                 new BluetoothControllerImpl(mContext, getDependency(BG_LOOPER)));
@@ -342,6 +349,14 @@
 
         mProviders.put(LockscreenGestureLogger.class, () -> new LockscreenGestureLogger());
 
+        mProviders.put(KeyguardEnvironment.class, () -> new KeyguardEnvironmentImpl());
+        mProviders.put(ShadeController.class, () ->
+                SysUiServiceProvider.getComponent(mContext, StatusBar.class));
+        mProviders.put(NotificationRemoteInputManager.Callback.class,
+                () -> new StatusBarRemoteInputCallback(mContext));
+
+        mProviders.put(InitController.class, InitController::new);
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
 
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
index 198a4e6..b1463a3 100644
--- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -143,9 +143,6 @@
                 mSeparatedView.setBackground(mSeparatedViewBackground);
                 updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
                 mOldHeight = mList.getMeasuredHeight();
-                mList.addOnLayoutChangeListener(
-                        (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
-                                updatePosition());
                 updateRotation();
             } else {
                 return;
@@ -155,6 +152,8 @@
         if (newHeight != mOldHeight) {
             animateChild(mOldHeight, newHeight);
         }
+
+        post(() -> updatePaddingAndGravityIfTooTall());
         post(() -> updatePosition());
     }
 
@@ -241,7 +240,7 @@
         separatedViewLayoutParams.gravity = rotateGravityRight(separatedViewLayoutParams.gravity);
         mSeparatedView.setLayoutParams(separatedViewLayoutParams);
 
-        setGravity(p.gravity);
+        setGravity(rotateGravityRight(getGravity()));
     }
 
     private void swapDimens(View v) {
@@ -299,7 +298,7 @@
         separatedViewLayoutParams.gravity = rotateGravityLeft(separatedViewLayoutParams.gravity);
         mSeparatedView.setLayoutParams(separatedViewLayoutParams);
 
-        setGravity(p.gravity);
+        setGravity(rotateGravityLeft(getGravity()));
     }
 
     private int rotateGravityLeft(int gravity) {
@@ -447,6 +446,46 @@
         mAnimator.start();
     }
 
+    // If current power menu height larger then screen height, remove padding to break power menu
+    // alignment and set menu center vertical within the screen.
+    private void updatePaddingAndGravityIfTooTall() {
+        int defaultTopPadding;
+        int viewsTotalHeight;
+        int separatedViewTopMargin;
+        int screenHeight;
+        int totalHeight;
+        int targetGravity;
+        MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams();
+        switch (RotationUtils.getRotation(getContext())) {
+            case RotationUtils.ROTATION_LANDSCAPE:
+                defaultTopPadding = getPaddingLeft();
+                viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
+                separatedViewTopMargin = mHasSeparatedButton ? params.leftMargin : 0;
+                screenHeight = getMeasuredWidth();
+                targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP;
+                break;
+            case RotationUtils.ROTATION_SEASCAPE:
+                defaultTopPadding = getPaddingRight();
+                viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
+                separatedViewTopMargin = mHasSeparatedButton ? params.leftMargin : 0;
+                screenHeight = getMeasuredWidth();
+                targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;
+                break;
+            default: // Portrait
+                defaultTopPadding = getPaddingTop();
+                viewsTotalHeight = mList.getMeasuredHeight() + mSeparatedView.getMeasuredHeight();
+                separatedViewTopMargin = mHasSeparatedButton ? params.topMargin : 0;
+                screenHeight = getMeasuredHeight();
+                targetGravity = Gravity.CENTER_VERTICAL|Gravity.RIGHT;
+                break;
+        }
+        totalHeight = defaultTopPadding + viewsTotalHeight + separatedViewTopMargin;
+        if (totalHeight >= screenHeight) {
+            setPadding(0, 0, 0, 0);
+            setGravity(targetGravity);
+        }
+    }
+
     @Override
     public ViewOutlineProvider getOutlineProvider() {
         return super.getOutlineProvider();
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 77f4bf5..d8eb965 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -30,7 +30,7 @@
 import android.util.Log;
 import android.view.Display;
 import android.view.DisplayInfo;
-import android.view.DisplayListCanvas;
+import android.graphics.RecordingCanvas;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.WindowManager;
@@ -381,7 +381,7 @@
                     try {
                         Bitmap wallpaper = mWallpaperManager.getBitmap(true /* hardware */);
                         if (wallpaper != null
-                                && wallpaper.getByteCount() > DisplayListCanvas.MAX_BITMAP_SIZE) {
+                                && wallpaper.getByteCount() > RecordingCanvas.MAX_BITMAP_SIZE) {
                             throw new RuntimeException("Wallpaper is too large to draw!");
                         }
                         return wallpaper;
diff --git a/packages/SystemUI/src/com/android/systemui/InitController.java b/packages/SystemUI/src/com/android/systemui/InitController.java
new file mode 100644
index 0000000..52ba66a
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/InitController.java
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+
+/**
+ * Created by {@link Dependency} on SystemUI startup. Add tasks which need to be executed only
+ * after all other dependencies have been created.
+ */
+public class InitController {
+
+    private final ArrayList<Runnable> mTasks = new ArrayList<>();
+
+    /**
+     * Add a task to be executed after {@link Dependency#start()}
+     * @param runnable the task to be executed
+     */
+    public void addPostInitTask(Runnable runnable) {
+        mTasks.add(runnable);
+    }
+
+    /**
+     * Run post-init tasks and remove them from the tasks list
+     */
+    public void executePostInitTasks() {
+        while (!mTasks.isEmpty()) {
+            mTasks.remove(0).run();
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index 1af2156..1bf8750 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -17,6 +17,10 @@
 package com.android.systemui;
 
 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
+import static android.view.MotionEvent.ACTION_CANCEL;
+
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
 import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
 import static com.android.systemui.shared.system.NavigationBarCompat.InteractionType;
@@ -86,6 +90,7 @@
     private boolean mIsEnabled;
     private int mCurrentBoundedUserId = -1;
     private float mBackButtonAlpha;
+    private MotionEvent mStatusBarGestureDownEvent;
 
     private ISystemUiProxy mSysUiProxy = new ISystemUiProxy.Stub() {
 
@@ -108,6 +113,9 @@
         }
 
         public void onStatusBarMotionEvent(MotionEvent event) {
+            if (!verifyCaller("onStatusBarMotionEvent")) {
+                return;
+            }
             long token = Binder.clearCallingIdentity();
             try {
                 // TODO move this logic to message queue
@@ -115,6 +123,16 @@
                     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);
+                        }
+                        if (action == ACTION_UP || action == ACTION_CANCEL) {
+                            mStatusBarGestureDownEvent.recycle();
+                            mStatusBarGestureDownEvent = null;
+                        }
+                        event.recycle();
                     }
                 });
             } finally {
@@ -241,6 +259,7 @@
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             mHandler.removeCallbacks(mDeferredConnectionCallback);
+            mCurrentBoundedUserId = mDeviceProvisionedController.getCurrentUser();
             mConnectionBackoffAttempts = 0;
             mOverviewProxy = IOverviewProxy.Stub.asInterface(service);
             // Listen for launcher's death
@@ -251,7 +270,6 @@
             }
             try {
                 mOverviewProxy.onBind(mSysUiProxy);
-                mCurrentBoundedUserId = mDeviceProvisionedController.getCurrentUser();
             } catch (RemoteException e) {
                 mCurrentBoundedUserId = -1;
                 Log.e(TAG_OPS, "Failed to call onBind()", e);
@@ -298,7 +316,7 @@
 
     // This is the death handler for the binder from the launcher service
     private final IBinder.DeathRecipient mOverviewServiceDeathRcpt
-            = this::startConnectionToCurrentUser;
+            = this::cleanupAfterDeath;
 
     public OverviewProxyService(Context context) {
         mContext = context;
@@ -328,6 +346,22 @@
         return mBackButtonAlpha;
     }
 
+    public void cleanupAfterDeath() {
+        if (mStatusBarGestureDownEvent != null) {
+            mHandler.post(()-> {
+                StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
+                if (bar != null) {
+                    System.out.println("MERONG dispatchNotificationPanelTouchEvent");
+                    mStatusBarGestureDownEvent.setAction(MotionEvent.ACTION_CANCEL);
+                    bar.dispatchNotificationsPanelTouchEvent(mStatusBarGestureDownEvent);
+                    mStatusBarGestureDownEvent.recycle();
+                    mStatusBarGestureDownEvent = null;
+                }
+            });
+        }
+        startConnectionToCurrentUser();
+    }
+
     public void startConnectionToCurrentUser() {
         if (mHandler.getLooper() != Looper.myLooper()) {
             mHandler.post(mConnectionRunnable);
diff --git a/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java b/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java
index 646f69e..6dc2d67 100644
--- a/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/RegionInterceptingFrameLayout.java
@@ -76,7 +76,7 @@
                 continue;
             }
 
-            internalInsetsInfo.touchableRegion.op(riv.getInterceptRegion(), Op.UNION);
+            internalInsetsInfo.touchableRegion.op(unionRegion, Op.UNION);
         }
     };
 
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 48181bc..c844496 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -76,6 +76,9 @@
 import com.android.systemui.tuner.TunerService.Tunable;
 import com.android.systemui.util.leak.RotationUtils;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import androidx.annotation.VisibleForTesting;
 
 /**
@@ -108,6 +111,23 @@
     private boolean mPendingRotationChange;
     private Handler mHandler;
 
+    /**
+     * Converts a set of {@link Rect}s into a {@link Region}
+     *
+     * @hide
+     */
+    public static Region rectsToRegion(List<Rect> rects) {
+        Region result = Region.obtain();
+        if (rects != null) {
+            for (Rect r : rects) {
+                if (r != null && !r.isEmpty()) {
+                    result.op(r, Region.Op.UNION);
+                }
+            }
+        }
+        return result;
+    }
+
     @Override
     public void start() {
         mHandler = startHandlerThread();
@@ -187,11 +207,11 @@
 
         mOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
         mOverlay.setAlpha(0);
-        mOverlay.setAllowForceDark(false);
+        mOverlay.setForceDarkAllowed(false);
 
         mBottomOverlay.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
         mBottomOverlay.setAlpha(0);
-        mBottomOverlay.setAllowForceDark(false);
+        mBottomOverlay.setForceDarkAllowed(false);
 
         updateViews();
 
@@ -539,7 +559,7 @@
 
         private final DisplayInfo mInfo = new DisplayInfo();
         private final Paint mPaint = new Paint();
-        private final Region mBounds = new Region();
+        private final List<Rect> mBounds = new ArrayList();
         private final Rect mBoundingRect = new Rect();
         private final Path mBoundingPath = new Path();
         private final int[] mLocation = new int[2];
@@ -629,12 +649,12 @@
             mStart = isStart();
             requestLayout();
             getDisplay().getDisplayInfo(mInfo);
-            mBounds.setEmpty();
+            mBounds.clear();
             mBoundingRect.setEmpty();
             mBoundingPath.reset();
             int newVisible;
             if (shouldDrawCutout(getContext()) && hasCutout()) {
-                mBounds.set(mInfo.displayCutout.getBounds());
+                mBounds.addAll(mInfo.displayCutout.getBoundingRects());
                 localBounds(mBoundingRect);
                 updateBoundingPath();
                 invalidate();
@@ -713,32 +733,22 @@
 
         public static void boundsFromDirection(DisplayCutout displayCutout, int gravity,
                 Rect out) {
-            Region bounds = boundsFromDirection(displayCutout, gravity);
-            out.set(bounds.getBounds());
-            bounds.recycle();
-        }
-
-        public static Region boundsFromDirection(DisplayCutout displayCutout, int gravity) {
-            Region bounds = displayCutout.getBounds();
             switch (gravity) {
                 case Gravity.TOP:
-                    bounds.op(0, 0, Integer.MAX_VALUE, displayCutout.getSafeInsetTop(),
-                            Region.Op.INTERSECT);
+                    out.set(displayCutout.getBoundingRectTop());
                     break;
                 case Gravity.LEFT:
-                    bounds.op(0, 0, displayCutout.getSafeInsetLeft(), Integer.MAX_VALUE,
-                            Region.Op.INTERSECT);
+                    out.set(displayCutout.getBoundingRectLeft());
                     break;
                 case Gravity.BOTTOM:
-                    bounds.op(0, displayCutout.getSafeInsetTop() + 1, Integer.MAX_VALUE,
-                            Integer.MAX_VALUE, Region.Op.INTERSECT);
+                    out.set(displayCutout.getBoundingRectBottom());
                     break;
                 case Gravity.RIGHT:
-                    bounds.op(displayCutout.getSafeInsetLeft() + 1, 0, Integer.MAX_VALUE,
-                            Integer.MAX_VALUE, Region.Op.INTERSECT);
+                    out.set(displayCutout.getBoundingRectRight());
                     break;
+                default:
+                    out.setEmpty();
             }
-            return bounds;
         }
 
         private void localBounds(Rect out) {
@@ -771,7 +781,8 @@
             }
 
             View rootView = getRootView();
-            Region cutoutBounds = mInfo.displayCutout.getBounds();
+            Region cutoutBounds = rectsToRegion(
+                    mInfo.displayCutout.getBoundingRects());
 
             // Transform to window's coordinate space
             rootView.getLocationOnScreen(mLocation);
diff --git a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
index 6d79066..449ed8c 100644
--- a/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/SlicePermissionActivity.java
@@ -14,7 +14,7 @@
 
 package com.android.systemui;
 
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -69,7 +69,7 @@
                     .setPositiveButton(R.string.slice_permission_allow, this)
                     .setOnDismissListener(this)
                     .create();
-            dialog.getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+            dialog.getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
             dialog.show();
             TextView t1 = dialog.getWindow().getDecorView().findViewById(R.id.text1);
             t1.setText(getString(R.string.slice_permission_text_1, app2));
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 0215fda..3fe9944 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -87,6 +87,8 @@
     private Runnable mWatchLongPress;
     private final long mLongPressTimeout;
 
+    protected boolean mSwipingInProgress;
+
     final private int[] mTmpPos = new int[2];
     private final int mFalsingThreshold;
     private boolean mTouchAboveFalsingThreshold;
@@ -127,6 +129,10 @@
         mDisableHwLayers = disableHwLayers;
     }
 
+    public boolean isSwipingInProgress() {
+        return mSwipingInProgress;
+    }
+
     private float getPos(MotionEvent ev) {
         return mSwipeDirection == X ? ev.getX() : ev.getY();
     }
@@ -318,6 +324,7 @@
                     if (Math.abs(delta) > mPagingTouchSlop
                             && Math.abs(delta) > Math.abs(deltaPerpendicular)) {
                         if (mCallback.canChildBeDragged(mCurrView)) {
+                            mSwipingInProgress = true;
                             mCallback.onBeginDrag(mCurrView);
                             mDragging = true;
                             mInitialTouchPos = getPos(ev);
@@ -437,6 +444,7 @@
                     wasRemoved = row.isRemoved();
                 }
                 if (!mCancelled || wasRemoved) {
+                    mSwipingInProgress = false;
                     mCallback.onChildDismissed(animView);
                 }
                 if (endAction != null) {
@@ -626,6 +634,7 @@
                                 !swipedFastEnough() /* useAccelerateInterpolator */);
                     } else {
                         // snappity
+                        mSwipingInProgress = false;
                         mCallback.onDragCancelled(mCurrView);
                         snapChild(mCurrView, 0 /* leftTarget */, velocity);
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 78053b2..92aa652 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -194,6 +194,7 @@
                 mServices[i].onBootCompleted();
             }
         }
+        Dependency.get(InitController.class).executePostInitTasks();
         log.traceEnd();
         Dependency.get(PluginManager.class).addPluginListener(
                 new PluginListener<OverlayPlugin>() {
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 258b6f6..c4bf27b 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -32,6 +32,7 @@
 import com.android.systemui.qs.QSTileHost;
 import com.android.systemui.statusbar.AmbientPulseManager;
 import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
 import com.android.systemui.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -133,7 +134,7 @@
             Context context) {
         providers.put(StatusBarStateController.class, StatusBarStateController::new);
         providers.put(NotificationLockscreenUserManager.class,
-                () -> new NotificationLockscreenUserManager(context));
+                () -> new NotificationLockscreenUserManagerImpl(context));
         providers.put(VisualStabilityManager.class, VisualStabilityManager::new);
         providers.put(NotificationGroupManager.class, NotificationGroupManager::new);
         providers.put(NotificationMediaManager.class, () -> new NotificationMediaManager(context));
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 38a90cf..53cdee5 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -202,7 +202,8 @@
 
         // Close Recent Apps if needed
         SysUiServiceProvider.getComponent(mContext, CommandQueue.class).animateCollapsePanels(
-                CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL | CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL);
+                CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL | CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL,
+                false /* force */);
 
         boolean structureEnabled = Settings.Secure.getIntForUser(mContext.getContentResolver(),
                 Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index c90861e..7d77929 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -200,7 +200,9 @@
         mLastState = STATE_NONE;
         updateState(STATE_AUTHENTICATING);
 
-        title.setText(mBundle.getCharSequence(BiometricPrompt.KEY_TITLE));
+        CharSequence titleText = mBundle.getCharSequence(BiometricPrompt.KEY_TITLE);
+
+        title.setText(titleText);
         title.setSelected(true);
 
         positive.setVisibility(View.INVISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
index 5739c99..96af08b 100644
--- a/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -44,7 +44,7 @@
         // Because space is usually constrained in the auto use-case, there should not be a
         // pinned notification when the shade has been expanded. Ensure this by not pinning any
         // notification if the shade is already opened.
-        if (!mPresenter.isPresenterFullyCollapsed()) {
+        if (!getPresenter().isPresenterFullyCollapsed()) {
             return false;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarNotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/car/CarNotificationMediaManager.java
new file mode 100644
index 0000000..f34d6b3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/car/CarNotificationMediaManager.java
@@ -0,0 +1,30 @@
+/*
+ * 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.car;
+
+import android.content.Context;
+
+import com.android.systemui.statusbar.NotificationMediaManager;
+
+public class CarNotificationMediaManager extends NotificationMediaManager {
+    public CarNotificationMediaManager(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
+        // Do nothing, we don't want to display media art in the lock screen for a car.
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
index a015a18..e4b2e07 100644
--- a/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/car/CarSystemUIFactory.java
@@ -22,6 +22,7 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.Dependency.DependencyProvider;
 import com.android.systemui.SystemUIFactory;
+import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.car.CarFacetButtonController;
 import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
@@ -46,5 +47,7 @@
                 () -> new CarNotificationEntryManager(context));
         providers.put(CarFacetButtonController.class, () -> new CarFacetButtonController(context));
         providers.put(HvacController.class, () -> new HvacController(context));
+        providers.put(NotificationMediaManager.class,
+                () -> new CarNotificationMediaManager(context));
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
index bb05980..1e61a77 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeHost.java
@@ -47,6 +47,12 @@
 
     void onIgnoreTouchWhilePulsing(boolean ignore);
 
+    /**
+     * If the device was waken up by a passive interrupt that will show the lock screen without
+     * expanding the notification panel/shade.
+     */
+    void setPassiveInterrupt(boolean lightInterrupt);
+
     interface Callback {
         /**
          * Called when a high priority notification is added.
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 7013947..77f7ad4f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.doze;
 
+import static com.android.systemui.plugins.SensorManagerPlugin.Sensor.TYPE_WAKE_LOCK_SCREEN;
+
 import android.annotation.AnyThread;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
@@ -39,8 +41,10 @@
 import com.android.internal.hardware.AmbientDisplayConfiguration;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.systemui.plugins.SensorManagerPlugin;
 import com.android.systemui.statusbar.phone.DozeParameters;
 import com.android.systemui.util.AlarmTimeout;
+import com.android.systemui.util.AsyncSensorManager;
 import com.android.systemui.util.wakelock.WakeLock;
 
 import java.io.PrintWriter;
@@ -112,8 +116,8 @@
                         DozeLog.PULSE_REASON_SENSOR_LONG_PRESS,
                         true /* reports touch coordinates */,
                         true /* touchscreen */),
-                new TriggerSensor(
-                        findSensorWithType(config.wakeLockScreenSensorType()),
+                new PluginTriggerSensor(
+                        new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
                         Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
                         true /* configured */,
                         DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
@@ -375,7 +379,7 @@
             mHandler.post(mWakeLock.wrap(() -> {
                 if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
                 boolean sensorPerformsProxCheck = false;
-                if (mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
+                if (mSensor != null && mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
                     int subType = (int) event.values[0];
                     MetricsLogger.action(
                             mContext, MetricsProto.MetricsEvent.ACTION_AMBIENT_GESTURE,
@@ -418,6 +422,49 @@
         }
     }
 
+    /**
+     * A Sensor that is injected via plugin.
+     */
+    private class PluginTriggerSensor extends TriggerSensor {
+
+        private final SensorManagerPlugin.Sensor mPluginSensor;
+        private final SensorManagerPlugin.TriggerEventListener mTriggerEventListener = (event) -> {
+            onTrigger(null);
+        };
+
+        PluginTriggerSensor(SensorManagerPlugin.Sensor sensor, String setting, boolean configured,
+                int pulseReason, boolean reportsTouchCoordinates, boolean requiresTouchscreen) {
+            super(null, setting, configured, pulseReason, reportsTouchCoordinates,
+                    requiresTouchscreen);
+            mPluginSensor = sensor;
+        }
+
+        @Override
+        public void updateListener() {
+            if (!mConfigured) return;
+            AsyncSensorManager asyncSensorManager = (AsyncSensorManager) mSensorManager;
+            if (mRequested && !mDisabled && enabledBySetting() && !mRegistered) {
+                asyncSensorManager.requestPluginTriggerSensor(mPluginSensor, mTriggerEventListener);
+                mRegistered = true;
+                if (DEBUG) Log.d(TAG, "requestPluginTriggerSensor");
+            } else if (mRegistered) {
+                asyncSensorManager.cancelPluginTriggerSensor(mPluginSensor, mTriggerEventListener);
+                mRegistered = false;
+                if (DEBUG) Log.d(TAG, "cancelPluginTriggerSensor");
+            }
+        }
+
+        @Override
+        public String toString() {
+            return new StringBuilder("{mRegistered=").append(mRegistered)
+                    .append(", mRequested=").append(mRequested)
+                    .append(", mDisabled=").append(mDisabled)
+                    .append(", mConfigured=").append(mConfigured)
+                    .append(", mSensor=").append(mPluginSensor).append("}").toString();
+        }
+
+    }
+
     private class WakeScreenSensor extends TriggerSensor {
 
         WakeScreenSensor() {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index cb91d78..d69b1bf 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -142,6 +142,7 @@
                     mDozeHost.onDoubleTap(screenX, screenY);
                     mMachine.wakeUp();
                 } else if (isPickup || isWakeLockScreen) {
+                    mDozeHost.setPassiveInterrupt(true);
                     mMachine.wakeUp();
                 } else {
                     mDozeHost.extendPulse();
@@ -210,6 +211,7 @@
             case INITIALIZED:
                 mBroadcastReceiver.register(mContext);
                 mDozeHost.addCallback(mHostCallback);
+                mDozeHost.setPassiveInterrupt(false);
                 checkTriggersAtInit();
                 break;
             case DOZE:
@@ -219,6 +221,7 @@
                     mDozeSensors.reregisterAllSensors();
                 }
                 mDozeSensors.setListening(true);
+                mDozeHost.setPassiveInterrupt(false);
                 break;
             case DOZE_AOD_PAUSED:
             case DOZE_AOD_PAUSING:
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index bde7f1b..512cd82 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -90,6 +90,7 @@
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
 import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
 import com.android.systemui.util.EmergencyDialerConstants;
 import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator;
 
@@ -102,7 +103,8 @@
  * is provisioned.
  */
 class GlobalActionsDialog implements DialogInterface.OnDismissListener,
-        DialogInterface.OnClickListener, DialogInterface.OnShowListener {
+        DialogInterface.OnClickListener, DialogInterface.OnShowListener,
+        ConfigurationController.ConfigurationListener {
 
     static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
     static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
@@ -197,6 +199,8 @@
 
         mEmergencyAffordanceManager = new EmergencyAffordanceManager(context);
         mScreenshotHelper = new ScreenshotHelper(context);
+
+        Dependency.get(ConfigurationController.class).addCallback(this);
     }
 
     /**
@@ -417,6 +421,15 @@
                 || state == SOME_AUTH_REQUIRED_AFTER_USER_REQUEST);
     }
 
+    @Override
+    public void onUiModeChanged() {
+        mContext.getTheme().applyStyle(mContext.getThemeResId(), true);
+    }
+
+    public void destroy() {
+        Dependency.get(ConfigurationController.class).removeCallback(this);
+    }
+
     private final class PowerAction extends SinglePressAction implements LongPressAction {
         private PowerAction() {
             super(R.drawable.ic_lock_power_off,
@@ -1530,7 +1543,6 @@
                                 * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
                         mGradientDrawable.setAlpha(alpha);
                     })
-                    .withEndAction(() -> getWindow().getDecorView().requestAccessibilityFocus())
                     .start();
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 1489c21..0394998 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -61,6 +61,10 @@
     @Override
     public void destroy() {
         SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
+        if (mGlobalActions != null) {
+            mGlobalActions.destroy();
+            mGlobalActions = null;
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
index 4a67868..df76315 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaProjectionPermissionActivity.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.media;
 
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 
 import android.app.Activity;
 import android.app.AlertDialog;
@@ -151,7 +151,7 @@
         ((CheckBox) mDialog.findViewById(R.id.remember)).setOnCheckedChangeListener(this);
         final Window w = mDialog.getWindow();
         w.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
-        w.addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+        w.addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
 
         mDialog.show();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginEnablerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginEnablerImpl.java
new file mode 100644
index 0000000..e2417f7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginEnablerImpl.java
@@ -0,0 +1,48 @@
+/*
+ * 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.plugins;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.shared.plugins.PluginEnabler;
+
+public class PluginEnablerImpl implements PluginEnabler {
+
+    final private PackageManager mPm;
+
+    public PluginEnablerImpl(Context context) {
+        this(context.getPackageManager());
+    }
+
+    @VisibleForTesting public PluginEnablerImpl(PackageManager pm) {
+        mPm = pm;
+    }
+
+    @Override
+    public void setEnabled(ComponentName component, boolean enabled) {
+        final int desiredState = enabled ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+                : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+        mPm.setComponentEnabledSetting(component, desiredState, PackageManager.DONT_KILL_APP);
+    }
+
+    @Override
+    public boolean isEnabled(ComponentName component) {
+        return mPm.getComponentEnabledSetting(component)
+                != PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginInitializerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginInitializerImpl.java
index 108c2d0..95029c0 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginInitializerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginInitializerImpl.java
@@ -16,32 +16,55 @@
 
 import android.content.Context;
 import android.os.Looper;
+import android.util.Log;
 
 import com.android.systemui.Dependency;
-import com.android.systemui.shared.plugins.PluginInitializer;
 import com.android.systemui.R;
+import com.android.systemui.shared.plugins.PluginEnabler;
+import com.android.systemui.shared.plugins.PluginInitializer;
+import com.android.systemui.shared.plugins.PluginManagerImpl;
 
 public class PluginInitializerImpl implements PluginInitializer {
+
+    /**
+     * True if WTFs should lead to crashes
+     */
+    private static final boolean WTFS_SHOULD_CRASH = false;
+    private boolean mWtfsSet;
+
     @Override
     public Looper getBgLooper() {
         return Dependency.get(Dependency.BG_LOOPER);
     }
 
     @Override
-    public Runnable getBgInitCallback() {
-        return new Runnable() {
-            @Override
-            public void run() {
-                // Plugin dependencies that don't have another good home can go here, but
-                // dependencies that have better places to init can happen elsewhere.
-                Dependency.get(PluginDependencyProvider.class)
-                        .allowPluginDependency(ActivityStarter.class);
-            }
-        };
+    public void onPluginManagerInit() {
+        // Plugin dependencies that don't have another good home can go here, but
+        // dependencies that have better places to init can happen elsewhere.
+        Dependency.get(PluginDependencyProvider.class)
+                .allowPluginDependency(ActivityStarter.class);
     }
 
     @Override
     public String[] getWhitelistedPlugins(Context context) {
         return context.getResources().getStringArray(R.array.config_pluginWhitelist);
     }
+
+    public PluginEnabler getPluginEnabler(Context context) {
+        return new PluginEnablerImpl(context);
+    }
+
+    @Override
+    public void handleWtfs() {
+        if (WTFS_SHOULD_CRASH && !mWtfsSet) {
+            mWtfsSet = true;
+            Log.setWtfHandler(new Log.TerribleFailureHandler() {
+                @Override
+                public void onTerribleFailure(String tag, Log.TerribleFailure what,
+                        boolean system) {
+                    throw new PluginManagerImpl.CrashWhilePluginActiveException(what);
+                }
+            });
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index 4b5ab2a..76dfddb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -6,7 +6,10 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.content.Context;
+import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.graphics.Rect;
+import android.os.Bundle;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -29,6 +32,7 @@
 public class PagedTileLayout extends ViewPager implements QSTileLayout {
 
     private static final boolean DEBUG = false;
+    private static final String CURRENT_PAGE = "current_page";
 
     private static final String TAG = "PagedTileLayout";
     private static final int REVEAL_SCROLL_DURATION_MILLIS = 750;
@@ -54,6 +58,10 @@
     private AnimatorSet mBounceAnimatorSet;
     private float mLastExpansion;
     private boolean mDistributeTiles = false;
+    private int mPageToRestore = -1;
+    private int mLayoutOrientation;
+    private int mLayoutDirection;
+    private int mHorizontalClipBound;
 
     public PagedTileLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -61,13 +69,37 @@
         setAdapter(mAdapter);
         setOnPageChangeListener(mOnPageChangeListener);
         setCurrentItem(0, false);
+        mLayoutOrientation = getResources().getConfiguration().orientation;
+        mLayoutDirection = getLayoutDirection();
+    }
+
+    public void saveInstanceState(Bundle outState) {
+        outState.putInt(CURRENT_PAGE, getCurrentItem());
+    }
+
+    public void restoreInstanceState(Bundle savedInstanceState) {
+        // There's only 1 page at this point. We want to restore the correct page once the
+        // pages have been inflated
+        mPageToRestore = savedInstanceState.getInt(CURRENT_PAGE, -1);
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        if (mLayoutOrientation != newConfig.orientation) {
+            mLayoutOrientation = newConfig.orientation;
+            setCurrentItem(0, false);
+        }
     }
 
     @Override
     public void onRtlPropertiesChanged(int layoutDirection) {
         super.onRtlPropertiesChanged(layoutDirection);
-        setAdapter(mAdapter);
-        setCurrentItem(0, false);
+        if (mLayoutDirection != layoutDirection) {
+            mLayoutDirection = layoutDirection;
+            setAdapter(mAdapter);
+            setCurrentItem(0, false);
+        }
     }
 
     @Override
@@ -116,6 +148,7 @@
         super.onFinishInflate();
         mPages.add((TilePage) LayoutInflater.from(getContext())
                 .inflate(R.layout.qs_paged_page, this, false));
+        mAdapter.notifyDataSetChanged();
     }
 
     public void setPageIndicator(PageIndicator indicator) {
@@ -218,7 +251,10 @@
         mPageIndicator.setNumPages(mPages.size());
         setAdapter(mAdapter);
         mAdapter.notifyDataSetChanged();
-        setCurrentItem(0, false);
+        if (mPageToRestore != -1) {
+            setCurrentItem(mPageToRestore, false);
+            mPageToRestore = -1;
+        }
     }
 
     @Override
@@ -226,8 +262,8 @@
         // Update bottom padding, useful for removing extra space once the panel page indicator is
         // hidden.
         Resources res = getContext().getResources();
-        final int sidePadding = res.getDimensionPixelSize(R.dimen.notification_side_paddings);
-        setPadding(sidePadding, 0, sidePadding,
+        mHorizontalClipBound = res.getDimensionPixelSize(R.dimen.notification_side_paddings);
+        setPadding(0, 0, 0,
                 getContext().getResources().getDimensionPixelSize(
                         R.dimen.qs_paged_tile_layout_padding_bottom));
         boolean changed = false;
@@ -242,6 +278,13 @@
     }
 
     @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        Rect clipBounds = new Rect(mHorizontalClipBound, 0, (r-l) - mHorizontalClipBound, b - t);
+        setClipBounds(clipBounds);
+    }
+
+    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 
         final int nTiles = mTiles.size();
@@ -378,6 +421,14 @@
         public int maxTiles() {
             return mColumns * mRows;
         }
+
+        @Override
+        public boolean updateResources() {
+            final int sidePadding = getContext().getResources().getDimensionPixelSize(
+                    R.dimen.notification_side_paddings);
+            setPadding(sidePadding, 0, sidePadding, 0);
+            return super.updateResources();
+        }
     }
 
     private final PagerAdapter mAdapter = new PagerAdapter() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 79e5086..f9971d8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -103,6 +103,9 @@
             setListening(savedInstanceState.getBoolean(EXTRA_LISTENING));
             setEditLocation(view);
             mQSCustomizer.restoreInstanceState(savedInstanceState);
+            if (mQsExpanded) {
+                mQSPanel.getTileLayout().restoreInstanceState(savedInstanceState);
+            }
         }
         SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
     }
@@ -127,6 +130,9 @@
         outState.putBoolean(EXTRA_EXPANDED, mQsExpanded);
         outState.putBoolean(EXTRA_LISTENING, mListening);
         mQSCustomizer.saveInstanceState(outState);
+        if (mQsExpanded) {
+            mQSPanel.getTileLayout().saveInstanceState(outState);
+        }
     }
 
     @VisibleForTesting
@@ -166,7 +172,6 @@
     }
 
     private void setEditLocation(View view) {
-        Log.w(TAG, "I'm changing the location of the button!!!");
         View edit = view.findViewById(android.R.id.edit);
         int[] loc = edit.getLocationOnScreen();
         int x = loc[0] + edit.getWidth() / 2;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index e98ef4c..cf63e47 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -25,6 +25,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.metrics.LogMaker;
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.service.quicksettings.Tile;
@@ -666,6 +667,11 @@
     }
 
     public interface QSTileLayout {
+
+        default void saveInstanceState(Bundle outState) {}
+
+        default void restoreInstanceState(Bundle savedInstanceState) {}
+
         void addTile(TileRecord tile);
 
         void removeTile(TileRecord tile);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index e884302..1dd729d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -104,11 +104,13 @@
         // container is measured. Any change in the tiles, should trigger a remeasure.
         final int numTiles = mRecords.size();
         final int width = MeasureSpec.getSize(widthMeasureSpec);
+        final int availableWidth = width - getPaddingStart() - getPaddingEnd();
         final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
         if (heightMode == MeasureSpec.UNSPECIFIED) {
             mRows = (numTiles + mColumns - 1) / mColumns;
         }
-        mCellWidth = (width - mSidePadding * 2 - (mCellMarginHorizontal * mColumns)) / mColumns;
+        mCellWidth =
+                (availableWidth - mSidePadding * 2 - (mCellMarginHorizontal * mColumns)) / mColumns;
 
         // Measure each QS tile.
         View previousView = this;
@@ -124,7 +126,7 @@
                 (mRows != 0 ? (mCellMarginTop - mCellMarginVertical) : 0);
         if (height < 0) height = 0;
 
-        setMeasuredDimension(width, height);
+        setMeasuredDimension(width + getPaddingStart() + getPaddingEnd(), height);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 92f5cae..15d2e66 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -308,6 +308,7 @@
                     @Override
                     public void onClick(View v) {
                         int position = holder.getAdapterPosition();
+                        if (position == RecyclerView.NO_POSITION) return;
                         if (mAccessibilityAction != ACTION_NONE) {
                             selectPosition(position, v);
                         } else {
@@ -561,6 +562,7 @@
             if (viewHolder == mCurrentDrag) return;
             if (mCurrentDrag != null) {
                 int position = mCurrentDrag.getAdapterPosition();
+                if (position == RecyclerView.NO_POSITION) return;
                 TileInfo info = mTiles.get(position);
                 mCurrentDrag.mTileView.setShowAppLabel(
                         position > mEditIndex && !info.isSystem);
@@ -582,13 +584,14 @@
         @Override
         public boolean canDropOver(RecyclerView recyclerView, ViewHolder current,
                 ViewHolder target) {
-            if (target.getAdapterPosition() == 0){
+            final int position = target.getAdapterPosition();
+            if (position == 0 || position == RecyclerView.NO_POSITION){
                 return false;
             }
             if (!canRemoveTiles() && current.getAdapterPosition() < mEditIndex) {
-                return target.getAdapterPosition() < mEditIndex;
+                return position < mEditIndex;
             }
-            return target.getAdapterPosition() <= mEditIndex + 1;
+            return position <= mEditIndex + 1;
         }
 
         @Override
@@ -610,6 +613,10 @@
         public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) {
             int from = viewHolder.getAdapterPosition();
             int to = target.getAdapterPosition();
+            if (from == 0 || from == RecyclerView.NO_POSITION ||
+                    to == 0 || to == RecyclerView.NO_POSITION) {
+                return false;
+            }
             return move(from, to, target.itemView);
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index ed78048..921db69 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -46,6 +46,7 @@
 import com.android.systemui.statusbar.policy.CastController;
 import com.android.systemui.statusbar.policy.CastController.CastDevice;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
+import com.android.systemui.statusbar.policy.NetworkController;
 
 import java.util.LinkedHashMap;
 import java.util.Set;
@@ -58,16 +59,18 @@
     private final CastController mController;
     private final CastDetailAdapter mDetailAdapter;
     private final KeyguardMonitor mKeyguard;
+    private final NetworkController mNetworkController;
     private final Callback mCallback = new Callback();
     private final ActivityStarter mActivityStarter;
     private Dialog mDialog;
-    private boolean mRegistered;
+    private boolean mWifiConnected;
 
     public CastTile(QSHost host) {
         super(host);
         mController = Dependency.get(CastController.class);
         mDetailAdapter = new CastDetailAdapter();
         mKeyguard = Dependency.get(KeyguardMonitor.class);
+        mNetworkController = Dependency.get(NetworkController.class);
         mActivityStarter = Dependency.get(ActivityStarter.class);
     }
 
@@ -87,10 +90,12 @@
         if (listening) {
             mController.addCallback(mCallback);
             mKeyguard.addCallback(mCallback);
+            mNetworkController.addCallback(mSignalCallback);
         } else {
             mController.setDiscovering(false);
             mController.removeCallback(mCallback);
             mKeyguard.removeCallback(mCallback);
+            mNetworkController.removeCallback(mSignalCallback);
         }
     }
 
@@ -112,6 +117,9 @@
 
     @Override
     protected void handleClick() {
+        if (getState().state == Tile.STATE_UNAVAILABLE) {
+            return;
+        }
         if (mKeyguard.isSecure() && !mKeyguard.canSkipBouncer()) {
             mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
                 showDetail(true);
@@ -164,13 +172,22 @@
         if (!state.value && connecting) {
             state.label = mContext.getString(R.string.quick_settings_connecting);
         }
-        state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.icon = ResourceIcon.get(state.value ? R.drawable.ic_qs_cast_on
                 : R.drawable.ic_qs_cast_off);
+        if (mWifiConnected) {
+            state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+            state.secondaryLabel = "";
+            state.contentDescription = state.contentDescription + ","
+                    + mContext.getString(R.string.accessibility_quick_settings_open_details);
+            state.expandedAccessibilityClassName = Button.class.getName();
+        } else {
+            state.state = Tile.STATE_UNAVAILABLE;
+            String noWifi = mContext.getString(R.string.quick_settings_cast_no_wifi);
+            state.secondaryLabel = noWifi;
+            state.contentDescription = state.contentDescription + ", " + mContext.getString(
+                    R.string.accessibility_quick_settings_not_available, noWifi);
+        }
         mDetailAdapter.updateItems(devices);
-        state.expandedAccessibilityClassName = Button.class.getName();
-        state.contentDescription = state.contentDescription + ","
-                + mContext.getString(R.string.accessibility_quick_settings_open_details);
     }
 
     @Override
@@ -192,6 +209,22 @@
                 : mContext.getString(R.string.quick_settings_cast_device_default_name);
     }
 
+    private final NetworkController.SignalCallback mSignalCallback =
+            new NetworkController.SignalCallback() {
+                @Override
+                public void setWifiIndicators(boolean enabled,
+                        NetworkController.IconState statusIcon,
+                        NetworkController.IconState qsIcon, boolean activityIn, boolean activityOut,
+                        String description, boolean isTransient, String statusLabel) {
+                    // statusIcon.visible has the connected status information
+                    boolean enabledAndConnected = enabled && qsIcon.visible;
+                    if (enabledAndConnected != mWifiConnected) {
+                        mWifiConnected = enabledAndConnected;
+                        refreshState();
+                    }
+                }
+            };
+
     private final class Callback implements CastController.Callback, KeyguardMonitor.Callback {
         @Override
         public void onCastDevicesChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
index f217596..5bb5b2d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.recents.views;
 
-import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.content.Context;
 import android.graphics.Point;
@@ -25,14 +24,11 @@
 import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-
 import com.android.systemui.R;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.events.EventBus;
 import com.android.systemui.recents.events.ui.dragndrop.DragEndEvent;
 import com.android.systemui.recents.events.ui.dragndrop.DragStartEvent;
-import com.android.systemui.shared.recents.utilities.Utilities;
-import com.android.systemui.shared.recents.model.TaskStack;
 
 public class TaskViewAccessibilityDelegate extends View.AccessibilityDelegate {
     private static final String TAG = "TaskViewAccessibilityDelegate";
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index 6918a63..2ae53b5 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -46,11 +46,7 @@
         window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
         window.requestFeature(Window.FEATURE_NO_TITLE);
 
-        // Use a dialog theme as the activity theme, but inflate the content as
-        // the QS content.
-        ContextThemeWrapper themedContext = new ContextThemeWrapper(this,
-                com.android.internal.R.style.Theme_DeviceDefault_QuickSettings);
-        View v = LayoutInflater.from(themedContext).inflate(
+        View v = LayoutInflater.from(this).inflate(
                 R.layout.quick_settings_brightness_dialog, null);
         setContentView(v);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
index 2c384d0..21a33b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT;
+
 import android.annotation.NonNull;
 import android.content.Context;
 import android.content.res.Resources;
@@ -85,6 +87,7 @@
         for (OnAmbientChangedListener listener : mListeners) {
             listener.onAmbientStateChanged(entry, false);
         }
+        entry.row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 5c0b328..daaefb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -16,6 +16,9 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.statusbar.phone.StatusBar.ONLY_CORE_APPS;
+
+import android.app.StatusBarManager;
 import android.content.ComponentName;
 import android.graphics.Rect;
 import android.hardware.biometrics.IBiometricPromptReceiver;
@@ -24,7 +27,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.RemoteException;
+
 import androidx.annotation.VisibleForTesting;
 import android.util.Pair;
 
@@ -117,7 +120,7 @@
         default void removeIcon(String slot) { }
         default void disable(int state1, int state2, boolean animate) { }
         default void animateExpandNotificationsPanel() { }
-        default void animateCollapsePanels(int flags) { }
+        default void animateCollapsePanels(int flags, boolean force) { }
         default void togglePanel() { }
         default void animateExpandSettingsPanel(String obj) { }
         default void setSystemUiVisibility(int vis, int fullscreenStackVis,
@@ -169,7 +172,13 @@
     }
 
     @VisibleForTesting
-    protected CommandQueue() {
+    public CommandQueue() {
+    }
+
+    public boolean panelsEnabled() {
+        return (mDisable1 & StatusBarManager.DISABLE_EXPAND) == 0
+                && (mDisable2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0
+                && !ONLY_CORE_APPS;
     }
 
     public void addCallbacks(Callbacks callbacks) {
@@ -234,10 +243,10 @@
         }
     }
 
-    public void animateCollapsePanels(int flags) {
+    public void animateCollapsePanels(int flags, boolean force) {
         synchronized (mLock) {
             mHandler.removeMessages(MSG_COLLAPSE_PANELS);
-            mHandler.obtainMessage(MSG_COLLAPSE_PANELS, flags, 0).sendToTarget();
+            mHandler.obtainMessage(MSG_COLLAPSE_PANELS, flags, force ? 1 : 0).sendToTarget();
         }
     }
 
@@ -592,7 +601,7 @@
                     break;
                 case MSG_COLLAPSE_PANELS:
                     for (int i = 0; i < mCallbacks.size(); i++) {
-                        mCallbacks.get(i).animateCollapsePanels(msg.arg1);
+                        mCallbacks.get(i).animateCollapsePanels(msg.arg1, msg.arg2 != 0);
                     }
                     break;
                 case MSG_TOGGLE_PANEL:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 30d9ef7..8526afd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -131,7 +131,7 @@
                 if (!isFalseTouch() && mDragDownCallback.onDraggedDown(mStartingChild,
                         (int) (y - mInitialTouchY))) {
                     if (mStartingChild == null) {
-                        mDragDownCallback.setEmptyDragAmount(0f);
+                        cancelExpansion();
                     } else {
                         mCallback.setUserLockedChild(mStartingChild, false);
                         mStartingChild = null;
@@ -206,11 +206,8 @@
         ValueAnimator anim = ValueAnimator.ofFloat(mLastHeight, 0);
         anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
         anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS);
-        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue());
-            }
+        anim.addUpdateListener(animation -> {
+            mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue());
         });
         anim.start();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
index e12b574..1f57634 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java
@@ -29,9 +29,9 @@
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
+import android.graphics.RecordingCanvas;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
-import android.view.DisplayListCanvas;
 import android.view.RenderNodeAnimator;
 import android.view.View;
 import android.view.ViewAnimationUtils;
@@ -54,10 +54,10 @@
     public static final float MAX_ICON_SCALE_AMOUNT = 1.5f;
     public static final float MIN_ICON_SCALE_AMOUNT = 0.8f;
 
+    protected final int mDarkIconColor;
+    protected final int mNormalColor;
     private final int mMinBackgroundRadius;
     private final Paint mCirclePaint;
-    private final int mDarkIconColor;
-    private final int mNormalColor;
     private final ArgbEvaluator mColorInterpolator;
     private final FlingAnimationUtils mFlingAnimationUtils;
     private float mCircleRadius;
@@ -76,7 +76,7 @@
     private float mCircleStartRadius;
     private float mMaxCircleSize;
     private Animator mPreviewClipper;
-    private float mRestingAlpha = KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT;
+    private float mRestingAlpha = 1f;
     private boolean mSupportHardware;
     private boolean mFinishing;
     private boolean mLaunchingAffordance;
@@ -192,8 +192,8 @@
                 // Our hardware drawing proparties can be null if the finishing started but we have
                 // never drawn before. In that case we are not doing a render thread animation
                 // anyway, so we need to use the normal drawing.
-                DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
-                displayListCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius,
+                RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
+                recordingCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius,
                         mHwCirclePaint);
             } else {
                 updateCircleColor();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 0c5f391..a00eac4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -19,14 +19,14 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.app.admin.DevicePolicyManager;
-import android.hardware.biometrics.BiometricSourceType;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.Resources;
 import android.content.res.ColorStateList;
+import android.content.res.Resources;
 import android.graphics.Color;
+import android.hardware.biometrics.BiometricSourceType;
 import android.hardware.face.FaceManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.BatteryManager;
@@ -106,6 +106,7 @@
 
     private final DevicePolicyManager mDevicePolicyManager;
     private boolean mDozing;
+    private float mDarkAmount;
 
     /**
      * Creates a new KeyguardIndicationController and registers callbacks.
@@ -298,6 +299,15 @@
         if (mVisible) {
             // Walk down a precedence-ordered list of what indication
             // should be shown based on user or device state
+            if (mDozing) {
+                if (!TextUtils.isEmpty(mTransientIndication)) {
+                    mTextView.setTextColor(Color.WHITE);
+                    mTextView.switchIndication(mTransientIndication);
+                }
+                updateAlphas();
+                return;
+            }
+
             KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
             int userId = KeyguardUpdateMonitor.getCurrentUser();
             String trustGrantedIndication = getTrustGrantedIndication();
@@ -335,6 +345,14 @@
         }
     }
 
+    private void updateAlphas() {
+        if (!TextUtils.isEmpty(mTransientIndication)) {
+            mTextView.setAlpha(1f);
+        } else {
+            mTextView.setAlpha(1f - mDarkAmount);
+        }
+    }
+
     // animates textView - textView moves up and bounces down
     private void animateText(KeyguardIndicationTextView textView, String indication) {
         int yTranslation = mContext.getResources().getInteger(
@@ -492,6 +510,14 @@
         pw.println("  computePowerIndication(): " + computePowerIndication());
     }
 
+    public void setDarkAmount(float darkAmount) {
+        if (mDarkAmount == darkAmount) {
+            return;
+        }
+        mDarkAmount = darkAmount;
+        updateAlphas();
+    }
+
     protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
         public static final int HIDE_DELAY_MS = 5000;
         private int mLastSuccessiveErrorMessage = -1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index cfa09bc..f3a46ce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -29,6 +29,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins;
 
 /**
@@ -41,11 +42,14 @@
     // Dependencies:
     private final NotificationRemoteInputManager mRemoteInputManager =
             Dependency.get(NotificationRemoteInputManager.class);
+    private final NotificationEntryManager mEntryManager =
+            Dependency.get(NotificationEntryManager.class);
+    private final NotificationGroupManager mGroupManager =
+            Dependency.get(NotificationGroupManager.class);
 
     private final Context mContext;
 
     protected NotificationPresenter mPresenter;
-    protected NotificationEntryManager mEntryManager;
 
     public NotificationListener(Context context) {
         mContext = context;
@@ -61,7 +65,7 @@
             return;
         }
         final RankingMap currentRanking = getCurrentRanking();
-        mPresenter.getHandler().post(() -> {
+        Dependency.get(Dependency.MAIN_HANDLER).post(() -> {
             for (StatusBarNotification sbn : notifications) {
                 mEntryManager.addNotification(sbn, currentRanking);
             }
@@ -73,7 +77,7 @@
             final RankingMap rankingMap) {
         if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
         if (sbn != null && !onPluginNotificationPosted(sbn, rankingMap)) {
-            mPresenter.getHandler().post(() -> {
+            Dependency.get(Dependency.MAIN_HANDLER).post(() -> {
                 processForRemoteInput(sbn.getNotification(), mContext);
                 String key = sbn.getKey();
                 boolean isUpdate =
@@ -83,7 +87,7 @@
                 // anyway. This is true also when the summary is canceled,
                 // because children are automatically canceled by NoMan in that case.
                 if (!ENABLE_CHILD_NOTIFICATIONS
-                        && mPresenter.getGroupManager().isChildInGroupWithSummary(sbn)) {
+                        && mGroupManager.isChildInGroupWithSummary(sbn)) {
                     if (DEBUG) {
                         Log.d(TAG, "Ignoring group child due to existing summary: " + sbn);
                     }
@@ -112,7 +116,7 @@
         if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
         if (sbn != null && !onPluginNotificationRemoved(sbn, rankingMap)) {
             final String key = sbn.getKey();
-            mPresenter.getHandler().post(() -> {
+            Dependency.get(Dependency.MAIN_HANDLER).post(() -> {
                 mEntryManager.removeNotification(key, rankingMap);
             });
         }
@@ -123,16 +127,14 @@
         if (DEBUG) Log.d(TAG, "onRankingUpdate");
         if (rankingMap != null) {
             RankingMap r = onPluginRankingUpdate(rankingMap);
-            mPresenter.getHandler().post(() -> {
+            Dependency.get(Dependency.MAIN_HANDLER).post(() -> {
                 mEntryManager.updateNotificationRanking(r);
             });
         }
     }
 
-    public void setUpWithPresenter(NotificationPresenter presenter,
-            NotificationEntryManager entryManager) {
+    public void setUpWithPresenter(NotificationPresenter presenter) {
         mPresenter = presenter;
-        mEntryManager = entryManager;
 
         try {
             registerAsSystemService(mContext,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
index 89a842e..bc662e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
@@ -1,516 +1,61 @@
 /*
  * 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
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
  *
  *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under 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.
  */
+
 package com.android.systemui.statusbar;
 
-import android.app.ActivityManager;
-import android.app.KeyguardManager;
-import android.app.Notification;
-import android.app.admin.DevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.IntentSender;
 import android.content.pm.UserInfo;
-import android.database.ContentObserver;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
-import android.util.Log;
 import android.util.SparseArray;
-import android.util.SparseBooleanArray;
 
-import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.systemui.Dependency;
-import com.android.systemui.Dumpable;
-import com.android.systemui.OverviewProxyService;
-import com.android.systemui.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.statusbar.notification.NotificationData;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.notification.NotificationData.Entry;
 
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Handles keeping track of the current user, profiles, and various things related to hiding
- * contents, redacting notifications, and the lockscreen.
- */
-public class NotificationLockscreenUserManager implements Dumpable, StateListener {
-    private static final String TAG = "LockscreenUserManager";
-    private static final boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false;
-    public static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
-    public static final String NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION
+public interface NotificationLockscreenUserManager {
+    String PERMISSION_SELF = "com.android.systemui.permission.SELF";
+    String NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION
             = "com.android.systemui.statusbar.work_challenge_unlocked_notification_action";
 
-    private final DevicePolicyManager mDevicePolicyManager;
-    private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray();
-    private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
-    private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
-    private final DeviceProvisionedController mDeviceProvisionedController =
-            Dependency.get(DeviceProvisionedController.class);
-    private final UserManager mUserManager;
-    private final IStatusBarService mBarService;
-    private final LockPatternUtils mLockPatternUtils;
-    private final KeyguardManager mKeyguardManager;
-    private StatusBarKeyguardViewManager mKeyguardViewManager;
-
-    private boolean mShowLockscreenNotifications;
-    private boolean mAllowLockscreenRemoteInput;
-    private int mState = StatusBarState.SHADE;
-
-    protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
-
-            if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action) &&
-                    isCurrentProfile(getSendingUserId())) {
-                mUsersAllowingPrivateNotifications.clear();
-                updateLockscreenNotificationSetting();
-                mEntryManager.updateNotifications();
-            } else if (Intent.ACTION_DEVICE_LOCKED_CHANGED.equals(action)) {
-                if (userId != mCurrentUserId && isCurrentProfile(userId)) {
-                    updatePublicMode();
-                    mPresenter.onWorkChallengeChanged();
-                    mEntryManager.updateNotifications();
-                }
-            }
-        }
-    };
-
-    protected final BroadcastReceiver mBaseBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
-                mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
-                updateCurrentProfilesCache();
-                Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
-
-                updateLockscreenNotificationSetting();
-                updatePublicMode();
-                mPresenter.onUserSwitched(mCurrentUserId);
-                mEntryManager.getNotificationData().filterAndSort();
-            } else if (Intent.ACTION_USER_ADDED.equals(action)) {
-                updateCurrentProfilesCache();
-            } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
-                // Start the overview connection to the launcher service
-                Dependency.get(OverviewProxyService.class).startConnectionToCurrentUser();
-            } else if (NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION.equals(action)) {
-                final IntentSender intentSender = intent.getParcelableExtra(Intent.EXTRA_INTENT);
-                final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
-                if (intentSender != null) {
-                    try {
-                        mContext.startIntentSender(intentSender, null, 0, 0, 0);
-                    } catch (IntentSender.SendIntentException e) {
-                        /* ignore */
-                    }
-                }
-                if (notificationKey != null) {
-                    final int count =
-                            mEntryManager.getNotificationData().getActiveNotifications().size();
-                    final int rank = mEntryManager.getNotificationData().getRank(notificationKey);
-                    final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey,
-                            rank, count, true);
-                    try {
-                        mBarService.onNotificationClick(notificationKey, nv);
-                    } catch (RemoteException e) {
-                        /* ignore */
-                    }
-                }
-            }
-        }
-    };
-
-    protected final Context mContext;
-    protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
-
-    protected int mCurrentUserId = 0;
-    protected NotificationPresenter mPresenter;
-    protected NotificationEntryManager mEntryManager;
-    protected ContentObserver mLockscreenSettingsObserver;
-    protected ContentObserver mSettingsObserver;
-
-    public NotificationLockscreenUserManager(Context context) {
-        mContext = context;
-        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
-                Context.DEVICE_POLICY_SERVICE);
-        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
-        mCurrentUserId = ActivityManager.getCurrentUser();
-        mBarService = IStatusBarService.Stub.asInterface(
-                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        mLockPatternUtils = new LockPatternUtils(mContext);
-        mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-        Dependency.get(StatusBarStateController.class).addListener(this);
-    }
-
-    public void setUpWithPresenter(NotificationPresenter presenter,
-            NotificationEntryManager entryManager) {
-        mPresenter = presenter;
-        mEntryManager = entryManager;
-
-        mLockscreenSettingsObserver = new ContentObserver(mPresenter.getHandler()) {
-            @Override
-            public void onChange(boolean selfChange) {
-                // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS or
-                // LOCK_SCREEN_SHOW_NOTIFICATIONS, so we just dump our cache ...
-                mUsersAllowingPrivateNotifications.clear();
-                mUsersAllowingNotifications.clear();
-                // ... and refresh all the notifications
-                updateLockscreenNotificationSetting();
-                mEntryManager.updateNotifications();
-            }
-        };
-
-        mSettingsObserver = new ContentObserver(mPresenter.getHandler()) {
-            @Override
-            public void onChange(boolean selfChange) {
-                updateLockscreenNotificationSetting();
-                if (mDeviceProvisionedController.isDeviceProvisioned()) {
-                    mEntryManager.updateNotifications();
-                }
-            }
-        };
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
-                mLockscreenSettingsObserver,
-                UserHandle.USER_ALL);
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
-                true,
-                mLockscreenSettingsObserver,
-                UserHandle.USER_ALL);
-
-        mContext.getContentResolver().registerContentObserver(
-                Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
-                mSettingsObserver);
-
-        if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
-            mContext.getContentResolver().registerContentObserver(
-                    Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT),
-                    false,
-                    mSettingsObserver,
-                    UserHandle.USER_ALL);
-        }
-
-        IntentFilter allUsersFilter = new IntentFilter();
-        allUsersFilter.addAction(
-                DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
-        allUsersFilter.addAction(Intent.ACTION_DEVICE_LOCKED_CHANGED);
-        mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL, allUsersFilter,
-                null, null);
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(Intent.ACTION_USER_SWITCHED);
-        filter.addAction(Intent.ACTION_USER_ADDED);
-        filter.addAction(Intent.ACTION_USER_UNLOCKED);
-        mContext.registerReceiver(mBaseBroadcastReceiver, filter);
-
-        IntentFilter internalFilter = new IntentFilter();
-        internalFilter.addAction(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
-        mContext.registerReceiver(mBaseBroadcastReceiver, internalFilter, PERMISSION_SELF, null);
-
-        updateCurrentProfilesCache();
-
-        mSettingsObserver.onChange(false);  // set up
-    }
-
-    public boolean shouldShowLockscreenNotifications() {
-        return mShowLockscreenNotifications;
-    }
-
-    public boolean shouldAllowLockscreenRemoteInput() {
-        return mAllowLockscreenRemoteInput;
-    }
-
-    public boolean isCurrentProfile(int userId) {
-        synchronized (mCurrentProfiles) {
-            return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
-        }
-    }
-
-    public void setKeyguardViewManager(StatusBarKeyguardViewManager sbkvm) {
-        mKeyguardViewManager = sbkvm;
-    }
-
-    @Override
-    public void onStateChanged(int newState) {
-        mState = newState;
-        updatePublicMode();
-    }
-
-    public void updatePublicMode() {
-        //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns
-        // false when it should be true. Therefore, if we are not on the SHADE, don't even bother
-        // asking if the keyguard is showing. We still need to check it though because showing the
-        // camera on the keyguard has a state of SHADE but the keyguard is still showing.
-        boolean showingKeyguard = mState != StatusBarState.SHADE
-                || mKeyguardViewManager.isShowing();
-        boolean devicePublic = showingKeyguard && mKeyguardViewManager.isSecure(getCurrentUserId());
-
-        SparseArray<UserInfo> currentProfiles = getCurrentProfiles();
-        for (int i = currentProfiles.size() - 1; i >= 0; i--) {
-            final int userId = currentProfiles.valueAt(i).id;
-            boolean isProfilePublic = devicePublic;
-            if (!devicePublic && userId != mCurrentUserId) {
-                // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge
-                // due to a race condition where this code could be called before
-                // TrustManagerService updates its internal records, resulting in an incorrect
-                // state being cached in mLockscreenPublicMode. (b/35951989)
-                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
-                        && mKeyguardViewManager.isSecure(userId)) {
-                    isProfilePublic = mKeyguardManager.isDeviceLocked(userId);
-                }
-            }
-            setLockscreenPublicMode(isProfilePublic, userId);
-        }
-    }
+    boolean shouldAllowLockscreenRemoteInput();
 
     /**
-     * Returns true if notifications are temporarily disabled for this user for security reasons,
-     * regardless of the normal settings for that user.
+     * @param userId user Id
+     * @return true if we re on a secure lock screen
      */
-    private boolean shouldTemporarilyHideNotifications(int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            userId = mCurrentUserId;
-        }
-        return KeyguardUpdateMonitor.getInstance(mContext).isUserInLockdown(userId);
-    }
+    boolean isLockscreenPublicMode(int userId);
 
-    /**
-     * Returns true if we're on a secure lockscreen and the user wants to hide notification data.
-     * If so, notifications should be hidden.
-     */
-    public boolean shouldHideNotifications(int userId) {
-        return isLockscreenPublicMode(userId) && !userAllowsNotificationsInPublic(userId)
-                || (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId))
-                || shouldTemporarilyHideNotifications(userId);
-    }
+    void setUpWithPresenter(NotificationPresenter presenter);
 
-    /**
-     * Returns true if we're on a secure lockscreen and the user wants to hide notifications via
-     * package-specific override.
-     */
-    public boolean shouldHideNotifications(String key) {
-        if (mEntryManager == null) {
-            Log.wtf(TAG, "mEntryManager was null!", new Throwable());
-            return true;
-        }
-        return isLockscreenPublicMode(mCurrentUserId)
-                && mEntryManager.getNotificationData().getVisibilityOverride(key) ==
-                        Notification.VISIBILITY_SECRET;
-    }
+    int getCurrentUserId();
 
-    public boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
-        if (mEntryManager == null) {
-            Log.wtf(TAG, "mEntryManager was null!", new Throwable());
-            return false;
-        }
-        return mShowLockscreenNotifications
-                && !mEntryManager.getNotificationData().isAmbient(sbn.getKey());
-    }
+    boolean isCurrentProfile(int userId);
 
-    private void setShowLockscreenNotifications(boolean show) {
-        mShowLockscreenNotifications = show;
-    }
+    void destroy();
 
-    private void setLockscreenAllowRemoteInput(boolean allowLockscreenRemoteInput) {
-        mAllowLockscreenRemoteInput = allowLockscreenRemoteInput;
-    }
+    SparseArray<UserInfo> getCurrentProfiles();
 
-    protected void updateLockscreenNotificationSetting() {
-        final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
-                1,
-                mCurrentUserId) != 0;
-        final int dpmFlags = mDevicePolicyManager.getKeyguardDisabledFeatures(
-                null /* admin */, mCurrentUserId);
-        final boolean allowedByDpm = (dpmFlags
-                & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) == 0;
+    void setLockscreenPublicMode(boolean isProfilePublic, int userId);
 
-        setShowLockscreenNotifications(show && allowedByDpm);
+    boolean shouldShowLockscreenNotifications();
 
-        if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
-            final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(),
-                    Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
-                    0,
-                    mCurrentUserId) != 0;
-            final boolean remoteInputDpm =
-                    (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
+    boolean shouldHideNotifications(int userId);
+    boolean shouldHideNotifications(String key);
+    boolean shouldShowOnKeyguard(StatusBarNotification sbn);
 
-            setLockscreenAllowRemoteInput(remoteInput && remoteInputDpm);
-        } else {
-            setLockscreenAllowRemoteInput(false);
-        }
-    }
+    boolean isAnyProfilePublicMode();
 
-    /**
-     * Has the given user chosen to allow their private (full) notifications to be shown even
-     * when the lockscreen is in "public" (secure & locked) mode?
-     */
-    public boolean userAllowsPrivateNotificationsInPublic(int userHandle) {
-        if (userHandle == UserHandle.USER_ALL) {
-            return true;
-        }
+    void updatePublicMode();
 
-        if (mUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) {
-            final boolean allowedByUser = 0 != Settings.Secure.getIntForUser(
-                    mContext.getContentResolver(),
-                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userHandle);
-            final boolean allowedByDpm = adminAllowsKeyguardFeature(userHandle,
-                    DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
-            final boolean allowed = allowedByUser && allowedByDpm;
-            mUsersAllowingPrivateNotifications.append(userHandle, allowed);
-            return allowed;
-        }
+    boolean needsRedaction(Entry entry);
 
-        return mUsersAllowingPrivateNotifications.get(userHandle);
-    }
-
-    private boolean adminAllowsKeyguardFeature(int userHandle, int feature) {
-        if (userHandle == UserHandle.USER_ALL) {
-            return true;
-        }
-        final int dpmFlags =
-                mDevicePolicyManager.getKeyguardDisabledFeatures(null /* admin */, userHandle);
-        return (dpmFlags & feature) == 0;
-    }
-
-    /**
-     * Save the current "public" (locked and secure) state of the lockscreen.
-     */
-    public void setLockscreenPublicMode(boolean publicMode, int userId) {
-        mLockscreenPublicMode.put(userId, publicMode);
-    }
-
-    public boolean isLockscreenPublicMode(int userId) {
-        if (userId == UserHandle.USER_ALL) {
-            return mLockscreenPublicMode.get(mCurrentUserId, false);
-        }
-        return mLockscreenPublicMode.get(userId, false);
-    }
-
-    /**
-     * Has the given user chosen to allow notifications to be shown even when the lockscreen is in
-     * "public" (secure & locked) mode?
-     */
-    private boolean userAllowsNotificationsInPublic(int userHandle) {
-        if (isCurrentProfile(userHandle) && userHandle != mCurrentUserId) {
-            return true;
-        }
-
-        if (mUsersAllowingNotifications.indexOfKey(userHandle) < 0) {
-            final boolean allowedByUser = 0 != Settings.Secure.getIntForUser(
-                    mContext.getContentResolver(),
-                    Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userHandle);
-            final boolean allowedByDpm = adminAllowsKeyguardFeature(userHandle,
-                    DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
-            final boolean allowed = allowedByUser && allowedByDpm;
-            mUsersAllowingNotifications.append(userHandle, allowed);
-            return allowed;
-        }
-
-        return mUsersAllowingNotifications.get(userHandle);
-    }
-
-    /** @return true if the entry needs redaction when on the lockscreen. */
-    public boolean needsRedaction(NotificationData.Entry ent) {
-        int userId = ent.notification.getUserId();
-
-        boolean currentUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
-        boolean notiUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(userId);
-        boolean redactedLockscreen = currentUserWantsRedaction || notiUserWantsRedaction;
-
-        boolean notificationRequestsRedaction =
-                ent.notification.getNotification().visibility == Notification.VISIBILITY_PRIVATE;
-        boolean userForcesRedaction = packageHasVisibilityOverride(ent.notification.getKey());
-
-        return userForcesRedaction || notificationRequestsRedaction && redactedLockscreen;
-    }
-
-    private boolean packageHasVisibilityOverride(String key) {
-        if (mEntryManager == null) {
-            Log.wtf(TAG, "mEntryManager was null!", new Throwable());
-            return true;
-        }
-        return mEntryManager.getNotificationData().getVisibilityOverride(key) ==
-                Notification.VISIBILITY_PRIVATE;
-    }
-
-    private void updateCurrentProfilesCache() {
-        synchronized (mCurrentProfiles) {
-            mCurrentProfiles.clear();
-            if (mUserManager != null) {
-                for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) {
-                    mCurrentProfiles.put(user.id, user);
-                }
-            }
-        }
-    }
-
-    public boolean isAnyProfilePublicMode() {
-        for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
-            if (isLockscreenPublicMode(mCurrentProfiles.valueAt(i).id)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns the current user id. This can change if the user is switched.
-     */
-    public int getCurrentUserId() {
-        return mCurrentUserId;
-    }
-
-    public SparseArray<UserInfo> getCurrentProfiles() {
-        return mCurrentProfiles;
-    }
-
-    public void destroy() {
-        mContext.unregisterReceiver(mBaseBroadcastReceiver);
-        mContext.unregisterReceiver(mAllUsersReceiver);
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("NotificationLockscreenUserManager state:");
-        pw.print("  mCurrentUserId=");
-        pw.println(mCurrentUserId);
-        pw.print("  mShowLockscreenNotifications=");
-        pw.println(mShowLockscreenNotifications);
-        pw.print("  mAllowLockscreenRemoteInput=");
-        pw.println(mAllowLockscreenRemoteInput);
-        pw.print("  mCurrentProfiles=");
-        for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
-            final int userId = mCurrentProfiles.valueAt(i).id;
-            pw.print("" + userId + " ");
-        }
-        pw.println();
-    }
+    boolean userAllowsPrivateNotificationsInPublic(int currentUserId);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
new file mode 100644
index 0000000..178c5c5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -0,0 +1,551 @@
+/*
+ * 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 android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
+
+import android.app.ActivityManager;
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.service.notification.StatusBarNotification;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dependency;
+import com.android.systemui.Dumpable;
+import com.android.systemui.OverviewProxyService;
+import com.android.systemui.statusbar.StatusBarStateController.StateListener;
+import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.phone.StatusBarRemoteInputCallback;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Handles keeping track of the current user, profiles, and various things related to hiding
+ * contents, redacting notifications, and the lockscreen.
+ */
+public class NotificationLockscreenUserManagerImpl implements
+        Dumpable, NotificationLockscreenUserManager, StateListener {
+    private static final String TAG = "LockscreenUserManager";
+    private static final boolean ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT = false;
+
+    private final DeviceProvisionedController mDeviceProvisionedController =
+            Dependency.get(DeviceProvisionedController.class);
+    private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
+
+    // Lazy
+    private NotificationEntryManager mEntryManager;
+
+    private final DevicePolicyManager mDevicePolicyManager;
+    private final SparseBooleanArray mLockscreenPublicMode = new SparseBooleanArray();
+    private final SparseBooleanArray mUsersAllowingPrivateNotifications = new SparseBooleanArray();
+    private final SparseBooleanArray mUsersAllowingNotifications = new SparseBooleanArray();
+    private final UserManager mUserManager;
+    private final IStatusBarService mBarService;
+
+    private boolean mShowLockscreenNotifications;
+    private boolean mAllowLockscreenRemoteInput;
+    private LockPatternUtils mLockPatternUtils;
+    protected KeyguardManager mKeyguardManager;
+    private int mState = StatusBarState.SHADE;
+
+    protected final BroadcastReceiver mAllUsersReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+
+            if (ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action) &&
+                    isCurrentProfile(getSendingUserId())) {
+                mUsersAllowingPrivateNotifications.clear();
+                updateLockscreenNotificationSetting();
+                getEntryManager().updateNotifications();
+            }
+        }
+    };
+
+    protected final BroadcastReceiver mBaseBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_USER_SWITCHED.equals(action)) {
+                mCurrentUserId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
+                updateCurrentProfilesCache();
+                Log.v(TAG, "userId " + mCurrentUserId + " is in the house");
+
+                updateLockscreenNotificationSetting();
+                updatePublicMode();
+                mPresenter.onUserSwitched(mCurrentUserId);
+                getEntryManager().getNotificationData().filterAndSort();
+            } else if (Intent.ACTION_USER_ADDED.equals(action)) {
+                updateCurrentProfilesCache();
+            } else if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
+                // Start the overview connection to the launcher service
+                Dependency.get(OverviewProxyService.class).startConnectionToCurrentUser();
+            } else if (NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION.equals(action)) {
+                final IntentSender intentSender = intent.getParcelableExtra(Intent.EXTRA_INTENT);
+                final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
+                if (intentSender != null) {
+                    try {
+                        mContext.startIntentSender(intentSender, null, 0, 0, 0);
+                    } catch (IntentSender.SendIntentException e) {
+                        /* ignore */
+                    }
+                }
+                if (notificationKey != null) {
+                    final int count =
+                            getEntryManager().getNotificationData().getActiveNotifications().size();
+                    final int rank = getEntryManager().getNotificationData().getRank(notificationKey);
+                    final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey,
+                            rank, count, true);
+                    try {
+                        mBarService.onNotificationClick(notificationKey, nv);
+                    } catch (RemoteException e) {
+                        /* ignore */
+                    }
+                }
+            }
+        }
+    };
+
+    protected final Context mContext;
+    protected final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<>();
+
+    protected int mCurrentUserId = 0;
+    protected NotificationPresenter mPresenter;
+    protected ContentObserver mLockscreenSettingsObserver;
+    protected ContentObserver mSettingsObserver;
+
+    private NotificationEntryManager getEntryManager() {
+        if (mEntryManager == null) {
+            mEntryManager = Dependency.get(NotificationEntryManager.class);
+        }
+        return mEntryManager;
+    }
+
+    public NotificationLockscreenUserManagerImpl(Context context) {
+        mContext = context;
+        mDevicePolicyManager = (DevicePolicyManager) mContext.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
+        mCurrentUserId = ActivityManager.getCurrentUser();
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+        Dependency.get(StatusBarStateController.class).addListener(this);
+        mLockPatternUtils = new LockPatternUtils(context);
+        mKeyguardManager = context.getSystemService(KeyguardManager.class);
+    }
+
+    public void setUpWithPresenter(NotificationPresenter presenter) {
+        mPresenter = presenter;
+
+        mLockscreenSettingsObserver = new ContentObserver(Dependency.get(Dependency.MAIN_HANDLER)) {
+            @Override
+            public void onChange(boolean selfChange) {
+                // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS or
+                // LOCK_SCREEN_SHOW_NOTIFICATIONS, so we just dump our cache ...
+                mUsersAllowingPrivateNotifications.clear();
+                mUsersAllowingNotifications.clear();
+                // ... and refresh all the notifications
+                updateLockscreenNotificationSetting();
+                getEntryManager().updateNotifications();
+            }
+        };
+
+        mSettingsObserver = new ContentObserver(Dependency.get(Dependency.MAIN_HANDLER)) {
+            @Override
+            public void onChange(boolean selfChange) {
+                updateLockscreenNotificationSetting();
+                if (mDeviceProvisionedController.isDeviceProvisioned()) {
+                    getEntryManager().updateNotifications();
+                }
+            }
+        };
+
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
+                mLockscreenSettingsObserver,
+                UserHandle.USER_ALL);
+
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
+                true,
+                mLockscreenSettingsObserver,
+                UserHandle.USER_ALL);
+
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
+                mSettingsObserver);
+
+        if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT),
+                    false,
+                    mSettingsObserver,
+                    UserHandle.USER_ALL);
+        }
+
+        mContext.registerReceiverAsUser(mAllUsersReceiver, UserHandle.ALL,
+                new IntentFilter(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+                null, null);
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Intent.ACTION_USER_SWITCHED);
+        filter.addAction(Intent.ACTION_USER_ADDED);
+        filter.addAction(Intent.ACTION_USER_UNLOCKED);
+        mContext.registerReceiver(mBaseBroadcastReceiver, filter);
+
+        IntentFilter internalFilter = new IntentFilter();
+        internalFilter.addAction(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
+        mContext.registerReceiver(mBaseBroadcastReceiver, internalFilter, PERMISSION_SELF, null);
+
+        updateCurrentProfilesCache();
+
+        mSettingsObserver.onChange(false);  // set up
+    }
+
+    public boolean shouldShowLockscreenNotifications() {
+        return mShowLockscreenNotifications;
+    }
+
+    public boolean shouldAllowLockscreenRemoteInput() {
+        return mAllowLockscreenRemoteInput;
+    }
+
+    public boolean isCurrentProfile(int userId) {
+        synchronized (mCurrentProfiles) {
+            return userId == UserHandle.USER_ALL || mCurrentProfiles.get(userId) != null;
+        }
+    }
+
+    /**
+     * Returns true if notifications are temporarily disabled for this user for security reasons,
+     * regardless of the normal settings for that user.
+     */
+    private boolean shouldTemporarilyHideNotifications(int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            userId = mCurrentUserId;
+        }
+        return KeyguardUpdateMonitor.getInstance(mContext).isUserInLockdown(userId);
+    }
+
+    /**
+     * Returns true if we're on a secure lockscreen and the user wants to hide notification data.
+     * If so, notifications should be hidden.
+     */
+    public boolean shouldHideNotifications(int userId) {
+        return isLockscreenPublicMode(userId) && !userAllowsNotificationsInPublic(userId)
+                || (userId != mCurrentUserId && shouldHideNotifications(mCurrentUserId))
+                || shouldTemporarilyHideNotifications(userId);
+    }
+
+    /**
+     * Returns true if we're on a secure lockscreen and the user wants to hide notifications via
+     * package-specific override.
+     */
+    public boolean shouldHideNotifications(String key) {
+        if (getEntryManager() == null) {
+            Log.wtf(TAG, "mEntryManager was null!", new Throwable());
+            return true;
+        }
+        return isLockscreenPublicMode(mCurrentUserId)
+                && getEntryManager().getNotificationData().getVisibilityOverride(key) ==
+                        Notification.VISIBILITY_SECRET;
+    }
+
+    public boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
+        if (getEntryManager() == null) {
+            Log.wtf(TAG, "mEntryManager was null!", new Throwable());
+            return false;
+        }
+        return mShowLockscreenNotifications
+                && !getEntryManager().getNotificationData().isAmbient(sbn.getKey());
+    }
+
+    private void setShowLockscreenNotifications(boolean show) {
+        mShowLockscreenNotifications = show;
+    }
+
+    private void setLockscreenAllowRemoteInput(boolean allowLockscreenRemoteInput) {
+        mAllowLockscreenRemoteInput = allowLockscreenRemoteInput;
+    }
+
+    protected void updateLockscreenNotificationSetting() {
+        final boolean show = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+                1,
+                mCurrentUserId) != 0;
+        final int dpmFlags = mDevicePolicyManager.getKeyguardDisabledFeatures(
+                null /* admin */, mCurrentUserId);
+        final boolean allowedByDpm = (dpmFlags
+                & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS) == 0;
+
+        setShowLockscreenNotifications(show && allowedByDpm);
+
+        if (ENABLE_LOCK_SCREEN_ALLOW_REMOTE_INPUT) {
+            final boolean remoteInput = Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
+                    0,
+                    mCurrentUserId) != 0;
+            final boolean remoteInputDpm =
+                    (dpmFlags & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
+
+            setLockscreenAllowRemoteInput(remoteInput && remoteInputDpm);
+        } else {
+            setLockscreenAllowRemoteInput(false);
+        }
+    }
+
+    /**
+     * Has the given user chosen to allow their private (full) notifications to be shown even
+     * when the lockscreen is in "public" (secure & locked) mode?
+     */
+    public boolean userAllowsPrivateNotificationsInPublic(int userHandle) {
+        if (userHandle == UserHandle.USER_ALL) {
+            return true;
+        }
+
+        if (mUsersAllowingPrivateNotifications.indexOfKey(userHandle) < 0) {
+            final boolean allowedByUser = 0 != Settings.Secure.getIntForUser(
+                    mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, 0, userHandle);
+            final boolean allowedByDpm = adminAllowsKeyguardFeature(userHandle,
+                    DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
+            final boolean allowed = allowedByUser && allowedByDpm;
+            mUsersAllowingPrivateNotifications.append(userHandle, allowed);
+            return allowed;
+        }
+
+        return mUsersAllowingPrivateNotifications.get(userHandle);
+    }
+
+    private boolean adminAllowsKeyguardFeature(int userHandle, int feature) {
+        if (userHandle == UserHandle.USER_ALL) {
+            return true;
+        }
+        final int dpmFlags =
+                mDevicePolicyManager.getKeyguardDisabledFeatures(null /* admin */, userHandle);
+        return (dpmFlags & feature) == 0;
+    }
+
+    /**
+     * Save the current "public" (locked and secure) state of the lockscreen.
+     */
+    public void setLockscreenPublicMode(boolean publicMode, int userId) {
+        mLockscreenPublicMode.put(userId, publicMode);
+    }
+
+    public boolean isLockscreenPublicMode(int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            return mLockscreenPublicMode.get(mCurrentUserId, false);
+        }
+        return mLockscreenPublicMode.get(userId, false);
+    }
+
+    /**
+     * Has the given user chosen to allow notifications to be shown even when the lockscreen is in
+     * "public" (secure & locked) mode?
+     */
+    private boolean userAllowsNotificationsInPublic(int userHandle) {
+        if (isCurrentProfile(userHandle) && userHandle != mCurrentUserId) {
+            return true;
+        }
+
+        if (mUsersAllowingNotifications.indexOfKey(userHandle) < 0) {
+            final boolean allowedByUser = 0 != Settings.Secure.getIntForUser(
+                    mContext.getContentResolver(),
+                    Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0, userHandle);
+            final boolean allowedByDpm = adminAllowsKeyguardFeature(userHandle,
+                    DevicePolicyManager.KEYGUARD_DISABLE_SECURE_NOTIFICATIONS);
+            final boolean allowed = allowedByUser && allowedByDpm;
+            mUsersAllowingNotifications.append(userHandle, allowed);
+            return allowed;
+        }
+
+        return mUsersAllowingNotifications.get(userHandle);
+    }
+
+    /** @return true if the entry needs redaction when on the lockscreen. */
+    public boolean needsRedaction(NotificationData.Entry ent) {
+        int userId = ent.notification.getUserId();
+
+        boolean currentUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(mCurrentUserId);
+        boolean notiUserWantsRedaction = !userAllowsPrivateNotificationsInPublic(userId);
+        boolean redactedLockscreen = currentUserWantsRedaction || notiUserWantsRedaction;
+
+        boolean notificationRequestsRedaction =
+                ent.notification.getNotification().visibility == Notification.VISIBILITY_PRIVATE;
+        boolean userForcesRedaction = packageHasVisibilityOverride(ent.notification.getKey());
+
+        return userForcesRedaction || notificationRequestsRedaction && redactedLockscreen;
+    }
+
+    private boolean packageHasVisibilityOverride(String key) {
+        if (getEntryManager() == null) {
+            Log.wtf(TAG, "mEntryManager was null!", new Throwable());
+            return true;
+        }
+        return getEntryManager().getNotificationData().getVisibilityOverride(key) ==
+                Notification.VISIBILITY_PRIVATE;
+    }
+
+    private void updateCurrentProfilesCache() {
+        synchronized (mCurrentProfiles) {
+            mCurrentProfiles.clear();
+            if (mUserManager != null) {
+                for (UserInfo user : mUserManager.getProfiles(mCurrentUserId)) {
+                    mCurrentProfiles.put(user.id, user);
+                }
+            }
+        }
+    }
+
+    public boolean isAnyProfilePublicMode() {
+        for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
+            if (isLockscreenPublicMode(mCurrentProfiles.valueAt(i).id)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the current user id. This can change if the user is switched.
+     */
+    public int getCurrentUserId() {
+        return mCurrentUserId;
+    }
+
+    public SparseArray<UserInfo> getCurrentProfiles() {
+        return mCurrentProfiles;
+    }
+
+    @Override
+    public void onStateChanged(int newState) {
+        mState = newState;
+        updatePublicMode();
+    }
+
+    public void updatePublicMode() {
+        //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns
+        // false when it should be true. Therefore, if we are not on the SHADE, don't even bother
+        // asking if the keyguard is showing. We still need to check it though because showing the
+        // camera on the keyguard has a state of SHADE but the keyguard is still showing.
+        final boolean showingKeyguard = mState != StatusBarState.SHADE
+              || mKeyguardMonitor.isShowing();
+        final boolean devicePublic = showingKeyguard && isSecure(getCurrentUserId());
+
+
+        // Look for public mode users. Users are considered public in either case of:
+        //   - device keyguard is shown in secure mode;
+        //   - profile is locked with a work challenge.
+        SparseArray<UserInfo> currentProfiles = getCurrentProfiles();
+        for (int i = currentProfiles.size() - 1; i >= 0; i--) {
+            final int userId = currentProfiles.valueAt(i).id;
+            boolean isProfilePublic = devicePublic;
+            if (!devicePublic && userId != getCurrentUserId()) {
+                // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge
+                // due to a race condition where this code could be called before
+                // TrustManagerService updates its internal records, resulting in an incorrect
+                // state being cached in mLockscreenPublicMode. (b/35951989)
+                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
+                        && isSecure(userId)) {
+                    isProfilePublic = mKeyguardManager.isDeviceLocked(userId);
+                }
+            }
+            setLockscreenPublicMode(isProfilePublic, userId);
+        }
+    }
+
+
+//    public void updatePublicMode() {
+//        //TODO: I think there may be a race condition where mKeyguardViewManager.isShowing() returns
+//        // false when it should be true. Therefore, if we are not on the SHADE, don't even bother
+//        // asking if the keyguard is showing. We still need to check it though because showing the
+//        // camera on the keyguard has a state of SHADE but the keyguard is still showing.
+//        final boolean showingKeyguard = mState != StatusBarState.SHADE
+//              || mKeyguardMonitor.isShowing();
+//        final boolean devicePublic = showingKeyguard && isSecure(getCurrentUserId());
+//
+//
+//        // Look for public mode users. Users are considered public in either case of:
+//        //   - device keyguard is shown in secure mode;
+//        //   - profile is locked with a work challenge.
+//        SparseArray<UserInfo> currentProfiles = getCurrentProfiles();
+//        for (int i = currentProfiles.size() - 1; i >= 0; i--) {
+//            final int userId = currentProfiles.valueAt(i).id;
+//            boolean isProfilePublic = devicePublic;
+//            if (!devicePublic && userId != getCurrentUserId()) {
+//                // We can't rely on KeyguardManager#isDeviceLocked() for unified profile challenge
+//                // due to a race condition where this code could be called before
+//                // TrustManagerService updates its internal records, resulting in an incorrect
+//                // state being cached in mLockscreenPublicMode. (b/35951989)
+//                if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
+//                        && isSecure(userId)) {
+//                    isProfilePublic = mKeyguardManager.isDeviceLocked(userId);
+//                }
+//            }
+//            setLockscreenPublicMode(isProfilePublic, userId);
+//        }
+//    }
+
+    private boolean isSecure(int userId) {
+        return mKeyguardMonitor.isSecure() || mLockPatternUtils.isSecure(userId);
+    }
+
+    public void destroy() {
+        mContext.unregisterReceiver(mBaseBroadcastReceiver);
+        mContext.unregisterReceiver(mAllUsersReceiver);
+    }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("NotificationLockscreenUserManager state:");
+        pw.print("  mCurrentUserId=");
+        pw.println(mCurrentUserId);
+        pw.print("  mShowLockscreenNotifications=");
+        pw.println(mShowLockscreenNotifications);
+        pw.print("  mAllowLockscreenRemoteInput=");
+        pw.println(mAllowLockscreenRemoteInput);
+        pw.print("  mCurrentProfiles=");
+        for (int i = mCurrentProfiles.size() - 1; i >= 0; i--) {
+            final int userId = mCurrentProfiles.valueAt(i).id;
+            pw.print("" + userId + " ");
+        }
+        pw.println();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index e89e6e8..c437b14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -15,19 +15,46 @@
  */
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.Dependency.MAIN_HANDLER;
+import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
+import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_MEDIA_FAKE_ARTWORK;
+import static com.android.systemui.statusbar.phone.StatusBar.ENABLE_LOCKSCREEN_WALLPAPER;
+import static com.android.systemui.statusbar.phone.StatusBar.SHOW_LOCKSCREEN_MEDIA_ARTWORK;
+
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
 import android.media.MediaMetadata;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
+import android.os.Handler;
+import android.os.Trace;
 import android.os.UserHandle;
 import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.Interpolators;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.LockscreenWallpaper;
+import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.statusbar.phone.ScrimState;
+import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -42,15 +69,45 @@
     private static final String TAG = "NotificationMediaManager";
     public static final boolean DEBUG_MEDIA = false;
 
+    private final StatusBarStateController mStatusBarStateController
+            = Dependency.get(StatusBarStateController.class);
+    private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+    private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
+
+    // Late binding
+    private NotificationEntryManager mEntryManager;
+
+    // Late binding, also @Nullable due to being in com.android.systemui.statusbar.phone package
+    @Nullable
+    private ShadeController mShadeController;
+    @Nullable
+    private StatusBarWindowController mStatusBarWindowController;
+
+    @Nullable
+    private BiometricUnlockController mBiometricUnlockController;
+    @Nullable
+    private ScrimController mScrimController;
+    @Nullable
+    private LockscreenWallpaper mLockscreenWallpaper;
+
+    protected final PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
+    protected final PorterDuffXfermode mSrcOverXferMode =
+            new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
+
+    private final Handler mHandler = Dependency.get(MAIN_HANDLER);
+
     private final Context mContext;
     private final MediaSessionManager mMediaSessionManager;
 
     protected NotificationPresenter mPresenter;
-    protected NotificationEntryManager mEntryManager;
     private MediaController mMediaController;
     private String mMediaNotificationKey;
     private MediaMetadata mMediaMetadata;
 
+    private BackDropView mBackdrop;
+    private ImageView mBackdropFront;
+    private ImageView mBackdropBack;
+
     private final MediaController.Callback mMediaListener = new MediaController.Callback() {
         @Override
         public void onPlaybackStateChanged(PlaybackState state) {
@@ -77,6 +134,29 @@
         }
     };
 
+    @Nullable
+    private ShadeController getShadeController() {
+        if (mShadeController == null) {
+            mShadeController = Dependency.get(ShadeController.class);
+        }
+        return mShadeController;
+    }
+
+    @Nullable
+    private StatusBarWindowController getWindowController() {
+        if (mStatusBarWindowController == null) {
+            mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
+        }
+        return mStatusBarWindowController;
+    }
+
+    private NotificationEntryManager getEntryManager() {
+        if (mEntryManager == null) {
+            mEntryManager = Dependency.get(NotificationEntryManager.class);
+        }
+        return mEntryManager;
+    }
+
     public NotificationMediaManager(Context context) {
         mContext = context;
         mMediaSessionManager
@@ -85,10 +165,8 @@
         // in session state
     }
 
-    public void setUpWithPresenter(NotificationPresenter presenter,
-            NotificationEntryManager entryManager) {
+    public void setUpWithPresenter(NotificationPresenter presenter) {
         mPresenter = presenter;
-        mEntryManager = entryManager;
     }
 
     public void onNotificationRemoved(String key) {
@@ -109,8 +187,9 @@
     public void findAndUpdateMediaNotifications() {
         boolean metaDataChanged = false;
 
-        synchronized (mEntryManager.getNotificationData()) {
-            ArrayList<NotificationData.Entry> activeNotifications = mEntryManager
+        NotificationEntryManager manager = getEntryManager();
+        synchronized (manager.getNotificationData()) {
+            ArrayList<NotificationData.Entry> activeNotifications = manager
                     .getNotificationData().getActiveNotifications();
             final int N = activeNotifications.size();
 
@@ -199,7 +278,7 @@
         }
 
         if (metaDataChanged) {
-            mEntryManager.updateNotifications();
+            getEntryManager().updateNotifications();
         }
         mPresenter.updateMediaMetaData(metaDataChanged, true);
     }
@@ -256,9 +335,9 @@
 
     private boolean isMediaNotification(NotificationData.Entry entry) {
         // TODO: confirm that there's a valid media key
-        return entry.getExpandedContentView() != null &&
-                entry.getExpandedContentView()
-                        .findViewById(com.android.internal.R.id.media_actions) != null;
+        return entry.row.getExpandedContentView() != null
+                && entry.row.getExpandedContentView().findViewById(
+                        com.android.internal.R.id.media_actions) != null;
     }
 
     private void clearCurrentMediaNotificationSession() {
@@ -272,4 +351,204 @@
         }
         mMediaController = null;
     }
+
+    /**
+     * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
+     */
+    public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
+        Trace.beginSection("StatusBar#updateMediaMetaData");
+        if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) {
+            Trace.endSection();
+            return;
+        }
+
+        if (mBackdrop == null) {
+            Trace.endSection();
+            return; // called too early
+        }
+
+        boolean wakeAndUnlock = mBiometricUnlockController != null
+            && mBiometricUnlockController.isWakeAndUnlock();
+        if (mKeyguardMonitor.isLaunchTransitionFadingAway() || wakeAndUnlock) {
+            mBackdrop.setVisibility(View.INVISIBLE);
+            Trace.endSection();
+            return;
+        }
+
+        MediaMetadata mediaMetadata = getMediaMetadata();
+
+        if (DEBUG_MEDIA) {
+            Log.v(TAG, "DEBUG_MEDIA: updating album art for notification "
+                    + getMediaNotificationKey()
+                    + " metadata=" + mediaMetadata
+                    + " metaDataChanged=" + metaDataChanged
+                    + " state=" + mStatusBarStateController.getState());
+        }
+
+        Drawable artworkDrawable = null;
+        if (mediaMetadata != null) {
+            Bitmap artworkBitmap = mediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
+            if (artworkBitmap == null) {
+                artworkBitmap = mediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
+                // might still be null
+            }
+            if (artworkBitmap != null) {
+                artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), artworkBitmap);
+            }
+        }
+        boolean allowWhenShade = false;
+        if (ENABLE_LOCKSCREEN_WALLPAPER && artworkDrawable == null) {
+            Bitmap lockWallpaper =
+                    mLockscreenWallpaper != null ? mLockscreenWallpaper.getBitmap() : null;
+            if (lockWallpaper != null) {
+                artworkDrawable = new LockscreenWallpaper.WallpaperDrawable(
+                        mBackdropBack.getResources(), lockWallpaper);
+                // We're in the SHADE mode on the SIM screen - yet we still need to show
+                // the lockscreen wallpaper in that mode.
+                allowWhenShade = mStatusBarStateController.getState() == KEYGUARD;
+            }
+        }
+
+        boolean hideBecauseOccluded = getShadeController() != null
+                && getShadeController().isOccluded();
+
+        final boolean hasArtwork = artworkDrawable != null;
+        mColorExtractor.setHasBackdrop(hasArtwork);
+        if (mScrimController != null) {
+            mScrimController.setHasBackdrop(hasArtwork);
+        }
+
+        if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
+                && (mStatusBarStateController.getState() != StatusBarState.SHADE || allowWhenShade)
+                &&  mBiometricUnlockController != null && mBiometricUnlockController.getMode()
+                        != BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
+                && !hideBecauseOccluded) {
+            // time to show some art!
+            if (mBackdrop.getVisibility() != View.VISIBLE) {
+                mBackdrop.setVisibility(View.VISIBLE);
+                if (allowEnterAnimation) {
+                    mBackdrop.setAlpha(0);
+                    mBackdrop.animate().alpha(1f);
+                } else {
+                    mBackdrop.animate().cancel();
+                    mBackdrop.setAlpha(1f);
+                }
+                if (getWindowController() != null) {
+                    getWindowController().setBackdropShowing(true);
+                }
+                metaDataChanged = true;
+                if (DEBUG_MEDIA) {
+                    Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
+                }
+            }
+            if (metaDataChanged) {
+                if (mBackdropBack.getDrawable() != null) {
+                    Drawable drawable =
+                            mBackdropBack.getDrawable().getConstantState()
+                                    .newDrawable(mBackdropFront.getResources()).mutate();
+                    mBackdropFront.setImageDrawable(drawable);
+                    mBackdropFront.setAlpha(1f);
+                    mBackdropFront.setVisibility(View.VISIBLE);
+                } else {
+                    mBackdropFront.setVisibility(View.INVISIBLE);
+                }
+
+                if (DEBUG_MEDIA_FAKE_ARTWORK) {
+                    final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
+                    Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
+                    mBackdropBack.setBackgroundColor(0xFFFFFFFF);
+                    mBackdropBack.setImageDrawable(new ColorDrawable(c));
+                } else {
+                    mBackdropBack.setImageDrawable(artworkDrawable);
+                }
+
+                if (mBackdropFront.getVisibility() == View.VISIBLE) {
+                    if (DEBUG_MEDIA) {
+                        Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
+                                + mBackdropFront.getDrawable()
+                                + " to "
+                                + mBackdropBack.getDrawable());
+                    }
+                    mBackdropFront.animate()
+                            .setDuration(250)
+                            .alpha(0f).withEndAction(mHideBackdropFront);
+                }
+            }
+        } else {
+            // need to hide the album art, either because we are unlocked, on AOD
+            // or because the metadata isn't there to support it
+            if (mBackdrop.getVisibility() != View.GONE) {
+                if (DEBUG_MEDIA) {
+                    Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
+                }
+                boolean cannotAnimateDoze = getShadeController() != null
+                        && getShadeController().isDozing()
+                        && !ScrimState.AOD.getAnimateChange();
+                if (mBiometricUnlockController != null && mBiometricUnlockController.getMode()
+                        == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
+                        || hideBecauseOccluded || cannotAnimateDoze) {
+
+                    // We are unlocking directly - no animation!
+                    mBackdrop.setVisibility(View.GONE);
+                    mBackdropBack.setImageDrawable(null);
+                    if (getWindowController() != null) {
+                        getWindowController().setBackdropShowing(false);
+                    }
+                } else {
+                    if (getWindowController() != null) {
+                        getWindowController().setBackdropShowing(false);
+                    }
+                    mBackdrop.animate()
+                            .alpha(0)
+                            .setInterpolator(Interpolators.ACCELERATE_DECELERATE)
+                            .setDuration(300)
+                            .setStartDelay(0)
+                            .withEndAction(() -> {
+                                mBackdrop.setVisibility(View.GONE);
+                                mBackdropFront.animate().cancel();
+                                mBackdropBack.setImageDrawable(null);
+                                mHandler.post(mHideBackdropFront);
+                            });
+                    if (mKeyguardMonitor.isKeyguardFadingAway()) {
+                        mBackdrop.animate()
+                                // Make it disappear faster, as the focus should be on the activity
+                                // behind.
+                                .setDuration(mKeyguardMonitor.getKeyguardFadingAwayDuration() / 2)
+                                .setStartDelay(mKeyguardMonitor.getKeyguardFadingAwayDelay())
+                                .setInterpolator(Interpolators.LINEAR)
+                                .start();
+                    }
+                }
+            }
+        }
+        Trace.endSection();
+    }
+
+    public void setup(BackDropView backdrop, ImageView backdropFront, ImageView backdropBack,
+            ScrimController scrimController, LockscreenWallpaper lockscreenWallpaper) {
+        mBackdrop = backdrop;
+        mBackdropFront = backdropFront;
+        mBackdropBack = backdropBack;
+        mScrimController = scrimController;
+        mLockscreenWallpaper = lockscreenWallpaper;
+    }
+
+    public void setBiometricUnlockController(BiometricUnlockController biometricUnlockController) {
+        mBiometricUnlockController = biometricUnlockController;
+    }
+
+    /**
+     * Hide the album artwork that is fading out and release its bitmap.
+     */
+    protected final Runnable mHideBackdropFront = new Runnable() {
+        @Override
+        public void run() {
+            if (DEBUG_MEDIA) {
+                Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
+            }
+            mBackdropFront.setVisibility(View.INVISIBLE);
+            mBackdropFront.animate().cancel();
+            mBackdropFront.setImageDrawable(null);
+        }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
index c58eb80..5c8f4cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationPresenter.java
@@ -19,6 +19,7 @@
 import android.os.Handler;
 import android.view.View;
 
+import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -31,9 +32,7 @@
  * for affecting the state of the system (e.g. starting an intent, given that the presenter may
  * want to perform some action before doing so).
  */
-public interface NotificationPresenter extends NotificationData.Environment,
-        NotificationRemoteInputManager.Callback,
-        ExpandableNotificationRow.OnExpandClickListener,
+public interface NotificationPresenter extends ExpandableNotificationRow.OnExpandClickListener,
         ActivatableNotificationView.OnActivatedListener,
         NotificationEntryManager.Callback {
     /**
@@ -43,59 +42,23 @@
     boolean isPresenterFullyCollapsed();
 
     /**
-     * Returns true if the presenter is locked. For example, if the keyguard is active.
-     */
-    boolean isPresenterLocked();
-
-    /**
      * Runs the given intent. The presenter may want to run some animations or close itself when
      * this happens.
      */
     void startNotificationGutsIntent(Intent intent, int appUid, ExpandableNotificationRow row);
 
     /**
-     * Returns the Handler for NotificationPresenter.
-     */
-    Handler getHandler();
-
-    /**
      * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
      */
     void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation);
 
     /**
-     * Called when the locked status of the device is changed for a work profile.
-     */
-    void onWorkChallengeChanged();
-
-    /**
      * Called when the current user changes.
      * @param newUserId new user id
      */
     void onUserSwitched(int newUserId);
 
     /**
-     * Gets the NotificationLockscreenUserManager for this Presenter.
-     */
-    NotificationLockscreenUserManager getNotificationLockscreenUserManager();
-
-    /**
-     * Wakes the device up if dozing.
-     *
-     * @param time the time when the request to wake up was issued
-     * @param where which view caused this wake up request
-     */
-    void wakeUpIfDozing(long time, View where);
-
-    /**
-     * True if the device currently requires a PIN, pattern, or password to unlock.
-     *
-     * @param userId user id to query about
-     * @return true iff the device is locked
-     */
-    boolean isDeviceLocked(int userId);
-
-    /**
      * @return true iff the device is in vr mode
      */
     boolean isDeviceInVrMode();
@@ -114,7 +77,36 @@
     int getMaxNotificationsWhileLocked(boolean recompute);
 
     /**
-     * Called when the row states are updated by NotificationViewHierarchyManager.
+     * True if the presenter
+     * @return
+     */
+    default boolean isPresenterLocked() { return false; }
+
+    /**
+     * Called when the row states are updated by {@link NotificationViewHierarchyManager}.
      */
     void onUpdateRowStates();
+
+    /**
+     * @return true if the shade is collapsing.
+     */
+    boolean isCollapsing();
+
+    /**
+     * @return true if the shade is collapsing to show an activity over the lock screen
+     */
+    default public boolean isCollapsingToShowActivityOverLockscreen() {
+        return false;
+    }
+
+    /**
+     * Get the {@link ActivityLaunchAnimator} from the presenter so it can be queried by
+     * {@link com.android.systemui.statusbar.phone.StatusBar}
+     * @return the current animator
+     * @deprecated This is only here for now because StatusBar is still the ActivityLaunchAnimator
+     * callback but shouldn't be.
+     */
+    default public ActivityLaunchAnimator getActivityLaunchAnimator() {
+        return null;
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index ea7e03e..f30377e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -20,6 +20,7 @@
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
+import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.RemoteInput;
@@ -46,9 +47,11 @@
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.InitController;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.policy.RemoteInputView;
 
 import java.io.FileDescriptor;
@@ -97,13 +100,18 @@
             Dependency.get(NotificationLockscreenUserManager.class);
     protected final SmartReplyController mSmartReplyController =
             Dependency.get(SmartReplyController.class);
+    private final NotificationEntryManager mEntryManager
+            = Dependency.get(NotificationEntryManager.class);
+
+    // Lazy
+    private ShadeController mShadeController;
 
     protected final Context mContext;
     private final UserManager mUserManager;
+    private final KeyguardManager mKeyguardManager;
 
     protected RemoteInputController mRemoteInputController;
     protected NotificationPresenter mPresenter;
-    protected NotificationEntryManager mEntryManager;
     protected NotificationLifetimeExtender.NotificationSafeToRemoveCallback
             mNotificationLifetimeFinishedCallback;
     protected IStatusBarService mBarService;
@@ -115,7 +123,7 @@
         @Override
         public boolean onClickHandler(
                 final View view, final PendingIntent pendingIntent, final Intent fillInIntent) {
-            mPresenter.wakeUpIfDozing(SystemClock.uptimeMillis(), view);
+            getShadeController().wakeUpIfDozing(SystemClock.uptimeMillis(), view);
 
             if (handleRemoteInput(view, pendingIntent)) {
                 return true;
@@ -240,7 +248,7 @@
                     return true;
                 }
                 if (mUserManager.getUserInfo(userId).isManagedProfile()
-                        && mPresenter.isDeviceLocked(userId)) {
+                        && mKeyguardManager.isDeviceLocked(userId)) {
                     mCallback.onLockedWorkRemoteInput(userId, row, view);
                     return true;
                 }
@@ -291,20 +299,26 @@
         }
     };
 
+    private ShadeController getShadeController() {
+        if (mShadeController == null) {
+            mShadeController = Dependency.get(ShadeController.class);
+        }
+        return mShadeController;
+    }
+
     public NotificationRemoteInputManager(Context context) {
         mContext = context;
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         addLifetimeExtenders();
+        mKeyguardManager = context.getSystemService(KeyguardManager.class);
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
-            NotificationEntryManager entryManager,
             Callback callback,
             RemoteInputController.Delegate delegate) {
         mPresenter = presenter;
-        mEntryManager = entryManager;
         mCallback = callback;
         mRemoteInputController = new RemoteInputController(delegate);
         mRemoteInputController.addCallback(new RemoteInputController.Callback() {
@@ -318,7 +332,7 @@
                     // view it is already canceled, so we'll need to cancel it on the apps behalf
                     // after sending - unless the app posts an update in the mean time, so wait a
                     // bit.
-                    mPresenter.getHandler().postDelayed(() -> {
+                    Dependency.get(Dependency.MAIN_HANDLER).postDelayed(() -> {
                         if (mEntriesKeptForRemoteInputActive.remove(entry)) {
                             mNotificationLifetimeFinishedCallback.onSafeToRemove(entry.key);
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index d8f7b61..cd3da123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -34,6 +34,7 @@
 import android.view.WindowInsets;
 import android.view.accessibility.AccessibilityNodeInfo;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
@@ -103,7 +104,8 @@
     }
 
     @Override
-    protected void onFinishInflate() {
+    @VisibleForTesting
+    public void onFinishInflate() {
         super.onFinishInflate();
         mShelfIcons = findViewById(R.id.content);
         mShelfIcons.setClipChildren(false);
@@ -436,7 +438,9 @@
                         public boolean onPreDraw() {
                             boolean animatingY = ViewState.isAnimatingY(icon);
                             if (!animatingY) {
-                                observer.removeOnPreDrawListener(this);
+                                if (observer.isAlive()) {
+                                    observer.removeOnPreDrawListener(this);
+                                }
                                 icon.setTag(TAG_CONTINUOUS_CLIPPING, null);
                                 return true;
                             }
@@ -453,7 +457,9 @@
                 @Override
                 public void onViewDetachedFromWindow(View v) {
                     if (v == icon) {
-                        observer.removeOnPreDrawListener(predrawListener);
+                        if (observer.isAlive()) {
+                            observer.removeOnPreDrawListener(predrawListener);
+                        }
                         icon.setTag(TAG_CONTINUOUS_CLIPPING, null);
                     }
                 }
@@ -789,7 +795,7 @@
     private void setOpenedAmount(float openedAmount) {
         mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f;
         mOpenedAmount = openedAmount;
-        if (!mAmbientState.isPanelFullWidth()) {
+        if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDark()) {
             // We don't do a transformation at all, lets just assume we are fully opened
             openedAmount = 1.0f;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index f69ad43..92765bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -24,6 +24,7 @@
 import android.view.ViewGroup;
 
 import com.android.systemui.Dependency;
+import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -31,6 +32,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ShadeController;
 
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -57,6 +59,13 @@
             Dependency.get(NotificationGroupManager.class);
     protected final VisualStabilityManager mVisualStabilityManager =
             Dependency.get(VisualStabilityManager.class);
+    private final StatusBarStateController mStatusBarStateController =
+            Dependency.get(StatusBarStateController.class);
+    private final NotificationEntryManager mEntryManager =
+            Dependency.get(NotificationEntryManager.class);
+
+    // Lazy
+    private ShadeController mShadeController;
 
     /**
      * {@code true} if notifications not part of a group should by default be rendered in their
@@ -66,9 +75,15 @@
     private final boolean mAlwaysExpandNonGroupedNotification;
 
     private NotificationPresenter mPresenter;
-    private NotificationEntryManager mEntryManager;
     private NotificationListContainer mListContainer;
 
+    private ShadeController getShadeController() {
+        if (mShadeController == null) {
+            mShadeController = Dependency.get(ShadeController.class);
+        }
+        return mShadeController;
+    }
+
     public NotificationViewHierarchyManager(Context context) {
         Resources res = context.getResources();
         mAlwaysExpandNonGroupedNotification =
@@ -76,9 +91,8 @@
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
-            NotificationEntryManager entryManager, NotificationListContainer listContainer) {
+            NotificationListContainer listContainer) {
         mPresenter = presenter;
-        mEntryManager = entryManager;
         mListContainer = listContainer;
     }
 
@@ -291,9 +305,9 @@
         final int N = mListContainer.getContainerChildCount();
 
         int visibleNotifications = 0;
-        boolean isLocked = mPresenter.isPresenterLocked();
+        boolean onKeyguard = mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
         int maxNotifications = -1;
-        if (isLocked) {
+        if (onKeyguard) {
             maxNotifications = mPresenter.getMaxNotificationsWhileLocked(true /* recompute */);
         }
         mListContainer.setMaxDisplayedNotifications(maxNotifications);
@@ -311,9 +325,9 @@
             boolean isChildNotification =
                     mGroupManager.isChildInGroupWithSummary(entry.notification);
 
-            row.setOnKeyguard(isLocked);
+            row.setOnKeyguard(onKeyguard);
 
-            if (!isLocked) {
+            if (!onKeyguard) {
                 // If mAlwaysExpandNonGroupedNotification is false, then only expand the
                 // very first notification and if it's not a child of grouped notifications.
                 row.setSystemExpanded(mAlwaysExpandNonGroupedNotification
@@ -321,15 +335,26 @@
                         && !row.isLowPriority()));
             }
 
-            entry.row.setOnAmbient(mPresenter.isDozing());
+            entry.row.setOnAmbient(getShadeController().isDozing());
             int userId = entry.notification.getUserId();
             boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
                     entry.notification) && !entry.row.isRemoved();
             boolean showOnKeyguard = mLockscreenUserManager.shouldShowOnKeyguard(entry
                     .notification);
+            if (!showOnKeyguard) {
+                // min priority notifications should show if their summary is showing
+                if (mGroupManager.isChildInGroupWithSummary(entry.notification)) {
+                    ExpandableNotificationRow summary = mGroupManager.getLogicalGroupSummary(
+                            entry.notification);
+                    if (summary != null && mLockscreenUserManager.shouldShowOnKeyguard(
+                            summary.getStatusBarNotification()))         {
+                        showOnKeyguard = true;
+                    }
+                }
+            }
             if (suppressedSummary
                     || mLockscreenUserManager.shouldHideNotifications(userId)
-                    || (isLocked && !showOnKeyguard)) {
+                    || (onKeyguard && !showOnKeyguard)) {
                 entry.row.setVisibility(View.GONE);
             } else {
                 boolean wasGone = entry.row.getVisibility() == View.GONE;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index cc5fbe5..1e04377 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -38,7 +38,6 @@
 import android.os.Parcelable;
 import android.os.UserHandle;
 import android.service.notification.StatusBarNotification;
-import androidx.core.graphics.ColorUtils;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
@@ -49,6 +48,8 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Interpolator;
 
+import androidx.core.graphics.ColorUtils;
+
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.Interpolators;
@@ -121,6 +122,7 @@
     private StatusBarNotification mNotification;
     private final boolean mBlocked;
     private int mDensity;
+    private boolean mNightMode;
     private float mIconScale = 1.0f;
     private final Paint mDotPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     private float mDotRadius;
@@ -171,10 +173,10 @@
         setNotification(sbn);
         setScaleType(ScaleType.CENTER);
         mDensity = context.getResources().getDisplayMetrics().densityDpi;
-        if (mNotification != null) {
-            setDecorColor(getContext().getColor(
-                    com.android.internal.R.color.notification_default_color_light));
-        }
+        Configuration configuration = context.getResources().getConfiguration();
+        mNightMode = (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+                == Configuration.UI_MODE_NIGHT_YES;
+        initializeDecorColor();
         reloadDimens();
         maybeUpdateIconScaleDimens();
     }
@@ -222,6 +224,12 @@
             maybeUpdateIconScaleDimens();
             updateDrawable();
         }
+        boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK)
+                == Configuration.UI_MODE_NIGHT_YES;
+        if (nightMode != mNightMode) {
+            mNightMode = nightMode;
+            initializeDecorColor();
+        }
     }
 
     private void reloadDimens() {
@@ -540,6 +548,14 @@
         updateDecorColor();
     }
 
+    private void initializeDecorColor() {
+        if (mNotification != null) {
+            setDecorColor(getContext().getColor(mNightMode
+                    ? com.android.internal.R.color.notification_default_color_dark
+                    : com.android.internal.R.color.notification_default_color_light));
+        }
+    }
+
     private void updateDecorColor() {
         int color = NotificationUtils.interpolateColors(mDecorColor, Color.WHITE, mDarkAmount);
         if (mDotPaint.getColor() != color) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
index d6719f0..12c0fcb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateController.java
@@ -22,6 +22,7 @@
 import android.util.ArraySet;
 import android.util.Log;
 import com.android.internal.annotations.GuardedBy;
+import com.android.systemui.statusbar.phone.StatusBar;
 import java.lang.annotation.Retention;
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -39,9 +40,11 @@
             = (o1, o2) -> Integer.compare(o1.rank, o2.rank);
 
     private final ArrayList<RankedListener> mListeners = new ArrayList<>();
+    private boolean mIsDozing;
     private int mState;
     private int mLastState;
     private boolean mLeaveOpenOnKeyguardHide;
+    private boolean mKeyguardRequested;
 
     // TODO: b/115739177 (remove this explicit ordering if we can)
     @Retention(SOURCE)
@@ -57,6 +60,11 @@
         return mState;
     }
 
+    /**
+     * Update the status bar state
+     * @param state see {@link StatusBarState} for valid options
+     * @return {@code true} if the state changed, else {@code false}
+     */
     public boolean setState(int state) {
         if (state > MAX_STATE || state < MIN_STATE) {
             throw new IllegalArgumentException("Invalid state " + state);
@@ -82,6 +90,32 @@
         return true;
     }
 
+    public boolean isDozing() {
+        return mIsDozing;
+    }
+
+    /**
+     * Update the dozing state from {@link StatusBar}'s perspective
+     * @param isDozing well, are we dozing?
+     * @return {@code true} if the state changed, else {@code false}
+     */
+    @SuppressWarnings("UnusedReturnValue")
+    public boolean setIsDozing(boolean isDozing) {
+        if (mIsDozing == isDozing) {
+            return false;
+        }
+
+        mIsDozing = isDozing;
+
+        synchronized (mListeners) {
+            for (RankedListener rl : new ArrayList<>(mListeners)) {
+                rl.listener.onDozingChanged(isDozing);
+            }
+        }
+
+        return true;
+    }
+
     public boolean goingToFullShade() {
         return mState == StatusBarState.SHADE && mLeaveOpenOnKeyguardHide;
     }
@@ -140,18 +174,16 @@
         }
     }
 
-    public static String describe(int state) {
-        return StatusBarState.toShortString(state);
+    public void setKeyguardRequested(boolean keyguardRequested) {
+        mKeyguardRequested = keyguardRequested;
     }
 
-    public interface StateListener {
-        public default void onStatePreChange(int oldState, int newState) {
-        }
+    public boolean isKeyguardRequested() {
+        return mKeyguardRequested;
+    }
 
-        public default void onStatePostChange() {
-        }
-
-        public void onStateChanged(int newState);
+    public static String describe(int state) {
+        return StatusBarState.toShortString(state);
     }
 
     private class RankedListener {
@@ -163,4 +195,40 @@
             rank = r;
         }
     }
+
+    /**
+     * Listener for StatusBarState updates
+     */
+    public interface StateListener {
+
+        /**
+         * Callback before the new state is applied, for those who need to preempt the change
+         * @param oldState state before the change
+         * @param newState new state to be applied in {@link #onStateChanged}
+         */
+        public default void onStatePreChange(int oldState, int newState) {
+        }
+
+        /**
+         * Callback after all listeners have had a chance to update based on the state change
+         */
+        public default void onStatePostChange() {
+        }
+
+        /**
+         * Required callback. Get the new state and do what you will with it. Keep in mind that
+         * other listeners are typically unordered and don't rely on your work being done before
+         * other peers
+         *
+         * Only called if the state is actually different
+         * @param newState the new {@link StatusBarState}
+         */
+        public void onStateChanged(int newState);
+
+        /**
+         * Callback to be notified when Dozing changes. Dozing is stored separately from state.
+         * @param isDozing {@code true} if dozing according to {@link StatusBar}
+         */
+        public default void onDozingChanged(boolean isDozing) {}
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 2450e44..8799341 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -491,6 +491,10 @@
     @Override
     public void onStateChanged(int newState) {
         super.onStateChanged(newState);
+        if (mFullscreenUserSwitcher == null) {
+            return; // Not using the full screen user switcher.
+        }
+
         if (newState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
             if (!mFullscreenUserSwitcher.isVisible()) {
                 // Current execution path continues to set state after this, thus we deffer the
@@ -521,12 +525,6 @@
     }
 
     @Override
-    public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
-        // Do nothing, we don't want to display media art in the lock screen for a car.
-    }
-
-
-    @Override
     public void animateExpandNotificationsPanel() {
         // Because space is usually constrained in the auto use-case, there should not be a
         // pinned notification when the shade has been expanded. Ensure this by removing all heads-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AppOpsListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AppOpsListener.java
index 8cae806..9e99fbb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/AppOpsListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/AppOpsListener.java
@@ -33,10 +33,11 @@
     // Dependencies:
     private final ForegroundServiceController mFsc =
             Dependency.get(ForegroundServiceController.class);
+    private final NotificationEntryManager mEntryManager =
+            Dependency.get(NotificationEntryManager.class);
 
     private final Context mContext;
     protected NotificationPresenter mPresenter;
-    protected NotificationEntryManager mEntryManager;
     protected final AppOpsManager mAppOps;
 
     protected static final int[] OPS = new int[] {AppOpsManager.OP_CAMERA,
@@ -48,10 +49,8 @@
         mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
     }
 
-    public void setUpWithPresenter(NotificationPresenter presenter,
-            NotificationEntryManager entryManager) {
+    public void setUpWithPresenter(NotificationPresenter presenter) {
         mPresenter = presenter;
-        mEntryManager = entryManager;
         mAppOps.startWatchingActive(OPS, this);
     }
 
@@ -62,7 +61,7 @@
     @Override
     public void onOpActiveChanged(int code, int uid, String packageName, boolean active) {
         mFsc.onAppOpChanged(code, uid, packageName, active);
-        mPresenter.getHandler().post(() -> {
+        Dependency.get(Dependency.MAIN_HANDLER).post(() -> {
           mEntryManager.updateNotificationsForAppOp(code, uid, packageName, active);
         });
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
index d097c8e..3539fff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationData.java
@@ -50,9 +50,6 @@
 import android.util.ArraySet;
 import android.view.View;
 import android.widget.ImageView;
-import android.widget.RemoteViews;
-
-import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.StatusBarIcon;
@@ -60,13 +57,16 @@
 import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.Dependency;
 import com.android.systemui.ForegroundServiceController;
+import com.android.systemui.InitController;
 import com.android.systemui.statusbar.InflationTask;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.ZenModeController;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -75,16 +75,23 @@
 import java.util.List;
 import java.util.Objects;
 
+import androidx.annotation.Nullable;
+
 /**
  * The list of currently displaying notifications.
  */
 public class NotificationData {
 
-    private final Environment mEnvironment;
-    private HeadsUpManager mHeadsUpManager;
+    /**
+     * These dependencies are late init-ed
+     */
+    private KeyguardEnvironment mEnvironment;
+    private ShadeController mShadeController;
+    private NotificationMediaManager mMediaManager;
+    private ForegroundServiceController mFsc;
+    private NotificationLockscreenUserManager mUserManager;
 
-    final ZenModeController mZen = Dependency.get(ZenModeController.class);
-    final ForegroundServiceController mFsc = Dependency.get(ForegroundServiceController.class);
+    private HeadsUpManager mHeadsUpManager;
 
     public static final class Entry {
         private static final long LAUNCH_COOLDOWN = 2000;
@@ -102,11 +109,6 @@
         public boolean autoRedacted; // whether the redacted notification was generated by us
         public int targetSdk;
         private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
-        public RemoteViews cachedContentView;
-        public RemoteViews cachedBigContentView;
-        public RemoteViews cachedHeadsUpContentView;
-        public RemoteViews cachedPublicContentView;
-        public RemoteViews cachedAmbientContentView;
         public CharSequence remoteInputText;
         public List<SnoozeCriterion> snoozeCriteria;
         public int userSentiment = Ranking.USER_SENTIMENT_NEUTRAL;
@@ -178,14 +180,6 @@
             }
         }
 
-        public View getExpandedContentView() {
-            return row.getPrivateLayout().getExpandedChild();
-        }
-
-        public View getPublicContentView() {
-            return row.getPublicLayout().getContractedChild();
-        }
-
         public void notifyFullScreenIntentLaunched() {
             setInterruption();
             lastFullScreenIntentLaunchTime = SystemClock.elapsedRealtime();
@@ -389,7 +383,8 @@
     private final ArrayList<Entry> mSortedAndFiltered = new ArrayList<>();
     private final ArrayList<Entry> mFilteredForUser = new ArrayList<>();
 
-    private NotificationGroupManager mGroupManager;
+    private final NotificationGroupManager mGroupManager
+            = Dependency.get(NotificationGroupManager.class);
 
     private RankingMap mRankingMap;
     private final Ranking mTmpRanking = new Ranking();
@@ -421,7 +416,7 @@
                 bRank = mRankingB.getRank();
             }
 
-            String mediaNotification = mEnvironment.getCurrentMediaNotificationKey();
+            String mediaNotification = getMediaManager().getMediaNotificationKey();
 
             // IMPORTANCE_MIN media streams are allowed to drift to the bottom
             final boolean aMedia = a.key.equals(mediaNotification)
@@ -456,13 +451,43 @@
         }
     };
 
-    public NotificationData(Environment environment) {
-        mEnvironment = environment;
-        mGroupManager = environment.getGroupManager();
+    private KeyguardEnvironment getEnvironment() {
+        if (mEnvironment == null) {
+            mEnvironment = Dependency.get(KeyguardEnvironment.class);
+        }
+        return mEnvironment;
+    }
+
+    private ShadeController getShadeController() {
+        if (mShadeController == null) {
+            mShadeController = Dependency.get(ShadeController.class);
+        }
+        return mShadeController;
+    }
+
+    private NotificationMediaManager getMediaManager() {
+        if (mMediaManager == null) {
+            mMediaManager = Dependency.get(NotificationMediaManager.class);
+        }
+        return mMediaManager;
+    }
+
+    private ForegroundServiceController getFsc() {
+        if (mFsc == null) {
+            mFsc = Dependency.get(ForegroundServiceController.class);
+        }
+        return mFsc;
+    }
+
+    private NotificationLockscreenUserManager getUserManager() {
+        if (mUserManager == null) {
+            mUserManager = Dependency.get(NotificationLockscreenUserManager.class);
+        }
+        return mUserManager;
     }
 
     /**
-     * Returns the sorted list of active notifications (depending on {@link Environment}
+     * Returns the sorted list of active notifications (depending on {@link KeyguardEnvironment}
      *
      * <p>
      * This call doesn't update the list of active notifications. Call {@link #filterAndSort()}
@@ -482,7 +507,7 @@
             for (int i = 0; i < N; i++) {
                 Entry entry = mEntries.valueAt(i);
                 final StatusBarNotification sbn = entry.notification;
-                if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) {
+                if (!getEnvironment().isNotificationForCurrentProfiles(sbn)) {
                     continue;
                 }
                 mFilteredForUser.add(entry);
@@ -733,27 +758,27 @@
      */
     public boolean shouldFilterOut(Entry entry) {
         final StatusBarNotification sbn = entry.notification;
-        if (!(mEnvironment.isDeviceProvisioned() ||
+        if (!(getEnvironment().isDeviceProvisioned() ||
                 showNotificationEvenIfUnprovisioned(sbn))) {
             return true;
         }
 
-        if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) {
+        if (!getEnvironment().isNotificationForCurrentProfiles(sbn)) {
             return true;
         }
 
-        if (mEnvironment.isSecurelyLocked(sbn.getUserId()) &&
+        if (getUserManager().isLockscreenPublicMode(sbn.getUserId()) &&
                 (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET
-                        || mEnvironment.shouldHideNotifications(sbn.getUserId())
-                        || mEnvironment.shouldHideNotifications(sbn.getKey()))) {
+                        || getUserManager().shouldHideNotifications(sbn.getUserId())
+                        || getUserManager().shouldHideNotifications(sbn.getKey()))) {
             return true;
         }
 
-        if (mEnvironment.isDozing() && shouldSuppressAmbient(entry)) {
+        if (getShadeController().isDozing() && shouldSuppressAmbient(entry)) {
             return true;
         }
 
-        if (!mEnvironment.isDozing() && shouldSuppressNotificationList(entry)) {
+        if (!getShadeController().isDozing() && shouldSuppressNotificationList(entry)) {
             return true;
         }
 
@@ -766,15 +791,16 @@
             return true;
         }
 
-        if (mFsc.isDungeonNotification(sbn) && !mFsc.isDungeonNeededForUser(sbn.getUserId())) {
+        if (getFsc().isDungeonNotification(sbn)
+                && !getFsc().isDungeonNeededForUser(sbn.getUserId())) {
             // this is a foreground-service disclosure for a user that does not need to show one
             return true;
         }
-        if (mFsc.isSystemAlertNotification(sbn)) {
+        if (getFsc().isSystemAlertNotification(sbn)) {
             final String[] apps = sbn.getNotification().extras.getStringArray(
                     Notification.EXTRA_FOREGROUND_APPS);
             if (apps != null && apps.length >= 1) {
-                if (!mFsc.isSystemAlertWarningNeeded(sbn.getUserId(), apps[0])) {
+                if (!getFsc().isSystemAlertWarningNeeded(sbn.getUserId(), apps[0])) {
                     return true;
                 }
             }
@@ -852,18 +878,8 @@
     /**
      * Provides access to keyguard state and user settings dependent data.
      */
-    public interface Environment {
-        public boolean isSecurelyLocked(int userId);
-        public boolean shouldHideNotifications(int userid);
-        public boolean shouldHideNotifications(String key);
-        public boolean isDeviceProvisioned();
-        public boolean isNotificationForCurrentProfiles(StatusBarNotification sbn);
-        public String getCurrentMediaNotificationKey();
-        public NotificationGroupManager getGroupManager();
-
-        /**
-         * @return true iff the device is dozing
-         */
-        boolean isDozing();
+    public interface KeyguardEnvironment {
+        boolean isDeviceProvisioned();
+        boolean isNotificationForCurrentProfiles(StatusBarNotification sbn);
     }
 }
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 a3e982e..3bea7db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -16,8 +16,9 @@
 package com.android.systemui.statusbar.notification;
 
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
-import static com.android.systemui.statusbar.NotificationRemoteInputManager
-        .FORCE_REMOTE_INPUT_HISTORY;
+import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
 
 import android.annotation.Nullable;
 import android.app.Notification;
@@ -58,11 +59,12 @@
 import com.android.systemui.Dumpable;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.ForegroundServiceController;
+import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.UiOffloadThread;
-import com.android.systemui.statusbar.NotificationLifetimeExtender;
 import com.android.systemui.statusbar.AlertingNotificationManager;
 import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.statusbar.NotificationLifetimeExtender;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationMediaManager;
@@ -70,12 +72,15 @@
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationUiAdjustment;
 import com.android.systemui.statusbar.NotificationUpdateHandler;
-import com.android.systemui.statusbar.notification.row.NotificationInflater;
-import com.android.systemui.statusbar.notification.row.RowInflaterTask;
+import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.row.NotificationInflater;
+import com.android.systemui.statusbar.notification.row.NotificationInflater.InflationFlag;
+import com.android.systemui.statusbar.notification.row.RowInflaterTask;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -105,33 +110,31 @@
     protected final HashMap<String, NotificationData.Entry> mPendingNotifications = new HashMap<>();
     protected final NotificationClicker mNotificationClicker = new NotificationClicker();
 
-    // Dependencies:
-    protected final NotificationLockscreenUserManager mLockscreenUserManager =
-            Dependency.get(NotificationLockscreenUserManager.class);
-    protected final NotificationGroupManager mGroupManager =
+    private final NotificationGroupManager mGroupManager =
             Dependency.get(NotificationGroupManager.class);
-    protected final NotificationGutsManager mGutsManager =
+    private final NotificationGutsManager mGutsManager =
             Dependency.get(NotificationGutsManager.class);
-    protected final NotificationRemoteInputManager mRemoteInputManager =
-            Dependency.get(NotificationRemoteInputManager.class);
-    protected final NotificationMediaManager mMediaManager =
-            Dependency.get(NotificationMediaManager.class);
-    protected final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
-    protected final DeviceProvisionedController mDeviceProvisionedController =
+    private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
+    private final DeviceProvisionedController mDeviceProvisionedController =
             Dependency.get(DeviceProvisionedController.class);
-    protected final VisualStabilityManager mVisualStabilityManager =
+    private final VisualStabilityManager mVisualStabilityManager =
             Dependency.get(VisualStabilityManager.class);
-    protected final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
-    protected final ForegroundServiceController mForegroundServiceController =
+    private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
+    private final ForegroundServiceController mForegroundServiceController =
             Dependency.get(ForegroundServiceController.class);
-    protected final NotificationListener mNotificationListener =
-            Dependency.get(NotificationListener.class);
-    protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
+    private final AmbientPulseManager mAmbientPulseManager =
+            Dependency.get(AmbientPulseManager.class);
+
+    // Lazily retrieved dependencies
+    private NotificationRemoteInputManager mRemoteInputManager;
+    private NotificationMediaManager mMediaManager;
+    private NotificationListener mNotificationListener;
+    private ShadeController mShadeController;
 
     protected IDreamManager mDreamManager;
     protected IStatusBarService mBarService;
-    protected NotificationPresenter mPresenter;
-    protected Callback mCallback;
+    private NotificationPresenter mPresenter;
+    private Callback mCallback;
     protected PowerManager mPowerManager;
     protected NotificationListenerService.RankingMap mLatestRankingMap;
     protected HeadsUpManager mHeadsUpManager;
@@ -144,7 +147,6 @@
             = new ArrayList<>();
     private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener;
 
-
     private final class NotificationClicker implements View.OnClickListener {
 
         @Override
@@ -154,7 +156,7 @@
                 return;
             }
 
-            mPresenter.wakeUpIfDozing(SystemClock.uptimeMillis(), v);
+            getShadeController().wakeUpIfDozing(SystemClock.uptimeMillis(), v);
 
             final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
             final StatusBarNotification sbn = row.getStatusBarNotification();
@@ -227,20 +229,55 @@
         mDreamManager = IDreamManager.Stub.asInterface(
                 ServiceManager.checkService(DreamService.DREAM_SERVICE));
         mMessagingUtil = new NotificationMessagingUtil(context);
+        mNotificationData = new NotificationData();
+        Dependency.get(InitController.class).addPostInitTask(this::onPostInit);
+    }
+
+    private void onPostInit() {
         mGroupManager.setPendingEntries(mPendingNotifications);
     }
 
+    /**
+     * Our dependencies can have cyclic references, so some need to be lazy
+     */
+    private NotificationRemoteInputManager getRemoteInputManager() {
+        if (mRemoteInputManager == null) {
+            mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);
+        }
+        return mRemoteInputManager;
+    }
+
+    private NotificationMediaManager getMediaManager() {
+        if (mMediaManager == null) {
+            mMediaManager = Dependency.get(NotificationMediaManager.class);
+        }
+        return mMediaManager;
+    }
+
+    private NotificationListener getNotificationListener() {
+        if (mNotificationListener == null) {
+            mNotificationListener = Dependency.get(NotificationListener.class);
+        }
+        return mNotificationListener;
+    }
+
+    private ShadeController getShadeController() {
+        if (mShadeController == null) {
+            mShadeController = Dependency.get(ShadeController.class);
+        }
+        return mShadeController;
+    }
+
     public void setUpWithPresenter(NotificationPresenter presenter,
             NotificationListContainer listContainer, Callback callback,
             HeadsUpManager headsUpManager) {
         mPresenter = presenter;
         mCallback = callback;
-        mNotificationData = new NotificationData(presenter);
         mHeadsUpManager = headsUpManager;
         mNotificationData.setHeadsUpManager(mHeadsUpManager);
         mListContainer = listContainer;
 
-        mHeadsUpObserver = new ContentObserver(mPresenter.getHandler()) {
+        mHeadsUpObserver = new ContentObserver(Dependency.get(Dependency.MAIN_HANDLER)) {
             @Override
             public void onChange(boolean selfChange) {
                 boolean wasUsing = mUseHeadsUp;
@@ -273,7 +310,7 @@
         mNotificationLifetimeExtenders.add(mHeadsUpManager);
         mNotificationLifetimeExtenders.add(mAmbientPulseManager);
         mNotificationLifetimeExtenders.add(mGutsManager);
-        mNotificationLifetimeExtenders.addAll(mRemoteInputManager.getLifetimeExtenders());
+        mNotificationLifetimeExtenders.addAll(getRemoteInputManager().getLifetimeExtenders());
 
         for (NotificationLifetimeExtender extender : mNotificationLifetimeExtenders) {
             extender.setCallback(key -> removeNotification(key, mLatestRankingMap));
@@ -289,6 +326,14 @@
         return mNotificationData;
     }
 
+    protected Context getContext() {
+        return mContext;
+    }
+
+    protected NotificationPresenter getPresenter() {
+        return mPresenter;
+    }
+
     public ExpandableNotificationRow.LongPressListener getNotificationLongClicker() {
         return mGutsManager::openGuts;
     }
@@ -343,7 +388,7 @@
         row.setInflationCallback(this);
         row.setLongPressListener(getNotificationLongClicker());
         mListContainer.bindRow(row);
-        mRemoteInputManager.bindRow(row);
+        getRemoteInputManager().bindRow(row);
 
         // Get the app name.
         // Note that Notification.Builder#bindHeaderAppName has similar logic
@@ -382,7 +427,7 @@
                 true);
         NotificationData.Entry entry = mNotificationData.get(n.getKey());
 
-        mRemoteInputManager.onPerformRemoveNotification(n, entry);
+        getRemoteInputManager().onPerformRemoveNotification(n, entry);
         final String pkg = n.getPackageName();
         final String tag = n.getTag();
         final int id = n.getId();
@@ -440,25 +485,48 @@
     }
 
     private void addEntry(NotificationData.Entry shadeEntry) {
-        if (shouldHeadsUp(shadeEntry)) {
-            mHeadsUpManager.showNotification(shadeEntry);
-            // Mark as seen immediately
-            setNotificationShown(shadeEntry.notification);
-        }
-        if (shouldPulse(shadeEntry)) {
-            mAmbientPulseManager.showNotification(shadeEntry);
-        }
         addNotificationViews(shadeEntry);
         mCallback.onNotificationAdded(shadeEntry);
     }
 
+    /**
+     * Adds the entry to the respective alerting manager if the content view was inflated and
+     * the entry should still alert.
+     *
+     * @param entry entry to add
+     * @param inflatedFlags flags representing content views that were inflated
+     */
+    private void showAlertingView(NotificationData.Entry entry,
+            @InflationFlag int inflatedFlags) {
+        if ((inflatedFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) {
+            // Possible for shouldHeadsUp to change between the inflation starting and ending.
+            // If it does and we no longer need to heads up, we should free the view.
+            if (shouldHeadsUp(entry)) {
+                mHeadsUpManager.showNotification(entry);
+                // Mark as seen immediately
+                setNotificationShown(entry.notification);
+            } else {
+                entry.row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
+            }
+        }
+        if ((inflatedFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
+            if (shouldPulse(entry)) {
+                mAmbientPulseManager.showNotification(entry);
+            } else {
+                entry.row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
+            }
+        }
+    }
+
     @Override
-    public void onAsyncInflationFinished(NotificationData.Entry entry) {
+    public void onAsyncInflationFinished(NotificationData.Entry entry,
+            @InflationFlag int inflatedFlags) {
         mPendingNotifications.remove(entry.key);
         // If there was an async task started after the removal, we don't want to add it back to
         // the list, otherwise we might get leaks.
         boolean isNew = mNotificationData.get(entry.key) == null;
         if (isNew && !entry.row.isRemoved()) {
+            showAlertingView(entry, inflatedFlags);
             addEntry(entry);
         } else if (!isNew && entry.row.hasLowPriorityStateUpdated()) {
             mVisualStabilityManager.onLowPriorityUpdated(entry);
@@ -484,7 +552,7 @@
             // sending look longer than it takes.
             // Also we should not defer the removal if reordering isn't allowed since otherwise
             // some notifications can't disappear before the panel is closed.
-            boolean ignoreEarliestRemovalTime = mRemoteInputManager.getController().isSpinning(key)
+            boolean ignoreEarliestRemovalTime = getRemoteInputManager().getController().isSpinning(key)
                     && !FORCE_REMOTE_INPUT_HISTORY
                     || !mVisualStabilityManager.isReorderingAllowed();
             mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
@@ -519,7 +587,7 @@
             extender.setShouldManageLifetime(entry, false /* shouldManage */);
         }
 
-        mMediaManager.onNotificationRemoved(key);
+        getMediaManager().onNotificationRemoved(key);
         mForegroundServiceController.removeNotification(entry.notification);
 
         if (entry.row != null) {
@@ -574,8 +642,8 @@
                 boolean isForeground = (row.getStatusBarNotification().getNotification().flags
                         & Notification.FLAG_FOREGROUND_SERVICE) != 0;
                 boolean keepForReply =
-                        mRemoteInputManager.shouldKeepForRemoteInputHistory(childEntry)
-                        || mRemoteInputManager.shouldKeepForSmartReplyHistory(childEntry);
+                        getRemoteInputManager().shouldKeepForRemoteInputHistory(childEntry)
+                        || getRemoteInputManager().shouldKeepForSmartReplyHistory(childEntry);
                 if (isForeground || keepForReply) {
                     // the child is a foreground service notification which we can't remove or it's
                     // a child we're keeping around for reply!
@@ -605,7 +673,6 @@
 
     protected void updateNotification(NotificationData.Entry entry, PackageManager pmUser,
             StatusBarNotification sbn, ExpandableNotificationRow row) {
-        row.setNeedsRedaction(mLockscreenUserManager.needsRedaction(entry));
         boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
         boolean isUpdate = mNotificationData.get(entry.key) != null;
         boolean wasLowPriority = row.isLowPriority();
@@ -636,7 +703,13 @@
         row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
         row.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp);
         row.setSmartActions(entry.smartActions);
-        row.updateNotification(entry);
+        row.setEntry(entry);
+
+        row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, shouldHeadsUp(entry));
+        row.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, shouldPulse(entry));
+        row.setNeedsRedaction(
+                Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry));
+        row.inflateViews();
     }
 
     protected void addNotificationViews(NotificationData.Entry entry) {
@@ -786,7 +859,7 @@
                 mNotificationData.getImportance(key));
 
         boolean alertAgain = alertAgain(entry, entry.notification.getNotification());
-        if (mPresenter.isDozing()) {
+        if (getShadeController().isDozing()) {
             updateAlertState(entry, shouldPulse(entry), alertAgain, mAmbientPulseManager);
         } else {
             updateAlertState(entry, shouldHeadsUp(entry), alertAgain, mHeadsUpManager);
@@ -801,7 +874,8 @@
 
         if (DEBUG) {
             // Is this for you?
-            boolean isForCurrentUser = mPresenter.isNotificationForCurrentProfiles(notification);
+            boolean isForCurrentUser = Dependency.get(KeyguardEnvironment.class)
+                    .isNotificationForCurrentProfiles(notification);
             Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
         }
 
@@ -885,7 +959,7 @@
     public boolean shouldHeadsUp(NotificationData.Entry entry) {
         StatusBarNotification sbn = entry.notification;
 
-        if (mPresenter.isDozing()) {
+        if (getShadeController().isDozing()) {
             if (DEBUG) {
                 Log.d(TAG, "No heads up: device is dozing: " + sbn.getKey());
             }
@@ -966,7 +1040,7 @@
     protected boolean shouldPulse(NotificationData.Entry entry) {
         StatusBarNotification sbn = entry.notification;
 
-        if (!mPresenter.isDozing()) {
+        if (!getShadeController().isDozing()) {
             if (DEBUG) {
                 Log.d(TAG, "No pulsing: not dozing: " + sbn.getKey());
             }
@@ -1044,7 +1118,7 @@
 
     protected void setNotificationsShown(String[] keys) {
         try {
-            mNotificationListener.setNotificationsShown(keys);
+            getNotificationListener().setNotificationsShown(keys);
         } catch (RuntimeException e) {
             Log.d(TAG, "failed setNotificationsShown: ", e);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisibilityLocationProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisibilityLocationProvider.java
index 81208c4..53ebe74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisibilityLocationProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisibilityLocationProvider.java
@@ -24,7 +24,10 @@
 public interface VisibilityLocationProvider {
 
     /**
-     * @return whether the view is in a visible location right now.
+     * Returns whether an ExpandableNotificationRow is in a visible location or not.
+     *
+     * @param row
+     * @return true if row is in a visible location
      */
     boolean isInVisibleLocation(ExpandableNotificationRow row);
 }
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 e96e176..b5fbde1 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
@@ -56,8 +56,9 @@
     private final NotificationListenerService mNotificationListener =
             Dependency.get(NotificationListener.class);
     private final UiOffloadThread mUiOffloadThread = Dependency.get(UiOffloadThread.class);
+    protected NotificationEntryManager mEntryManager
+            = Dependency.get(NotificationEntryManager.class);
 
-    protected NotificationEntryManager mEntryManager;
     protected Handler mHandler = new Handler();
     protected IStatusBarService mBarService;
     private long mLastVisibilityReportUptimeMs;
@@ -147,9 +148,7 @@
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
     }
 
-    public void setUpWithEntryManager(NotificationEntryManager entryManager,
-            NotificationListContainer listContainer) {
-        mEntryManager = entryManager;
+    public void setUpWithContainer(NotificationListContainer listContainer) {
         mListContainer = listContainer;
     }
 
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 bce613a..22c37fd 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,12 +17,19 @@
 package com.android.systemui.statusbar.notification.row;
 
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
+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;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_PUBLIC;
 import static com.android.systemui.statusbar.notification.row.NotificationInflater.InflationCallback;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -38,8 +45,8 @@
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.Build;
-import android.os.SystemClock;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.util.AttributeSet;
@@ -72,28 +79,31 @@
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
-import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarIconView;
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
-import com.android.systemui.statusbar.notification.logging.NotificationCounters;
+import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationUtils;
-import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.phone.NotificationGroupManager;
-import com.android.systemui.statusbar.phone.StatusBar;
-import com.android.systemui.statusbar.policy.HeadsUpManager;
+import com.android.systemui.statusbar.notification.logging.NotificationCounters;
+import com.android.systemui.statusbar.notification.row.NotificationInflater.InflationFlag;
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.stack.AmbientState;
 import com.android.systemui.statusbar.notification.stack.AnimationProperties;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
 import com.android.systemui.statusbar.notification.stack.StackScrollState;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.function.BooleanSupplier;
@@ -203,6 +213,11 @@
      */
     private boolean mIsAmbientPulsing;
 
+    /**
+     * 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.
+     */
+    private boolean mNeedsRedaction;
     private boolean mLastChronometerRunning = true;
     private ViewStub mChildrenContainerStub;
     private NotificationGroupManager mGroupManager;
@@ -429,15 +444,65 @@
         }
     }
 
-    public void updateNotification(NotificationData.Entry entry) {
+    /**
+     * Set the entry for the row.
+     *
+     * @param entry the entry this row is tied to
+     */
+    public void setEntry(@NonNull NotificationData.Entry entry) {
         mEntry = entry;
         mStatusBarNotification = entry.notification;
-        mNotificationInflater.inflateNotificationViews();
-
         cacheIsSystemNotification();
     }
 
     /**
+     * Inflate views based off the inflation flags set.  Inflation happens asynchronously.
+     */
+    public void inflateViews() {
+        mNotificationInflater.inflateNotificationViews();
+    }
+
+    /**
+     * Marks a content view as freeable, setting it so that future inflations do not reinflate
+     * and ensuring that the view is freed when it is safe to remove.
+     *
+     * @param inflationFlag flag corresponding to the content view to be freed
+     */
+    public void freeContentViewWhenSafe(@InflationFlag int inflationFlag) {
+        // View should not be reinflated in the future
+        updateInflationFlag(inflationFlag, false);
+        Runnable freeViewRunnable = () ->
+                mNotificationInflater.freeNotificationView(inflationFlag);
+        switch (inflationFlag) {
+            case FLAG_CONTENT_VIEW_HEADS_UP:
+                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);
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Update whether or not a content view should be inflated.
+     *
+     * @param flag the flag corresponding to the content view
+     * @param shouldInflate true if it should be inflated, false if it should not
+     */
+    public void updateInflationFlag(@InflationFlag int flag, boolean shouldInflate) {
+        mNotificationInflater.updateInflationFlag(flag, shouldInflate);
+    }
+
+    /**
      * Caches whether or not this row contains a system notification. Note, this is only cached
      * once per notification as the packageInfo can't technically change for a notification row.
      */
@@ -499,6 +564,9 @@
         if (mIconAnimationRunning) {
             setIconAnimationRunning(true);
         }
+        if (mLastChronometerRunning) {
+            setChronometerRunning(true);
+        }
         if (mNotificationParent != null) {
             mNotificationParent.updateChildrenHeaderAppearance();
         }
@@ -557,7 +625,8 @@
     }
 
     private void updateLimitsForView(NotificationContentView layout) {
-        boolean customView = layout.getContractedChild().getId()
+        boolean customView = layout.getContractedChild() != null
+                && layout.getContractedChild().getId()
                 != com.android.internal.R.id.status_bar_latest_event_content;
         boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N;
         boolean beforeP = mEntry.targetSdk < Build.VERSION_CODES.P;
@@ -581,7 +650,7 @@
             headsUpHeight = mMaxHeadsUpHeight;
         }
         NotificationViewWrapper headsUpWrapper = layout.getVisibleWrapper(
-                NotificationContentView.VISIBLE_TYPE_HEADSUP);
+                VISIBLE_TYPE_HEADSUP);
         if (headsUpWrapper != null) {
             headsUpHeight = Math.max(headsUpHeight, headsUpWrapper.getMinLayoutHeight());
         }
@@ -1511,7 +1580,14 @@
     }
 
     public void setNeedsRedaction(boolean needsRedaction) {
-        mNotificationInflater.setRedactAmbient(needsRedaction);
+        if (mNeedsRedaction != needsRedaction) {
+            mNeedsRedaction = needsRedaction;
+            updateInflationFlag(FLAG_CONTENT_VIEW_PUBLIC, needsRedaction /* shouldInflate */);
+            mNotificationInflater.updateNeedsRedaction(needsRedaction);
+            if (!needsRedaction) {
+                freeContentViewWhenSafe(FLAG_CONTENT_VIEW_PUBLIC);
+            }
+        }
     }
 
     @VisibleForTesting
@@ -2616,6 +2692,10 @@
         return shouldShowPublic() ? mPublicLayout : mPrivateLayout;
     }
 
+    public View getExpandedContentView() {
+        return getPrivateLayout().getExpandedChild();
+    }
+
     public void setLegacy(boolean legacy) {
         for (NotificationContentView l : mLayouts) {
             l.setLegacy(legacy);
@@ -3017,6 +3097,36 @@
         boolean onClick(View v, int x, int y, MenuItem item);
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        super.dump(fd, pw, args);
+        pw.println("  Notification: " + getStatusBarNotification().getKey());
+        pw.print("    visibility: " + getVisibility());
+        pw.print(", alpha: " + getAlpha());
+        pw.print(", translation: " + getTranslation());
+        pw.print(", removed: " + isRemoved());
+        pw.print(", privateShowing: " + (getShowingLayout() == mPrivateLayout));
+        pw.println();
+        pw.print("    ");
+        if (mNotificationViewState != null) {
+            mNotificationViewState.dump(fd, pw, args);
+        } else {
+            pw.print("no viewState!!!");
+        }
+        pw.println();
+        pw.println();
+        if (mIsSummaryWithChildren) {
+            List<ExpandableNotificationRow> notificationChildren = getNotificationChildren();
+            pw.println("  Children: " + notificationChildren.size());
+            pw.println("  {");
+            for(ExpandableNotificationRow child : notificationChildren) {
+                child.dump(fd, pw, args);
+            }
+            pw.println("  }");
+            pw.println();
+        }
+    }
+
     /**
      * Background task for executing IPCs to check if the notification is a system notification. The
      * output is used for both the blocking helper and the notification info.
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 46019e3..38d657b 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
@@ -25,16 +25,19 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
+import com.android.systemui.Dumpable;
 import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.notification.stack.StackScrollState;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 
 /**
  * An abstract view for expandable views.
  */
-public abstract class ExpandableView extends FrameLayout {
+public abstract class ExpandableView extends FrameLayout implements Dumpable {
 
     public static final float NO_ROUNDNESS = -1;
     protected OnHeightChangedListener mOnHeightChangedListener;
@@ -559,6 +562,10 @@
         return false;
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+    }
+
     /**
      * A listener notifying when {@link #getActualHeight} changes.
      */
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 4963a0c..11cf8e0 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
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import android.annotation.Nullable;
 import android.app.Notification;
 import android.app.PendingIntent;
 import android.app.RemoteInput;
@@ -23,9 +24,11 @@
 import android.graphics.Rect;
 import android.os.Build;
 import android.service.notification.StatusBarNotification;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.util.Pair;
 import android.view.MotionEvent;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -40,12 +43,12 @@
 import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.TransformableView;
-import com.android.systemui.statusbar.notification.row.wrapper.NotificationCustomViewWrapper;
+import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationUtils;
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationCustomViewWrapper;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.policy.RemoteInputView;
@@ -107,6 +110,10 @@
     private NotificationGroupManager mGroupManager;
     private RemoteInputController mRemoteInputController;
     private Runnable mExpandedVisibleListener;
+    /**
+     * List of listeners for when content views become inactive (i.e. not the showing view).
+     */
+    private final ArrayMap<View, Runnable> mOnContentViewInactiveListeners = new ArrayMap<>();
 
     private final ViewTreeObserver.OnPreDrawListener mEnableAnimationPredrawListener
             = new ViewTreeObserver.OnPreDrawListener() {
@@ -417,11 +424,24 @@
         return mAmbientSingleLineChild;
     }
 
-    public void setContractedChild(View child) {
+    /**
+     * Sets the contracted view. Child may be null to remove the content view.
+     *
+     * @param child contracted content view to set
+     */
+    public void setContractedChild(@Nullable View child) {
         if (mContractedChild != null) {
             mContractedChild.animate().cancel();
             removeView(mContractedChild);
         }
+        if (child == null) {
+            mContractedChild = null;
+            mContractedWrapper = null;
+            if (mTransformationStartVisibleType == VISIBLE_TYPE_CONTRACTED) {
+                mTransformationStartVisibleType = UNDEFINED;
+            }
+            return;
+        }
         addView(child);
         mContractedChild = child;
         mContractedWrapper = NotificationViewWrapper.wrap(getContext(), child,
@@ -444,7 +464,12 @@
         return null;
     }
 
-    public void setExpandedChild(View child) {
+    /**
+     * Sets the expanded view. Child may be null to remove the content view.
+     *
+     * @param child expanded content view to set
+     */
+    public void setExpandedChild(@Nullable View child) {
         if (mExpandedChild != null) {
             mPreviousExpandedRemoteInputIntent = null;
             if (mExpandedRemoteInput != null) {
@@ -477,7 +502,12 @@
                 mContainingNotification);
     }
 
-    public void setHeadsUpChild(View child) {
+    /**
+     * Sets the heads up view. Child may be null to remove the content view.
+     *
+     * @param child heads up content view to set
+     */
+    public void setHeadsUpChild(@Nullable View child) {
         if (mHeadsUpChild != null) {
             mPreviousHeadsUpRemoteInputIntent = null;
             if (mHeadsUpRemoteInput != null) {
@@ -510,12 +540,25 @@
                 mContainingNotification);
     }
 
-    public void setAmbientChild(View child) {
+    /**
+     * 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 (mVisibleType == VISIBLE_TYPE_AMBIENT) {
+                mVisibleType = VISIBLE_TYPE_CONTRACTED;
+            }
+            if (mTransformationStartVisibleType == VISIBLE_TYPE_AMBIENT) {
+                mTransformationStartVisibleType = UNDEFINED;
+            }
             return;
         }
         addView(child);
@@ -528,6 +571,13 @@
     protected void onVisibilityChanged(View changedView, int visibility) {
         super.onVisibilityChanged(changedView, visibility);
         updateVisibility();
+        if (visibility != VISIBLE) {
+            // View is no longer visible so all content views are inactive.
+            for (Runnable r : mOnContentViewInactiveListeners.values()) {
+                r.run();
+            }
+            mOnContentViewInactiveListeners.clear();
+        }
     }
 
     private void updateVisibility() {
@@ -575,6 +625,12 @@
         mContentHeight = Math.min(mUnrestrictedContentHeight, maxContentHeight);
         selectLayout(mAnimate /* animate */, false /* force */);
 
+        if (mContractedChild == null) {
+            // Contracted child may be null if this is the public content view and we don't need to
+            // show it.
+            return;
+        }
+
         int minHeightHint = getMinContentHeightHint();
 
         NotificationViewWrapper wrapper = getVisibleWrapper(mVisibleType);
@@ -725,7 +781,7 @@
     }
 
     public int getMaxHeight() {
-        if (mContainingNotification.isOnAmbient()) {
+        if (mContainingNotification.isOnAmbient() && getShowingAmbientView() != null) {
             return getShowingAmbientView().getHeight();
         } else if (mExpandedChild != null) {
             return getViewHeight(VISIBLE_TYPE_EXPANDED)
@@ -733,8 +789,10 @@
         } else if (mIsHeadsUp && mHeadsUpChild != null && !mContainingNotification.isOnKeyguard()) {
             return getViewHeight(VISIBLE_TYPE_HEADSUP)
                     + getExtraRemoteInputHeight(mHeadsUpRemoteInput);
+        } else if (mContractedChild != null) {
+            return getViewHeight(VISIBLE_TYPE_CONTRACTED);
         }
-        return getViewHeight(VISIBLE_TYPE_CONTRACTED);
+        return mNotificationMaxHeight;
     }
 
     private int getViewHeight(int visibleType) {
@@ -752,10 +810,11 @@
     }
 
     public int getMinHeight(boolean likeGroupExpanded) {
-        if (mContainingNotification.isOnAmbient()) {
+        if (mContainingNotification.isOnAmbient() && getShowingAmbientView() != null) {
             return getShowingAmbientView().getHeight();
         } else if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded()) {
-            return getViewHeight(VISIBLE_TYPE_CONTRACTED);
+            return mContractedChild != null
+                    ? getViewHeight(VISIBLE_TYPE_CONTRACTED) : mMinContractedHeight;
         } else {
             return mSingleLineView.getHeight();
         }
@@ -1090,7 +1149,8 @@
                 return VISIBLE_TYPE_EXPANDED;
             }
         } else {
-            if (noExpandedChild || (viewHeight <= getViewHeight(VISIBLE_TYPE_CONTRACTED)
+            if (noExpandedChild || (mContractedChild != null
+                    && viewHeight <= getViewHeight(VISIBLE_TYPE_CONTRACTED)
                     && (!mIsChildInGroup || isGroupExpanded()
                             || !mContainingNotification.isExpanded(true /* allowOnKeyguard */)))) {
                 return VISIBLE_TYPE_CONTRACTED;
@@ -1162,6 +1222,7 @@
 
     public void onNotificationUpdated(NotificationData.Entry entry) {
         mStatusBarNotification = entry.notification;
+        mOnContentViewInactiveListeners.clear();
         mBeforeN = entry.targetSdk < Build.VERSION_CODES.N;
         updateAllSingleLineViews();
         if (mContractedChild != null) {
@@ -1188,6 +1249,7 @@
         updateSingleLineView();
         updateAmbientSingleLineView();
     }
+
     private void updateSingleLineView() {
         if (mIsChildInGroup) {
             boolean isNewView = mSingleLineView == null;
@@ -1223,53 +1285,44 @@
             return;
         }
 
-        boolean enableSmartReplies = (mSmartReplyConstants.isEnabled()
+        Notification notification = entry.notification.getNotification();
+
+        Pair<RemoteInput, Notification.Action> remoteInputActionPair =
+                entry.notification.getNotification().findRemoteInputActionPair(false /*freeform */);
+        Pair<RemoteInput, Notification.Action> freeformRemoteInputActionPair =
+                notification.findRemoteInputActionPair(true /*freeform */);
+
+        boolean enableAppGeneratedSmartReplies = (mSmartReplyConstants.isEnabled()
                 && (!mSmartReplyConstants.requiresTargetingP()
-                    || entry.targetSdk >= Build.VERSION_CODES.P));
+                || entry.targetSdk >= Build.VERSION_CODES.P));
 
-        boolean hasRemoteInput = false;
         RemoteInput remoteInputWithChoices = null;
-        PendingIntent pendingIntentWithChoices = null;
+        PendingIntent pendingIntentWithChoices= null;
         CharSequence[] choices = null;
-
-        Notification.Action[] actions = entry.notification.getNotification().actions;
-        if (actions != null) {
-            for (Notification.Action a : actions) {
-                if (a.getRemoteInputs() == null) {
-                    continue;
-                }
-                for (RemoteInput ri : a.getRemoteInputs()) {
-                    boolean showRemoteInputView = ri.getAllowFreeFormInput();
-                    boolean showSmartReplyView = enableSmartReplies
-                            && (ArrayUtils.isEmpty(ri.getChoices())
-                            || (showRemoteInputView && !ArrayUtils.isEmpty(entry.smartReplies)));
-                    if (showRemoteInputView) {
-                        hasRemoteInput = true;
-                    }
-                    if (showSmartReplyView) {
-                        remoteInputWithChoices = ri;
-                        pendingIntentWithChoices = a.actionIntent;
-                        if (!ArrayUtils.isEmpty(ri.getChoices())) {
-                            choices = ri.getChoices();
-                        } else {
-                            choices = entry.smartReplies;
-                        }
-                    }
-                    if (showRemoteInputView || showSmartReplyView) {
-                        break;
-                    }
-                }
-            }
+        if (enableAppGeneratedSmartReplies
+                && remoteInputActionPair != null
+                && !ArrayUtils.isEmpty(remoteInputActionPair.first.getChoices())) {
+            // app generated smart replies
+            remoteInputWithChoices = remoteInputActionPair.first;
+            pendingIntentWithChoices = remoteInputActionPair.second.actionIntent;
+            choices = remoteInputActionPair.first.getChoices();
+        } else if (!ArrayUtils.isEmpty(entry.smartReplies)
+                && freeformRemoteInputActionPair != null
+                && freeformRemoteInputActionPair.second.getAllowGeneratedReplies()) {
+            // system generated smart replies
+            remoteInputWithChoices = freeformRemoteInputActionPair.first;
+            pendingIntentWithChoices = freeformRemoteInputActionPair.second.actionIntent;
+            choices = entry.smartReplies;
         }
 
-        applyRemoteInput(entry, hasRemoteInput);
+        applyRemoteInput(entry, freeformRemoteInputActionPair != null);
         applySmartReplyView(remoteInputWithChoices, pendingIntentWithChoices, entry, choices);
     }
 
-    private void applyRemoteInput(NotificationData.Entry entry, boolean hasRemoteInput) {
+    private void applyRemoteInput(NotificationData.Entry entry, boolean hasFreeformRemoteInput) {
         View bigContentView = mExpandedChild;
         if (bigContentView != null) {
-            mExpandedRemoteInput = applyRemoteInput(bigContentView, entry, hasRemoteInput,
+            mExpandedRemoteInput = applyRemoteInput(bigContentView, entry, hasFreeformRemoteInput,
                     mPreviousExpandedRemoteInputIntent, mCachedExpandedRemoteInput,
                     mExpandedWrapper);
         } else {
@@ -1284,7 +1337,8 @@
 
         View headsUpContentView = mHeadsUpChild;
         if (headsUpContentView != null) {
-            mHeadsUpRemoteInput = applyRemoteInput(headsUpContentView, entry, hasRemoteInput,
+            mHeadsUpRemoteInput = applyRemoteInput(
+                    headsUpContentView, entry, hasFreeformRemoteInput,
                     mPreviousHeadsUpRemoteInputIntent, mCachedHeadsUpRemoteInput, mHeadsUpWrapper);
         } else {
             mHeadsUpRemoteInput = null;
@@ -1370,8 +1424,8 @@
             mExpandedSmartReplyView =
                     applySmartReplyView(mExpandedChild, remoteInput, pendingIntent, entry, choices);
             if (mExpandedSmartReplyView != null && remoteInput != null
-                    && remoteInput.getChoices() != null && remoteInput.getChoices().length > 0) {
-                mSmartReplyController.smartRepliesAdded(entry, remoteInput.getChoices().length);
+                    && choices != null && choices.length > 0) {
+                mSmartReplyController.smartRepliesAdded(entry, choices.length);
             }
         }
     }
@@ -1626,15 +1680,65 @@
         fireExpandedVisibleListenerIfVisible();
     }
 
+    /**
+     * Set a one-shot listener to run when a given content view becomes inactive.
+     *
+     * @param visibleType visible type corresponding to the content view to listen
+     * @param listener runnable to run once when the content view becomes inactive
+     */
+    public void performWhenContentInactive(int visibleType, Runnable listener) {
+        View view = getViewForVisibleType(visibleType);
+        // View is already inactive
+        if (view == null || isContentViewInactive(visibleType)) {
+            listener.run();
+            return;
+        }
+        mOnContentViewInactiveListeners.put(view, listener);
+    }
+
+    /**
+     * Whether or not the content view is inactive.  This means it should not be visible
+     * or the showing content as removing it would cause visual jank.
+     *
+     * @param visibleType visible type corresponding to the content view to be removed
+     * @return true if the content view is inactive, false otherwise
+     */
+    public boolean isContentViewInactive(int visibleType) {
+        View view = getViewForVisibleType(visibleType);
+        return isContentViewInactive(view);
+    }
+
+    /**
+     * Whether or not the content view is inactive.
+     *
+     * @param view view to see if its inactive
+     * @return true if the view is inactive, false o/w
+     */
+    private boolean isContentViewInactive(View view) {
+        if (view == null) {
+            return true;
+        }
+        return !isShown()
+                || (view.getVisibility() != VISIBLE && getViewForVisibleType(mVisibleType) != view);
+    }
+
+    @Override
+    protected void onChildVisibilityChanged(View child, int oldVisibility, int newVisibility) {
+        super.onChildVisibilityChanged(child, oldVisibility, newVisibility);
+        if (isContentViewInactive(child)) {
+            Runnable listener = mOnContentViewInactiveListeners.remove(child);
+            if (listener != null) {
+                listener.run();
+            }
+        }
+    }
+
     public void setIsLowPriority(boolean isLowPriority) {
         mIsLowPriority = isLowPriority;
     }
 
     public boolean isDimmable() {
-        if (!mContractedWrapper.isDimmable()) {
-            return false;
-        }
-        return true;
+        return mContractedWrapper != null && mContractedWrapper.isDimmable();
     }
 
     /**
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 f4ef0f8..2499952 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
@@ -28,6 +28,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.net.Uri;
+import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
@@ -41,15 +42,23 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
+import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
 import com.android.systemui.statusbar.NotificationLifetimeExtender;
-import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -71,14 +80,20 @@
     // Dependencies:
     private final NotificationLockscreenUserManager mLockscreenUserManager =
             Dependency.get(NotificationLockscreenUserManager.class);
+    private final StatusBarStateController mStatusBarStateController =
+            Dependency.get(StatusBarStateController.class);
+    private final DeviceProvisionedController mDeviceProvisionedController =
+            Dependency.get(DeviceProvisionedController.class);
+    private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
 
     // which notification is currently being longpress-examined by the user
+    private final IStatusBarService mBarService;
     private NotificationGuts mNotificationGutsExposed;
     private NotificationMenuRowPlugin.MenuItem mGutsMenuItem;
-    private NotificationPresenter mPresenter;
     private NotificationSafeToRemoveCallback mNotificationLifetimeFinishedCallback;
+    private NotificationPresenter mPresenter;
     private NotificationListContainer mListContainer;
-    private NotificationInfo.CheckSaveListener mCheckSaveListener;
+    private CheckSaveListener mCheckSaveListener;
     private OnSettingsClickListener mOnSettingsClickListener;
     @VisibleForTesting
     protected String mKeyToRemoveOnGutsClosed;
@@ -89,16 +104,17 @@
 
         mAccessibilityManager = (AccessibilityManager)
                 mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
     }
 
     public void setUpWithPresenter(NotificationPresenter presenter,
             NotificationListContainer listContainer,
-            NotificationInfo.CheckSaveListener checkSaveListener,
-            OnSettingsClickListener onSettingsClickListener) {
+            CheckSaveListener checkSave, OnSettingsClickListener onSettingsClick) {
         mPresenter = presenter;
         mListContainer = listContainer;
-        mCheckSaveListener = checkSaveListener;
-        mOnSettingsClickListener = onSettingsClickListener;
+        mCheckSaveListener = checkSave;
+        mOnSettingsClickListener = onSettingsClick;
     }
 
     public void onDensityOrFontScaleChanged(ExpandableNotificationRow row) {
@@ -264,7 +280,7 @@
             onSettingsClick = (View v, NotificationChannel channel, int appUid) -> {
                 mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_NOTE_INFO);
                 guts.resetFalsingCheck();
-                mOnSettingsClickListener.onClick(sbn.getKey());
+                mOnSettingsClickListener.onSettingsClick(sbn.getKey());
                 startAppNotificationSettingsActivity(packageName, appUid, channel, row);
             };
         }
@@ -279,7 +295,7 @@
                 mCheckSaveListener,
                 onSettingsClick,
                 onAppSettingsClick,
-                mPresenter.isDeviceProvisioned(),
+                mDeviceProvisionedController.isDeviceProvisioned(),
                 row.getIsNonblockable(),
                 isForBlockingHelper,
                 row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE);
@@ -317,6 +333,10 @@
         mNotificationGutsExposed = guts;
     }
 
+    public ExpandableNotificationRow.LongPressListener getNotificationLongClicker() {
+        return this::openGuts;
+    }
+
     /**
      * Opens guts on the given ExpandableNotificationRow {@code view}. This handles opening guts for
      * the normal half-swipe and long-press use cases via a circular reveal. When the blocking
@@ -385,7 +405,7 @@
                 guts.setVisibility(View.VISIBLE);
 
                 final boolean needsFalsingProtection =
-                        (mPresenter.isPresenterLocked() &&
+                        (mStatusBarStateController.getState() == StatusBarState.KEYGUARD &&
                                 !mAccessibilityManager.isTouchExplorationEnabled());
 
                 guts.openControls(
@@ -442,6 +462,6 @@
     }
 
     public interface OnSettingsClickListener {
-        void onClick(String key);
+        public void onSettingsClick(String key);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
index aa4765a..38d6b35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInflater.java
@@ -16,12 +16,18 @@
 
 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;
+
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.app.Notification;
 import android.content.Context;
 import android.os.AsyncTask;
 import android.os.CancellationSignal;
 import android.service.notification.StatusBarNotification;
+import android.util.ArrayMap;
 import android.util.Log;
 import android.view.View;
 import android.widget.RemoteViews;
@@ -30,11 +36,13 @@
 import com.android.systemui.statusbar.InflationTask;
 import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.notification.MediaNotificationProcessor;
-import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.util.Assert;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -52,14 +60,67 @@
 public class NotificationInflater {
 
     public static final String TAG = "NotificationInflater";
-    @VisibleForTesting
-    static final int FLAG_REINFLATE_ALL = ~0;
-    private static final int FLAG_REINFLATE_CONTENT_VIEW = 1<<0;
-    @VisibleForTesting
-    static final int FLAG_REINFLATE_EXPANDED_VIEW = 1<<1;
-    private static final int FLAG_REINFLATE_HEADS_UP_VIEW = 1<<2;
-    private static final int FLAG_REINFLATE_PUBLIC_VIEW = 1<<3;
-    private static final int FLAG_REINFLATE_AMBIENT_VIEW = 1<<4;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            prefix = {"FLAG_CONTENT_VIEW_"},
+            value = {
+                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 {}
+    /**
+     * The default, contracted view.  Seen when the shade is pulled down and in the lock screen
+     * if there is no worry about content sensitivity.
+     */
+    public static final int FLAG_CONTENT_VIEW_CONTRACTED = 1;
+
+    /**
+     * The expanded view.  Seen when the user expands a notification.
+     */
+    public static final int FLAG_CONTENT_VIEW_EXPANDED = 1 << 1;
+
+    /**
+     * The heads up view.  Seen when a high priority notification peeks in from the top.
+     */
+    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_ALL = ~0;
+
+    // TODO: Heads up and ambient are always inflated as a temporary workaround.
+    // See http://b/117933032 and http://b/117894786
+    /**
+     * Content views that must be inflated at all times.
+     */
+    @InflationFlag
+    private static final int REQUIRED_INFLATION_FLAGS =
+            FLAG_CONTENT_VIEW_CONTRACTED
+            | FLAG_CONTENT_VIEW_EXPANDED
+            | FLAG_CONTENT_VIEW_HEADS_UP
+            | FLAG_CONTENT_VIEW_AMBIENT;
+
+    /**
+     * The set of content views to inflate.
+     */
+    @InflationFlag
+    private int mInflationFlags = REQUIRED_INFLATION_FLAGS;
+
     private static final InflationExecutor EXECUTOR = new InflationExecutor();
 
     private final ExpandableNotificationRow mRow;
@@ -71,6 +132,7 @@
     private InflationCallback mCallback;
     private boolean mRedactAmbient;
     private List<Notification.Action> mSmartActions;
+    private final ArrayMap<Integer, RemoteViews> mCachedContentViews = new ArrayMap<>();
 
     public NotificationInflater(ExpandableNotificationRow row) {
         mRow = row;
@@ -89,10 +151,10 @@
         if (childInGroup != mIsChildInGroup) {
             mIsChildInGroup = childInGroup;
             if (mIsLowPriority) {
-                int flags = FLAG_REINFLATE_CONTENT_VIEW | FLAG_REINFLATE_EXPANDED_VIEW;
+                int flags = FLAG_CONTENT_VIEW_CONTRACTED | FLAG_CONTENT_VIEW_EXPANDED;
                 inflateNotificationViews(flags);
             }
-        } ;
+        }
     }
 
     public void setUsesIncreasedHeight(boolean usesIncreasedHeight) {
@@ -111,14 +173,60 @@
         mRemoteViewClickHandler = remoteViewClickHandler;
     }
 
-    public void setRedactAmbient(boolean redactAmbient) {
-        if (mRedactAmbient != redactAmbient) {
-            mRedactAmbient = redactAmbient;
-            if (mRow.getEntry() == null) {
-                return;
-            }
-            inflateNotificationViews(FLAG_REINFLATE_AMBIENT_VIEW);
+    /**
+     * 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.
+     *
+     * @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;
+        }
+        inflateNotificationViews(flags);
+    }
+
+    /**
+     * Set whether or not a particular content view is needed and whether or not it should be
+     * inflated.  These flags will be used when we inflate or reinflate.
+     *
+     * @param flag the {@link InflationFlag} corresponding to the view that should/should not be
+     *             inflated
+     * @param shouldInflate true if the view should be inflated, false otherwise
+     */
+    public void updateInflationFlag(@InflationFlag int flag, boolean shouldInflate) {
+        if (shouldInflate) {
+            mInflationFlags |= flag;
+        } else if ((REQUIRED_INFLATION_FLAGS & flag) == 0) {
+            mInflationFlags &= ~flag;
+        }
+    }
+
+    /**
+     * Add flags for which content views should be inflated in addition to those already set.
+     *
+     * @param flags a set of {@link InflationFlag} corresponding to content views that should be
+     *              inflated
+     */
+    public void addInflationFlags(@InflationFlag int flags) {
+        mInflationFlags |= flags;
+    }
+
+    /**
+     * Whether or not the view corresponding to the flag is set to be inflated currently.
+     *
+     * @param flag the {@link InflationFlag} corresponding to the view
+     * @return true if the flag is set and view will be inflated, false o/w
+     */
+    @VisibleForTesting
+    public boolean isInflationFlagSet(@InflationFlag int flag) {
+        return ((mInflationFlags & flag) != 0);
     }
 
     /**
@@ -126,29 +234,32 @@
      * notify the callback once it's finished.
      */
     public void inflateNotificationViews() {
-        inflateNotificationViews(FLAG_REINFLATE_ALL);
+        inflateNotificationViews(mInflationFlags);
     }
 
     /**
-     * Reinflate all views for the specified flags on a background thread. This is asynchronous and
-     * will notify the callback once it's finished.
+     * Inflate all views for the specified flags on a background thread.  This is asynchronous and
+     * will notify the callback once it's finished.  If the content view is already inflated, this
+     * will reinflate it.
      *
-     * @param reInflateFlags flags which views should be reinflated. Use {@link #FLAG_REINFLATE_ALL}
-     *                       to reinflate all of views.
+     * @param reInflateFlags flags which views should be inflated.  Should be a subset of
+     *                       {@link NotificationInflater#mInflationFlags} as only those will be
+     *                       inflated/reinflated.
      */
-    @VisibleForTesting
-    void inflateNotificationViews(int reInflateFlags) {
+    private void inflateNotificationViews(@InflationFlag int reInflateFlags) {
         if (mRow.isRemoved()) {
             // We don't want to reinflate anything for removed notifications. Otherwise views might
             // be readded to the stack, leading to leaks. This may happen with low-priority groups
             // where the removal of already removed children can lead to a reinflation.
             return;
         }
+        // Only inflate the ones that are set.
+        reInflateFlags &= mInflationFlags;
         StatusBarNotification sbn = mRow.getEntry().notification;
-        AsyncInflationTask task = new AsyncInflationTask(sbn, reInflateFlags, mRow,
-                mIsLowPriority,
-                mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient,
-                mCallback, mRemoteViewClickHandler, mSmartActions);
+        AsyncInflationTask task = new AsyncInflationTask(sbn, reInflateFlags, mCachedContentViews,
+                mRow, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight,
+                mUsesIncreasedHeadsUpHeight, mRedactAmbient, mCallback, mRemoteViewClickHandler,
+                mSmartActions);
         if (mCallback != null && mCallback.doInflateSynchronous()) {
             task.onPostExecute(task.doInBackground());
         } else {
@@ -157,38 +268,85 @@
     }
 
     @VisibleForTesting
-    InflationProgress inflateNotificationViews(int reInflateFlags,
+    InflationProgress inflateNotificationViews(@InflationFlag int reInflateFlags,
             Notification.Builder builder, Context packageContext) {
         InflationProgress result = createRemoteViews(reInflateFlags, builder, mIsLowPriority,
                 mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
                 mRedactAmbient, packageContext);
-        apply(result, reInflateFlags, mRow, mRedactAmbient, mRemoteViewClickHandler, null);
+        apply(result, reInflateFlags, mCachedContentViews, mRow, mRedactAmbient,
+                mRemoteViewClickHandler, null);
         return result;
     }
 
-    private static InflationProgress createRemoteViews(int reInflateFlags,
+    /**
+     * Frees the content view associated with the inflation flag.  Will only succeed if the
+     * view is safe to remove.
+     *
+     * @param inflateFlag the flag corresponding to the content view which should be freed
+     */
+    public void freeNotificationView(@InflationFlag int inflateFlag) {
+        if ((mInflationFlags & inflateFlag) != 0) {
+            // The view should still be inflated.
+            return;
+        }
+        switch (inflateFlag) {
+            case FLAG_CONTENT_VIEW_HEADS_UP:
+                if (mRow.getPrivateLayout().isContentViewInactive(VISIBLE_TYPE_HEADSUP)) {
+                    mRow.getPrivateLayout().setHeadsUpChild(null);
+                    mCachedContentViews.remove(FLAG_CONTENT_VIEW_HEADS_UP);
+                }
+                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);
+                    mCachedContentViews.remove(FLAG_CONTENT_VIEW_PUBLIC);
+                }
+                break;
+            case FLAG_CONTENT_VIEW_CONTRACTED:
+            case FLAG_CONTENT_VIEW_EXPANDED:
+            default:
+                break;
+        }
+    }
+
+    private static InflationProgress createRemoteViews(@InflationFlag int reInflateFlags,
             Notification.Builder builder, boolean isLowPriority, boolean isChildInGroup,
             boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, boolean redactAmbient,
             Context packageContext) {
         InflationProgress result = new InflationProgress();
         isLowPriority = isLowPriority && !isChildInGroup;
-        if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
+        if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
             result.newContentView = createContentView(builder, isLowPriority, usesIncreasedHeight);
         }
 
-        if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
+        if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0) {
             result.newExpandedView = createExpandedView(builder, isLowPriority);
         }
 
-        if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
+        if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) {
             result.newHeadsUpView = builder.createHeadsUpContentView(usesIncreasedHeadsUpHeight);
         }
 
-        if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
+        if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) {
             result.newPublicView = builder.makePublicContentView();
         }
 
-        if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
+        if ((reInflateFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
             result.newAmbientView = redactAmbient ? builder.makePublicAmbientNotification()
                     : builder.makeAmbientNotification();
         }
@@ -199,18 +357,20 @@
         return result;
     }
 
-    public static CancellationSignal apply(InflationProgress result, int reInflateFlags,
+    public static CancellationSignal apply(InflationProgress result,
+            @InflationFlag int reInflateFlags, ArrayMap<Integer, RemoteViews> cachedContentViews,
             ExpandableNotificationRow row, boolean redactAmbient,
             RemoteViews.OnClickHandler remoteViewClickHandler,
             @Nullable InflationCallback callback) {
-        NotificationData.Entry entry = row.getEntry();
         NotificationContentView privateLayout = row.getPrivateLayout();
         NotificationContentView publicLayout = row.getPublicLayout();
         final HashMap<Integer, CancellationSignal> runningInflations = new HashMap<>();
 
-        int flag = FLAG_REINFLATE_CONTENT_VIEW;
+        int flag = FLAG_CONTENT_VIEW_CONTRACTED;
         if ((reInflateFlags & flag) != 0) {
-            boolean isNewView = !canReapplyRemoteView(result.newContentView, entry.cachedContentView);
+            boolean isNewView =
+                    !canReapplyRemoteView(result.newContentView,
+                            cachedContentViews.get(FLAG_CONTENT_VIEW_CONTRACTED));
             ApplyCallback applyCallback = new ApplyCallback() {
                 @Override
                 public void setResultView(View v) {
@@ -222,18 +382,19 @@
                     return result.newContentView;
                 }
             };
-            applyRemoteView(result, reInflateFlags, flag, row, redactAmbient,
-                    isNewView, remoteViewClickHandler, callback, entry, privateLayout,
+            applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row, redactAmbient,
+                    isNewView, remoteViewClickHandler, callback, privateLayout,
                     privateLayout.getContractedChild(), privateLayout.getVisibleWrapper(
                             NotificationContentView.VISIBLE_TYPE_CONTRACTED),
                     runningInflations, applyCallback);
         }
 
-        flag = FLAG_REINFLATE_EXPANDED_VIEW;
+        flag = FLAG_CONTENT_VIEW_EXPANDED;
         if ((reInflateFlags & flag) != 0) {
             if (result.newExpandedView != null) {
-                boolean isNewView = !canReapplyRemoteView(result.newExpandedView,
-                        entry.cachedBigContentView);
+                boolean isNewView =
+                        !canReapplyRemoteView(result.newExpandedView,
+                                cachedContentViews.get(FLAG_CONTENT_VIEW_EXPANDED));
                 ApplyCallback applyCallback = new ApplyCallback() {
                     @Override
                     public void setResultView(View v) {
@@ -245,8 +406,8 @@
                         return result.newExpandedView;
                     }
                 };
-                applyRemoteView(result, reInflateFlags, flag, row,
-                        redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
+                applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row,
+                        redactAmbient, isNewView, remoteViewClickHandler, callback,
                         privateLayout, privateLayout.getExpandedChild(),
                         privateLayout.getVisibleWrapper(
                                 NotificationContentView.VISIBLE_TYPE_EXPANDED), runningInflations,
@@ -254,11 +415,12 @@
             }
         }
 
-        flag = FLAG_REINFLATE_HEADS_UP_VIEW;
+        flag = FLAG_CONTENT_VIEW_HEADS_UP;
         if ((reInflateFlags & flag) != 0) {
             if (result.newHeadsUpView != null) {
-                boolean isNewView = !canReapplyRemoteView(result.newHeadsUpView,
-                        entry.cachedHeadsUpContentView);
+                boolean isNewView =
+                        !canReapplyRemoteView(result.newHeadsUpView,
+                                cachedContentViews.get(FLAG_CONTENT_VIEW_HEADS_UP));
                 ApplyCallback applyCallback = new ApplyCallback() {
                     @Override
                     public void setResultView(View v) {
@@ -270,19 +432,20 @@
                         return result.newHeadsUpView;
                     }
                 };
-                applyRemoteView(result, reInflateFlags, flag, row,
-                        redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
+                applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row,
+                        redactAmbient, isNewView, remoteViewClickHandler, callback,
                         privateLayout, privateLayout.getHeadsUpChild(),
                         privateLayout.getVisibleWrapper(
-                                NotificationContentView.VISIBLE_TYPE_HEADSUP), runningInflations,
+                                VISIBLE_TYPE_HEADSUP), runningInflations,
                         applyCallback);
             }
         }
 
-        flag = FLAG_REINFLATE_PUBLIC_VIEW;
+        flag = FLAG_CONTENT_VIEW_PUBLIC;
         if ((reInflateFlags & flag) != 0) {
-            boolean isNewView = !canReapplyRemoteView(result.newPublicView,
-                    entry.cachedPublicContentView);
+            boolean isNewView =
+                    !canReapplyRemoteView(result.newPublicView,
+                            cachedContentViews.get(FLAG_CONTENT_VIEW_PUBLIC));
             ApplyCallback applyCallback = new ApplyCallback() {
                 @Override
                 public void setResultView(View v) {
@@ -294,18 +457,19 @@
                     return result.newPublicView;
                 }
             };
-            applyRemoteView(result, reInflateFlags, flag, row,
-                    redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
+            applyRemoteView(result, reInflateFlags, flag, cachedContentViews, row,
+                    redactAmbient, isNewView, remoteViewClickHandler, callback,
                     publicLayout, publicLayout.getContractedChild(),
                     publicLayout.getVisibleWrapper(NotificationContentView.VISIBLE_TYPE_CONTRACTED),
                     runningInflations, applyCallback);
         }
 
-        flag = FLAG_REINFLATE_AMBIENT_VIEW;
+        flag = FLAG_CONTENT_VIEW_AMBIENT;
         if ((reInflateFlags & flag) != 0) {
             NotificationContentView newParent = redactAmbient ? publicLayout : privateLayout;
-            boolean isNewView = !canReapplyAmbient(row, redactAmbient) ||
-                    !canReapplyRemoteView(result.newAmbientView, entry.cachedAmbientContentView);
+            boolean isNewView = (!canReapplyAmbient(row, redactAmbient)
+                    || !canReapplyRemoteView(result.newAmbientView,
+                            cachedContentViews.get(FLAG_CONTENT_VIEW_AMBIENT)));
             ApplyCallback applyCallback = new ApplyCallback() {
                 @Override
                 public void setResultView(View v) {
@@ -317,15 +481,15 @@
                     return result.newAmbientView;
                 }
             };
-            applyRemoteView(result, reInflateFlags, flag, row,
-                    redactAmbient, isNewView, remoteViewClickHandler, callback, entry,
+            applyRemoteView(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, runningInflations, callback, row,
+        finishIfDone(result, reInflateFlags, cachedContentViews, runningInflations, callback, row,
                 redactAmbient);
         CancellationSignal cancellationSignal = new CancellationSignal();
         cancellationSignal.setOnCancelListener(
@@ -335,11 +499,11 @@
 
     @VisibleForTesting
     static void applyRemoteView(final InflationProgress result,
-            final int reInflateFlags, int inflationId,
-            final ExpandableNotificationRow row,
-            final boolean redactAmbient, boolean isNewView,
+            final @InflationFlag int reInflateFlags, @InflationFlag int inflationId,
+            final ArrayMap<Integer, RemoteViews> cachedContentViews,
+            final ExpandableNotificationRow row, final boolean redactAmbient, boolean isNewView,
             RemoteViews.OnClickHandler remoteViewClickHandler,
-            @Nullable final InflationCallback callback, NotificationData.Entry entry,
+            @Nullable final InflationCallback callback,
             NotificationContentView parentLayout, View existingView,
             NotificationViewWrapper existingWrapper,
             final HashMap<Integer, CancellationSignal> runningInflations,
@@ -362,7 +526,7 @@
                     existingWrapper.onReinflated();
                 }
             } catch (Exception e) {
-                handleInflationError(runningInflations, e, entry.notification, callback);
+                handleInflationError(runningInflations, e, row.getStatusBarNotification(), callback);
                 // Add a running inflation to make sure we don't trigger callbacks.
                 // Safe to do because only happens in tests.
                 runningInflations.put(inflationId, new CancellationSignal());
@@ -381,8 +545,8 @@
                     existingWrapper.onReinflated();
                 }
                 runningInflations.remove(inflationId);
-                finishIfDone(result, reInflateFlags, runningInflations, callback, row,
-                        redactAmbient);
+                finishIfDone(result, reInflateFlags, cachedContentViews, runningInflations,
+                        callback, row, redactAmbient);
             }
 
             @Override
@@ -407,7 +571,8 @@
                     onViewApplied(newView);
                 } catch (Exception anotherException) {
                     runningInflations.remove(inflationId);
-                    handleInflationError(runningInflations, e, entry.notification, callback);
+                    handleInflationError(runningInflations, e, row.getStatusBarNotification(),
+                            callback);
                 }
             }
         };
@@ -430,8 +595,9 @@
         runningInflations.put(inflationId, cancellationSignal);
     }
 
-    private static void handleInflationError(HashMap<Integer, CancellationSignal> runningInflations,
-            Exception e, StatusBarNotification notification, @Nullable InflationCallback callback) {
+    private static void handleInflationError(
+            HashMap<Integer, CancellationSignal> runningInflations, Exception e,
+            StatusBarNotification notification, @Nullable InflationCallback callback) {
         Assert.isMainThread();
         runningInflations.values().forEach(CancellationSignal::cancel);
         if (callback != null) {
@@ -444,7 +610,8 @@
      *
      * @return true if the inflation was finished
      */
-    private static boolean finishIfDone(InflationProgress result, int reInflateFlags,
+    private static boolean finishIfDone(InflationProgress result,
+            @InflationFlag int reInflateFlags, ArrayMap<Integer, RemoteViews> cachedContentViews,
             HashMap<Integer, CancellationSignal> runningInflations,
             @Nullable InflationCallback endListener, ExpandableNotificationRow row,
             boolean redactAmbient) {
@@ -453,40 +620,40 @@
         NotificationContentView privateLayout = row.getPrivateLayout();
         NotificationContentView publicLayout = row.getPublicLayout();
         if (runningInflations.isEmpty()) {
-            if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
+            if ((reInflateFlags & FLAG_CONTENT_VIEW_CONTRACTED) != 0) {
                 if (result.inflatedContentView != null) {
                     privateLayout.setContractedChild(result.inflatedContentView);
                 }
-                entry.cachedContentView = result.newContentView;
+                cachedContentViews.put(FLAG_CONTENT_VIEW_CONTRACTED, result.newContentView);
             }
 
-            if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
+            if ((reInflateFlags & FLAG_CONTENT_VIEW_EXPANDED) != 0) {
                 if (result.inflatedExpandedView != null) {
                     privateLayout.setExpandedChild(result.inflatedExpandedView);
                 } else if (result.newExpandedView == null) {
                     privateLayout.setExpandedChild(null);
                 }
-                entry.cachedBigContentView = result.newExpandedView;
+                cachedContentViews.put(FLAG_CONTENT_VIEW_EXPANDED, result.newExpandedView);
                 row.setExpandable(result.newExpandedView != null);
             }
 
-            if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
+            if ((reInflateFlags & FLAG_CONTENT_VIEW_HEADS_UP) != 0) {
                 if (result.inflatedHeadsUpView != null) {
                     privateLayout.setHeadsUpChild(result.inflatedHeadsUpView);
                 } else if (result.newHeadsUpView == null) {
                     privateLayout.setHeadsUpChild(null);
                 }
-                entry.cachedHeadsUpContentView = result.newHeadsUpView;
+                cachedContentViews.put(FLAG_CONTENT_VIEW_HEADS_UP, result.newHeadsUpView);
             }
 
-            if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
+            if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) {
                 if (result.inflatedPublicView != null) {
                     publicLayout.setContractedChild(result.inflatedPublicView);
                 }
-                entry.cachedPublicContentView = result.newPublicView;
+                cachedContentViews.put(FLAG_CONTENT_VIEW_PUBLIC, result.newPublicView);
             }
 
-            if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
+            if ((reInflateFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
                 if (result.inflatedAmbientView != null) {
                     NotificationContentView newParent = redactAmbient
                             ? publicLayout : privateLayout;
@@ -495,12 +662,12 @@
                     newParent.setAmbientChild(result.inflatedAmbientView);
                     otherParent.setAmbientChild(null);
                 }
-                entry.cachedAmbientContentView = result.newAmbientView;
+                cachedContentViews.put(FLAG_CONTENT_VIEW_AMBIENT, result.newAmbientView);
             }
             entry.headsUpStatusBarText = result.headsUpStatusBarText;
             entry.headsUpStatusBarTextPublic = result.headsUpStatusBarTextPublic;
             if (endListener != null) {
-                endListener.onAsyncInflationFinished(row.getEntry());
+                endListener.onAsyncInflationFinished(row.getEntry(), reInflateFlags);
             }
             return true;
         }
@@ -552,7 +719,15 @@
 
     public interface InflationCallback {
         void handleInflationException(StatusBarNotification notification, Exception e);
-        void onAsyncInflationFinished(NotificationData.Entry entry);
+
+        /**
+         * Callback for after the content views finish inflating.
+         *
+         * @param entry the entry with the content views set
+         * @param inflatedFlags the flags associated with the content views that were inflated
+         */
+        void onAsyncInflationFinished(NotificationData.Entry entry,
+                @InflationFlag int inflatedFlags);
 
         /**
          * Used to disable async-ness for tests. Should only be used for tests.
@@ -563,18 +738,13 @@
     }
 
     public void clearCachesAndReInflate() {
-        NotificationData.Entry entry = mRow.getEntry();
-        entry.cachedAmbientContentView = null;
-        entry.cachedBigContentView = null;
-        entry.cachedContentView = null;
-        entry.cachedHeadsUpContentView = null;
-        entry.cachedPublicContentView = null;
+        mCachedContentViews.clear();
         inflateNotificationViews();
     }
 
     private static boolean canReapplyAmbient(ExpandableNotificationRow row, boolean redactAmbient) {
         NotificationContentView ambientView = redactAmbient ? row.getPublicLayout()
-                : row.getPrivateLayout();            ;
+                : row.getPrivateLayout();
         return ambientView.getAmbientChild() != null;
     }
 
@@ -589,7 +759,8 @@
         private final InflationCallback mCallback;
         private final boolean mUsesIncreasedHeadsUpHeight;
         private final boolean mRedactAmbient;
-        private int mReInflateFlags;
+        private @InflationFlag int mReInflateFlags;
+        private final ArrayMap<Integer, RemoteViews> mCachedContentViews;
         private ExpandableNotificationRow mRow;
         private Exception mError;
         private RemoteViews.OnClickHandler mRemoteViewClickHandler;
@@ -597,15 +768,16 @@
         private List<Notification.Action> mSmartActions;
 
         private AsyncInflationTask(StatusBarNotification notification,
-                int reInflateFlags, ExpandableNotificationRow row, boolean isLowPriority,
-                boolean isChildInGroup, boolean usesIncreasedHeight,
+                @InflationFlag int reInflateFlags,
+                ArrayMap<Integer, RemoteViews> cachedContentViews, ExpandableNotificationRow row,
+                boolean isLowPriority, boolean isChildInGroup, boolean usesIncreasedHeight,
                 boolean usesIncreasedHeadsUpHeight, boolean redactAmbient,
-                InflationCallback callback,
-                RemoteViews.OnClickHandler remoteViewClickHandler,
+                InflationCallback callback, RemoteViews.OnClickHandler remoteViewClickHandler,
                 List<Notification.Action> smartActions) {
             mRow = row;
             mSbn = notification;
             mReInflateFlags = reInflateFlags;
+            mCachedContentViews = cachedContentViews;
             mContext = mRow.getContext();
             mIsLowPriority = isLowPriority;
             mIsChildInGroup = isChildInGroup;
@@ -622,6 +794,7 @@
         }
 
         @VisibleForTesting
+        @InflationFlag
         public int getReInflateFlags() {
             return mReInflateFlags;
         }
@@ -642,10 +815,9 @@
                             packageContext);
                     processor.processNotification(notification, recoveredBuilder);
                 }
-                return createRemoteViews(mReInflateFlags,
-                        recoveredBuilder, mIsLowPriority, mIsChildInGroup,
-                        mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight, mRedactAmbient,
-                        packageContext);
+                return createRemoteViews(mReInflateFlags, recoveredBuilder, mIsLowPriority,
+                        mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
+                        mRedactAmbient, packageContext);
             } catch (Exception e) {
                 mError = e;
                 return null;
@@ -655,8 +827,8 @@
         @Override
         protected void onPostExecute(InflationProgress result) {
             if (mError == null) {
-                mCancellationSignal = apply(result, mReInflateFlags, mRow, mRedactAmbient,
-                        mRemoteViewClickHandler, this);
+                mCancellationSignal = apply(result, mReInflateFlags, mCachedContentViews, mRow,
+                        mRedactAmbient, mRemoteViewClickHandler, this);
             } else {
                 handleError(mError);
             }
@@ -706,10 +878,11 @@
         }
 
         @Override
-        public void onAsyncInflationFinished(NotificationData.Entry entry) {
+        public void onAsyncInflationFinished(NotificationData.Entry entry,
+                @InflationFlag int inflatedFlags) {
             mRow.getEntry().onInflationTaskFinished();
             mRow.onNotificationUpdated();
-            mCallback.onAsyncInflationFinished(mRow.getEntry());
+            mCallback.onAsyncInflationFinished(mRow.getEntry(), inflatedFlags);
         }
 
         @Override
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 2ca7282..f76284d 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
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.row.wrapper;
 
 import android.content.Context;
+import android.graphics.Color;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.view.NotificationHeaderView;
@@ -76,8 +77,11 @@
         }
         Drawable background = mView.getBackground();
         if (background instanceof ColorDrawable) {
-            mBackgroundColor = ((ColorDrawable) background).getColor();
-            mView.setBackground(null);
+            int backgroundColor = ((ColorDrawable) background).getColor();
+            if (backgroundColor != Color.TRANSPARENT) {
+                mBackgroundColor = backgroundColor;
+                mView.setBackground(new ColorDrawable(Color.TRANSPARENT));
+            }
         }
     }
 
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 8969aca..0577841 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
@@ -426,6 +426,10 @@
         return mDarkAmount == 1;
     }
 
+    public boolean isDarkAtAll() {
+        return mDarkAmount != 0;
+    }
+
     public void setDarkTopPadding(int darkTopPadding) {
         mDarkTopPadding = darkTopPadding;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index fa75c71..cfb6d99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -22,6 +22,7 @@
 import android.view.ViewGroup;
 
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
+import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.NotificationData;
@@ -31,7 +32,8 @@
  * Interface representing the entity that contains notifications. It can have
  * notification views added and removed from it, and will manage displaying them to the user.
  */
-public interface NotificationListContainer {
+public interface NotificationListContainer extends ExpandableView.OnHeightChangedListener,
+        VisibilityLocationProvider {
 
     /**
      * Called when a child is being transferred.
@@ -128,14 +130,6 @@
     ViewGroup getViewParentForNotification(NotificationData.Entry entry);
 
     /**
-     * Called when the height of an expandable view changes.
-     *
-     * @param view view whose height changed
-     * @param animate whether this change should be animated
-     */
-    void onHeightChanged(ExpandableView view, boolean animate);
-
-    /**
      * Resets the currently exposed menu view.
      *
      * @param animate whether to animate the closing/change of menu view
@@ -158,13 +152,6 @@
      */
     void cleanUpViewState(View view);
 
-    /**
-     * Returns whether an ExpandableNotificationRow is in a visible location or not.
-     *
-     * @param row
-     * @return true if row is in a visible location
-     */
-    boolean isInVisibleLocation(ExpandableNotificationRow row);
 
     /**
      * Sets a listener to listen for changes in notification locations.
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 9978ec3..30d1701 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
@@ -25,7 +25,7 @@
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeAnimator;
 import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.WallpaperManager;
 import android.content.Context;
@@ -40,15 +40,9 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.os.Bundle;
-import android.os.Handler;
 import android.os.ServiceManager;
 import android.provider.Settings;
 import android.service.notification.StatusBarNotification;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-import androidx.core.graphics.ColorUtils;
-
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
@@ -71,6 +65,8 @@
 import android.widget.OverScroller;
 import android.widget.ScrollView;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
@@ -82,51 +78,50 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.SwipeHelper;
-import com.android.systemui.SwipeHelper.Callback;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEventListener;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.DragDownHelper.DragDownCallback;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.RemoteInputController;
-import com.android.systemui.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
 import com.android.systemui.statusbar.EmptyShadeView;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.ExpandableView;
-import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
-import com.android.systemui.statusbar.notification.row.FooterView;
-import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
-import com.android.systemui.statusbar.notification.NotificationData;
-import com.android.systemui.statusbar.notification.row.NotificationGuts;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShelf;
-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.RemoteInputController;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarStateController.StateListener;
 import com.android.systemui.statusbar.notification.FakeShadowView;
+import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.ShadeViewRefactor;
 import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent;
-import com.android.systemui.statusbar.notification.VisibilityLocationProvider;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+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.notification.row.FooterView;
+import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
+import com.android.systemui.statusbar.notification.row.NotificationGuts;
+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.HeadsUpManagerPhone.AnimationStateHandler;
+import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
 import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.NotificationGroupManager.OnGroupChangeListener;
 import com.android.systemui.statusbar.phone.NotificationIconAreaController;
 import com.android.systemui.statusbar.phone.NotificationPanelView;
 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.policy.ConfigurationController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -145,10 +140,8 @@
 /**
  * A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
  */
-public class NotificationStackScrollLayout extends ViewGroup
-        implements ExpandHelper.Callback, ScrollAdapter, OnHeightChangedListener,
-        OnGroupChangeListener, VisibilityLocationProvider, NotificationListContainer,
-        ConfigurationListener, DragDownCallback, AnimationStateHandler, Dumpable {
+public class NotificationStackScrollLayout extends ViewGroup implements ScrollAdapter,
+        NotificationListContainer, ConfigurationListener, Dumpable {
 
     public static final float BACKGROUND_ALPHA_DIMMED = 0.7f;
     private static final String TAG = "StackScroller";
@@ -163,7 +156,6 @@
 
     private ExpandHelper mExpandHelper;
     private final NotificationSwipeHelper mSwipeHelper;
-    private boolean mSwipingInProgress;
     private int mCurrentStackHeight = Integer.MAX_VALUE;
     private final Paint mBackgroundPaint = new Paint();
     private final boolean mShouldDrawNotificationBackground;
@@ -200,7 +192,7 @@
     // Current padding, will be either mRegularTopPadding or mDarkTopPadding
     private int mTopPadding;
     // Distance between AOD separator and shelf
-    private int mDarkSeparatorPadding;
+    private int mDarkShelfPadding;
     private int mBottomMargin;
     private int mBottomInset = 0;
     private float mQsExpansionFraction;
@@ -347,7 +339,7 @@
     private float mDimAmount;
     private ValueAnimator mDimAnimator;
     private ArrayList<ExpandableView> mTmpSortedChildren = new ArrayList<>();
-    private Animator.AnimatorListener mDimEndListener = new AnimatorListenerAdapter() {
+    private final Animator.AnimatorListener mDimEndListener = new AnimatorListenerAdapter() {
         @Override
         public void onAnimationEnd(Animator animation) {
             mDimAnimator = null;
@@ -429,8 +421,6 @@
     private Runnable mAnimateScroll = this::animateScroll;
     private int mCornerRadius;
     private int mSidePaddings;
-    private final int mSeparatorWidth;
-    private final int mSeparatorThickness;
     private final Rect mBackgroundAnimationRect = new Rect();
     private int mAntiBurnInOffsetX;
     private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
@@ -440,6 +430,8 @@
     private float mVerticalPanelTranslation;
     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);
@@ -459,6 +451,7 @@
 
     private Interpolator mDarkXInterpolator = Interpolators.FAST_OUT_SLOW_IN;
     private NotificationPanelView mNotificationPanel;
+    private final ShadeController mShadeController = Dependency.get(ShadeController.class);
 
     private final NotificationGutsManager
             mNotificationGutsManager = Dependency.get(NotificationGutsManager.class);
@@ -488,12 +481,12 @@
         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);
-        mExpandHelper = new ExpandHelper(getContext(), this,
+        mExpandHelper = new ExpandHelper(getContext(), mExpandHelperCallback,
                 minHeight, maxHeight);
         mExpandHelper.setEventSource(this);
         mExpandHelper.setScrollAdapter(this);
-        mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, new SwipeHelperCallback(),
-                getContext(), new NotificationMenuListener());
+        mSwipeHelper = new NotificationSwipeHelper(SwipeHelper.X, mNotificationCallback,
+                getContext(), mMenuEventListener);
         mStackScrollAlgorithm = createStackScrollAlgorithm(context);
         initView(context);
         mFalsingManager = FalsingManager.getInstance(context);
@@ -501,9 +494,7 @@
                 res.getBoolean(R.bool.config_drawNotificationBackground);
         mFadeNotificationsOnDismiss =
                 res.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
-        mSeparatorWidth = res.getDimensionPixelSize(R.dimen.widget_separator_width);
-        mSeparatorThickness = res.getDimensionPixelSize(R.dimen.widget_separator_thickness);
-        mDarkSeparatorPadding = res.getDimensionPixelSize(R.dimen.widget_bottom_separator_padding);
+        mDarkShelfPadding = res.getDimensionPixelSize(R.dimen.widget_bottom_separator_padding);
         mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
         mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
         addOnExpandedHeightListener(mRoundnessManager::setExpanded);
@@ -533,7 +524,7 @@
 
         inflateEmptyShadeView();
         inflateFooterView();
-        mVisualStabilityManager.setVisibilityLocationProvider(this);
+        mVisualStabilityManager.setVisibilityLocationProvider(this::isInVisibleLocation);
         setLongPressListener(mEntryManager.getNotificationLongClicker());
     }
 
@@ -592,7 +583,7 @@
         return false;
     }
 
-  @ShadeViewRefactor(RefactorComponent.INPUT)
+  @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
   public RemoteInputController.Delegate createDelegate() {
         return new RemoteInputController.Delegate() {
             public void setRemoteInputActive(NotificationData.Entry entry,
@@ -631,7 +622,7 @@
     }
 
     @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public NotificationSwipeActionHelper getSwipeActionHelper() {
         return mSwipeHelper;
     }
@@ -675,23 +666,15 @@
         final int lockScreenRight = getWidth() - mSidePaddings;
         final int lockScreenTop = mCurrentBounds.top;
         final int lockScreenBottom = mCurrentBounds.bottom;
-        int separatorWidth = 0;
-        int separatorThickness = 0;
-        if (mIconAreaController.hasShelfIconsWhenFullyDark()) {
-            separatorThickness = mSeparatorThickness;
-            separatorWidth = mSeparatorWidth;
-        }
-        final int darkLeft = getWidth() / 2 - separatorWidth / 2;
-        final int darkRight = darkLeft + separatorWidth;
-        final int darkTop = (int) (mRegularTopPadding + separatorThickness / 2f);
-        final int darkBottom = darkTop + separatorThickness;
+        final int darkLeft = getWidth() / 2;
+        final int darkTop = mRegularTopPadding;
 
         if (mAmbientState.hasPulsingNotifications()) {
             // No divider, we have a notification icon instead
         } else if (mAmbientState.isFullyDark()) {
             // Only draw divider on AOD if we actually have notifications
             if (mFirstVisibleBackgroundChild != null) {
-                canvas.drawRect(darkLeft, darkTop, darkRight, darkBottom, mBackgroundPaint);
+                canvas.drawRect(darkLeft, darkTop, darkLeft, darkTop, mBackgroundPaint);
             }
         } else {
             float yProgress = 1 - mInterpolatedDarkAmount;
@@ -701,8 +684,8 @@
             mBackgroundAnimationRect.set(
                     (int) MathUtils.lerp(darkLeft, lockScreenLeft, xProgress),
                     (int) MathUtils.lerp(darkTop, lockScreenTop, yProgress),
-                    (int) MathUtils.lerp(darkRight, lockScreenRight, xProgress),
-                    (int) MathUtils.lerp(darkBottom, lockScreenBottom, yProgress));
+                    (int) MathUtils.lerp(darkLeft, lockScreenRight, xProgress),
+                    (int) MathUtils.lerp(darkTop, lockScreenBottom, yProgress));
 
             if (!mAmbientState.isDark() || mFirstVisibleBackgroundChild != null) {
                 canvas.drawRoundRect(mBackgroundAnimationRect.left, mBackgroundAnimationRect.top,
@@ -1015,7 +998,7 @@
     private void setTopPadding(int topPadding, boolean animate) {
         if (mRegularTopPadding != topPadding) {
             mRegularTopPadding = topPadding;
-            mDarkTopPadding = topPadding + mDarkSeparatorPadding;
+            mDarkTopPadding = topPadding + mDarkShelfPadding;
             mAmbientState.setDarkTopPadding(mDarkTopPadding);
             updateAlgorithmHeightAndPadding();
             updateContentHeight();
@@ -1248,11 +1231,6 @@
         return firstChild != null ? firstChild.getMinHeight() : mCollapsedSize;
     }
 
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void setLongPressListener(ExpandableNotificationRow.LongPressListener listener) {
-        mLongPressListener = listener;
-    }
-
     @ShadeViewRefactor(RefactorComponent.ADAPTER)
     public void setQsContainer(ViewGroup qsContainer) {
         mQsContainer = qsContainer;
@@ -1276,7 +1254,7 @@
         return false;
     }
 
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     public ExpandableView getClosestChildAtRawPosition(float touchX, float touchY) {
         getLocationOnScreen(mTempInt2);
         float localTouchY = touchY - mTempInt2[1];
@@ -1306,16 +1284,8 @@
         return closestChild;
     }
 
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public ExpandableView getChildAtRawPosition(float touchX, float touchY) {
-        getLocationOnScreen(mTempInt2);
-        return getChildAtPosition(touchX - mTempInt2[0], touchY - mTempInt2[1]);
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public ExpandableView getChildAtPosition(float touchX, float touchY) {
+    @ShadeViewRefactor(RefactorComponent.COORDINATOR)
+    private ExpandableView getChildAtPosition(float touchX, float touchY) {
         return getChildAtPosition(touchX, touchY, true /* requireMinHeight */);
 
     }
@@ -1328,7 +1298,7 @@
      * @param requireMinHeight Whether a minimum height is required for a child to be returned.
      * @return the child at the given location.
      */
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     private ExpandableView getChildAtPosition(float touchX, float touchY,
             boolean requireMinHeight) {
         // find the view under the pointer, accounting for GONE views
@@ -1368,71 +1338,9 @@
         return null;
     }
 
-    @Override
-    @ShadeViewRefactor(RefactorComponent.ADAPTER)
-    public boolean canChildBeExpanded(View v) {
-        return v instanceof ExpandableNotificationRow
-                && ((ExpandableNotificationRow) v).isExpandable()
-                && !((ExpandableNotificationRow) v).areGutsExposed()
-                && (mIsExpanded || !((ExpandableNotificationRow) v).isPinned());
-    }
-
-    /* Only ever called as a consequence of an expansion gesture in the shade. */
-    @Override
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setUserExpandedChild(View v, boolean userExpanded) {
-        if (v instanceof ExpandableNotificationRow) {
-            ExpandableNotificationRow row = (ExpandableNotificationRow) v;
-            if (userExpanded && onKeyguard()) {
-                // Due to a race when locking the screen while touching, a notification may be
-                // expanded even after we went back to keyguard. An example of this happens if
-                // you click in the empty space while expanding a group.
-
-                // We also need to un-user lock it here, since otherwise the content height
-                // calculated might be wrong. We also can't invert the two calls since
-                // un-userlocking it will trigger a layout switch in the content view.
-                row.setUserLocked(false);
-                updateContentHeight();
-                notifyHeightChangeListener(row);
-                return;
-            }
-            row.setUserExpanded(userExpanded, true /* allowChildrenExpansion */);
-            row.onExpandedByGesture(userExpanded);
-        }
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setExpansionCancelled(View v) {
-        if (v instanceof ExpandableNotificationRow) {
-            ((ExpandableNotificationRow) v).setGroupExpansionChanging(false);
-        }
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void setUserLockedChild(View v, boolean userLocked) {
-        if (v instanceof ExpandableNotificationRow) {
-            ((ExpandableNotificationRow) v).setUserLocked(userLocked);
-        }
-        cancelLongPress();
-        requestDisallowInterceptTouchEvent(true);
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
-    public void expansionStateChanged(boolean isExpanding) {
-        mExpandingNotification = isExpanding;
-        if (!mExpandedInThisMotion) {
-            mMaxScrollAfterExpand = mOwnScrollY;
-            mExpandedInThisMotion = true;
-        }
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.COORDINATOR)
-    public int getMaxExpandHeight(ExpandableView view) {
-        return view.getMaxContentHeight();
+    private ExpandableView getChildAtRawPosition(float touchX, float touchY) {
+        getLocationOnScreen(mTempInt2);
+        return getChildAtPosition(touchX - mTempInt2[0], touchY - mTempInt2[1]);
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -1529,14 +1437,6 @@
         return mStatusBarState == StatusBarState.KEYGUARD;
     }
 
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void setSwipingInProgress(boolean isSwiped) {
-        mSwipingInProgress = isSwiped;
-        if (isSwiped) {
-            requestDisallowInterceptTouchEvent(true);
-        }
-    }
-
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     protected void onConfigurationChanged(Configuration newConfig) {
@@ -1570,249 +1470,6 @@
         return this;
     }
 
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean onTouchEvent(MotionEvent ev) {
-        boolean isCancelOrUp = ev.getActionMasked() == MotionEvent.ACTION_CANCEL
-                || ev.getActionMasked() == MotionEvent.ACTION_UP;
-        handleEmptySpaceClick(ev);
-        boolean expandWantsIt = false;
-        if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion) {
-            if (isCancelOrUp) {
-                mExpandHelper.onlyObserveMovements(false);
-            }
-            boolean wasExpandingBefore = mExpandingNotification;
-            expandWantsIt = mExpandHelper.onTouchEvent(ev);
-            if (mExpandedInThisMotion && !mExpandingNotification && wasExpandingBefore
-                    && !mDisallowScrollingInThisMotion) {
-                dispatchDownEventToScroller(ev);
-            }
-        }
-        boolean scrollerWantsIt = false;
-        if (mIsExpanded && !mSwipingInProgress && !mExpandingNotification
-                && !mDisallowScrollingInThisMotion) {
-            scrollerWantsIt = onScrollTouch(ev);
-        }
-        boolean horizontalSwipeWantsIt = false;
-        if (!mIsBeingDragged
-                && !mExpandingNotification
-                && !mExpandedInThisMotion
-                && !mOnlyScrollingInThisMotion
-                && !mDisallowDismissInThisMotion) {
-            horizontalSwipeWantsIt = mSwipeHelper.onTouchEvent(ev);
-        }
-
-        // Check if we need to clear any snooze leavebehinds
-        NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
-        if (guts != null && !NotificationSwipeHelper.isTouchInView(ev, guts)
-                && guts.getGutsContent() instanceof NotificationSnooze) {
-            NotificationSnooze ns = (NotificationSnooze) guts.getGutsContent();
-            if ((ns.isExpanded() && isCancelOrUp)
-                    || (!horizontalSwipeWantsIt && scrollerWantsIt)) {
-                // If the leavebehind is expanded we clear it on the next up event, otherwise we
-                // clear it on the next non-horizontal swipe or expand event.
-                checkSnoozeLeavebehind();
-            }
-        }
-        if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
-            mCheckForLeavebehind = true;
-        }
-        return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || super.onTouchEvent(ev);
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void dispatchDownEventToScroller(MotionEvent ev) {
-        MotionEvent downEvent = MotionEvent.obtain(ev);
-        downEvent.setAction(MotionEvent.ACTION_DOWN);
-        onScrollTouch(downEvent);
-        downEvent.recycle();
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean onGenericMotionEvent(MotionEvent event) {
-        if (!isScrollingEnabled() || !mIsExpanded || mSwipingInProgress || mExpandingNotification
-                || mDisallowScrollingInThisMotion) {
-            return false;
-        }
-        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_SCROLL: {
-                    if (!mIsBeingDragged) {
-                        final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
-                        if (vscroll != 0) {
-                            final int delta = (int) (vscroll * getVerticalScrollFactor());
-                            final int range = getScrollRange();
-                            int oldScrollY = mOwnScrollY;
-                            int newScrollY = oldScrollY - delta;
-                            if (newScrollY < 0) {
-                                newScrollY = 0;
-                            } else if (newScrollY > range) {
-                                newScrollY = range;
-                            }
-                            if (newScrollY != oldScrollY) {
-                                setOwnScrollY(newScrollY);
-                                return true;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return super.onGenericMotionEvent(event);
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private boolean onScrollTouch(MotionEvent ev) {
-        if (!isScrollingEnabled()) {
-            return false;
-        }
-        if (isInsideQsContainer(ev) && !mIsBeingDragged) {
-            return false;
-        }
-        mForcedScroll = null;
-        initVelocityTrackerIfNotExists();
-        mVelocityTracker.addMovement(ev);
-
-        final int action = ev.getAction();
-
-        switch (action & MotionEvent.ACTION_MASK) {
-            case MotionEvent.ACTION_DOWN: {
-                if (getChildCount() == 0 || !isInContentBounds(ev)) {
-                    return false;
-                }
-                boolean isBeingDragged = !mScroller.isFinished();
-                setIsBeingDragged(isBeingDragged);
-                /*
-                 * If being flinged and user touches, stop the fling. isFinished
-                 * will be false if being flinged.
-                 */
-                if (!mScroller.isFinished()) {
-                    mScroller.forceFinished(true);
-                }
-
-                // Remember where the motion event started
-                mLastMotionY = (int) ev.getY();
-                mDownX = (int) ev.getX();
-                mActivePointerId = ev.getPointerId(0);
-                break;
-            }
-            case MotionEvent.ACTION_MOVE:
-                final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
-                if (activePointerIndex == -1) {
-                    Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
-                    break;
-                }
-
-                final int y = (int) ev.getY(activePointerIndex);
-                final int x = (int) ev.getX(activePointerIndex);
-                int deltaY = mLastMotionY - y;
-                final int xDiff = Math.abs(x - mDownX);
-                final int yDiff = Math.abs(deltaY);
-                if (!mIsBeingDragged && yDiff > mTouchSlop && yDiff > xDiff) {
-                    setIsBeingDragged(true);
-                    if (deltaY > 0) {
-                        deltaY -= mTouchSlop;
-                    } else {
-                        deltaY += mTouchSlop;
-                    }
-                }
-                if (mIsBeingDragged) {
-                    // Scroll to follow the motion event
-                    mLastMotionY = y;
-                    int range = getScrollRange();
-                    if (mExpandedInThisMotion) {
-                        range = Math.min(range, mMaxScrollAfterExpand);
-                    }
-
-                    float scrollAmount;
-                    if (deltaY < 0) {
-                        scrollAmount = overScrollDown(deltaY);
-                    } else {
-                        scrollAmount = overScrollUp(deltaY, range);
-                    }
-
-                    // Calling customOverScrollBy will call onCustomOverScrolled, which
-                    // sets the scrolling if applicable.
-                    if (scrollAmount != 0.0f) {
-                        // The scrolling motion could not be compensated with the
-                        // existing overScroll, we have to scroll the view
-                        customOverScrollBy((int) scrollAmount, mOwnScrollY,
-                                range, getHeight() / 2);
-                        // If we're scrolling, leavebehinds should be dismissed
-                        checkSnoozeLeavebehind();
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-                if (mIsBeingDragged) {
-                    final VelocityTracker velocityTracker = mVelocityTracker;
-                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                    int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
-
-                    if (shouldOverScrollFling(initialVelocity)) {
-                        onOverScrollFling(true, initialVelocity);
-                    } else {
-                        if (getChildCount() > 0) {
-                            if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
-                                float currentOverScrollTop = getCurrentOverScrollAmount(true);
-                                if (currentOverScrollTop == 0.0f || initialVelocity > 0) {
-                                    fling(-initialVelocity);
-                                } else {
-                                    onOverScrollFling(false, initialVelocity);
-                                }
-                            } else {
-                                if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0,
-                                        getScrollRange())) {
-                                    animateScroll();
-                                }
-                            }
-                        }
-                    }
-                    mActivePointerId = INVALID_POINTER;
-                    endDrag();
-                }
-
-                break;
-            case MotionEvent.ACTION_CANCEL:
-                if (mIsBeingDragged && getChildCount() > 0) {
-                    if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0, getScrollRange())) {
-                        animateScroll();
-                    }
-                    mActivePointerId = INVALID_POINTER;
-                    endDrag();
-                }
-                break;
-            case MotionEvent.ACTION_POINTER_DOWN: {
-                final int index = ev.getActionIndex();
-                mLastMotionY = (int) ev.getY(index);
-                mDownX = (int) ev.getX(index);
-                mActivePointerId = ev.getPointerId(index);
-                break;
-            }
-            case MotionEvent.ACTION_POINTER_UP:
-                onSecondaryPointerUp(ev);
-                mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));
-                mDownX = (int) ev.getX(ev.findPointerIndex(mActivePointerId));
-                break;
-        }
-        return true;
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    protected boolean isInsideQsContainer(MotionEvent ev) {
-        return ev.getY() < mQsContainer.getBottom();
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void onOverScrollFling(boolean open, int initialVelocity) {
-        if (mOverscrollTopChangedListener != null) {
-            mOverscrollTopChangedListener.flingTopOverscroll(initialVelocity, open);
-        }
-        mDontReportNextOverScroll = true;
-        setOverScrollAmount(0.0f, true, false);
-    }
-
     /**
      * Perform a scroll upwards and adapt the overscroll amounts accordingly
      *
@@ -1820,7 +1477,7 @@
      * @return The amount of scrolling to be performed by the scroller,
      * not handled by the overScroll amount.
      */
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private float overScrollUp(int deltaY, int range) {
         deltaY = Math.max(deltaY, 0);
         float currentTopAmount = getCurrentOverScrollAmount(true);
@@ -1879,24 +1536,6 @@
         return scrollAmount;
     }
 
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void onSecondaryPointerUp(MotionEvent ev) {
-        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
-                MotionEvent.ACTION_POINTER_INDEX_SHIFT;
-        final int pointerId = ev.getPointerId(pointerIndex);
-        if (pointerId == mActivePointerId) {
-            // This was our active pointer going up. Choose a new
-            // active pointer and adjust accordingly.
-            // TODO: Make this decision more intelligent.
-            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
-            mLastMotionY = (int) ev.getY(newPointerIndex);
-            mActivePointerId = ev.getPointerId(newPointerIndex);
-            if (mVelocityTracker != null) {
-                mVelocityTracker.clear();
-            }
-        }
-    }
-
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     private void initVelocityTrackerIfNotExists() {
         if (mVelocityTracker == null) {
@@ -2639,7 +2278,7 @@
      *                  numbers mean that the finger/cursor is moving down the screen,
      *                  which means we want to scroll towards the top.
      */
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     protected void fling(int velocityY) {
         if (getChildCount() > 0) {
             int scrollRange = getScrollRange();
@@ -2677,7 +2316,7 @@
      * @return Whether a fling performed on the top overscroll edge lead to the expanded
      * overScroll view (i.e QS).
      */
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private boolean shouldOverScrollFling(int initialVelocity) {
         float topOverScroll = getCurrentOverScrollAmount(true);
         return mScrolledToTopOnFirstDown
@@ -2760,7 +2399,7 @@
         return Math.max(desiredPadding, mIntrinsicPadding);
     }
 
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private float getRubberBandFactor(boolean onTop) {
         if (!onTop) {
             return RUBBER_BAND_FACTOR_NORMAL;
@@ -2780,99 +2419,13 @@
      * rubberbanded, false if it is technically an overscroll but rather a motion to expand the
      * overscroll view (e.g. expand QS).
      */
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     private boolean isRubberbanded(boolean onTop) {
         return !onTop || mExpandedInThisMotion || mIsExpansionChanging || mPanelTracking
                 || !mScrolledToTopOnFirstDown;
     }
 
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void endDrag() {
-        setIsBeingDragged(false);
 
-        recycleVelocityTracker();
-
-        if (getCurrentOverScrollAmount(true /* onTop */) > 0) {
-            setOverScrollAmount(0, true /* onTop */, true /* animate */);
-        }
-        if (getCurrentOverScrollAmount(false /* onTop */) > 0) {
-            setOverScrollAmount(0, false /* onTop */, true /* animate */);
-        }
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void transformTouchEvent(MotionEvent ev, View sourceView, View targetView) {
-        ev.offsetLocation(sourceView.getX(), sourceView.getY());
-        ev.offsetLocation(-targetView.getX(), -targetView.getY());
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        initDownStates(ev);
-        handleEmptySpaceClick(ev);
-        boolean expandWantsIt = false;
-        if (!mSwipingInProgress && !mOnlyScrollingInThisMotion) {
-            expandWantsIt = mExpandHelper.onInterceptTouchEvent(ev);
-        }
-        boolean scrollWantsIt = false;
-        if (!mSwipingInProgress && !mExpandingNotification) {
-            scrollWantsIt = onInterceptTouchEventScroll(ev);
-        }
-        boolean swipeWantsIt = false;
-        if (!mIsBeingDragged
-                && !mExpandingNotification
-                && !mExpandedInThisMotion
-                && !mOnlyScrollingInThisMotion
-                && !mDisallowDismissInThisMotion) {
-            swipeWantsIt = mSwipeHelper.onInterceptTouchEvent(ev);
-        }
-        // Check if we need to clear any snooze leavebehinds
-        boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
-        NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
-        if (!NotificationSwipeHelper.isTouchInView(ev, guts) && isUp && !swipeWantsIt &&
-                !expandWantsIt && !scrollWantsIt) {
-            mCheckForLeavebehind = false;
-            mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
-                    false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
-                    false /* resetMenu */);
-        }
-        if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
-            mCheckForLeavebehind = true;
-        }
-        return swipeWantsIt || scrollWantsIt || expandWantsIt || super.onInterceptTouchEvent(ev);
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void handleEmptySpaceClick(MotionEvent ev) {
-        switch (ev.getActionMasked()) {
-            case MotionEvent.ACTION_MOVE:
-                if (mTouchIsClick && (Math.abs(ev.getY() - mInitialTouchY) > mTouchSlop
-                        || Math.abs(ev.getX() - mInitialTouchX) > mTouchSlop)) {
-                    mTouchIsClick = false;
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-                if (mStatusBarState != StatusBarState.KEYGUARD && mTouchIsClick &&
-                        isBelowLastNotification(mInitialTouchX, mInitialTouchY)) {
-                    mOnEmptySpaceClickListener.onEmptySpaceClicked(mInitialTouchX, mInitialTouchY);
-                }
-                break;
-        }
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void initDownStates(MotionEvent ev) {
-        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            mExpandedInThisMotion = false;
-            mOnlyScrollingInThisMotion = !mScroller.isFinished();
-            mDisallowScrollingInThisMotion = false;
-            mDisallowDismissInThisMotion = false;
-            mTouchIsClick = true;
-            mInitialTouchX = ev.getX();
-            mInitialTouchY = ev.getY();
-        }
-    }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void setChildTransferInProgress(boolean childTransferInProgress) {
@@ -2899,15 +2452,6 @@
         mCurrentStackScrollState.removeViewStateForView(child);
     }
 
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
-        super.requestDisallowInterceptTouchEvent(disallowIntercept);
-        if (disallowIntercept) {
-            cancelLongPress();
-        }
-    }
-
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     private void onViewRemovedInternal(View child, ViewGroup container) {
         if (mChangePositionInProgress) {
@@ -3603,6 +3147,385 @@
         mGoToFullShadeNeedsAnimation = false;
     }
 
+    @ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
+    protected StackScrollAlgorithm createStackScrollAlgorithm(Context context) {
+        return new StackScrollAlgorithm(context);
+    }
+
+    /**
+     * @return Whether a y coordinate is inside the content.
+     */
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    public boolean isInContentBounds(float y) {
+        return y < getHeight() - getEmptyBottomMargin();
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public void setLongPressListener(ExpandableNotificationRow.LongPressListener listener) {
+        mLongPressListener = listener;
+    }
+
+    @Override
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public boolean onTouchEvent(MotionEvent ev) {
+        boolean isCancelOrUp = ev.getActionMasked() == MotionEvent.ACTION_CANCEL
+                || ev.getActionMasked() == MotionEvent.ACTION_UP;
+        handleEmptySpaceClick(ev);
+        boolean expandWantsIt = false;
+        boolean swipingInProgress = mSwipeHelper.isSwipingInProgress();
+        if (mIsExpanded && !swipingInProgress && !mOnlyScrollingInThisMotion) {
+            if (isCancelOrUp) {
+                mExpandHelper.onlyObserveMovements(false);
+            }
+            boolean wasExpandingBefore = mExpandingNotification;
+            expandWantsIt = mExpandHelper.onTouchEvent(ev);
+            if (mExpandedInThisMotion && !mExpandingNotification && wasExpandingBefore
+                    && !mDisallowScrollingInThisMotion) {
+                dispatchDownEventToScroller(ev);
+            }
+        }
+        boolean scrollerWantsIt = false;
+        if (mIsExpanded && !swipingInProgress && !mExpandingNotification
+                && !mDisallowScrollingInThisMotion) {
+            scrollerWantsIt = onScrollTouch(ev);
+        }
+        boolean horizontalSwipeWantsIt = false;
+        if (!mIsBeingDragged
+                && !mExpandingNotification
+                && !mExpandedInThisMotion
+                && !mOnlyScrollingInThisMotion
+                && !mDisallowDismissInThisMotion) {
+            horizontalSwipeWantsIt = mSwipeHelper.onTouchEvent(ev);
+        }
+
+        // Check if we need to clear any snooze leavebehinds
+        NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
+        if (guts != null && !NotificationSwipeHelper.isTouchInView(ev, guts)
+                && guts.getGutsContent() instanceof NotificationSnooze) {
+            NotificationSnooze ns = (NotificationSnooze) guts.getGutsContent();
+            if ((ns.isExpanded() && isCancelOrUp)
+                    || (!horizontalSwipeWantsIt && scrollerWantsIt)) {
+                // If the leavebehind is expanded we clear it on the next up event, otherwise we
+                // clear it on the next non-horizontal swipe or expand event.
+                checkSnoozeLeavebehind();
+            }
+        }
+        if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
+            mCheckForLeavebehind = true;
+        }
+        return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || super.onTouchEvent(ev);
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private void dispatchDownEventToScroller(MotionEvent ev) {
+        MotionEvent downEvent = MotionEvent.obtain(ev);
+        downEvent.setAction(MotionEvent.ACTION_DOWN);
+        onScrollTouch(downEvent);
+        downEvent.recycle();
+    }
+
+    @Override
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public boolean onGenericMotionEvent(MotionEvent event) {
+        if (!isScrollingEnabled() || !mIsExpanded || mSwipeHelper.isSwipingInProgress() || mExpandingNotification
+                || mDisallowScrollingInThisMotion) {
+            return false;
+        }
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_SCROLL: {
+                    if (!mIsBeingDragged) {
+                        final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
+                        if (vscroll != 0) {
+                            final int delta = (int) (vscroll * getVerticalScrollFactor());
+                            final int range = getScrollRange();
+                            int oldScrollY = mOwnScrollY;
+                            int newScrollY = oldScrollY - delta;
+                            if (newScrollY < 0) {
+                                newScrollY = 0;
+                            } else if (newScrollY > range) {
+                                newScrollY = range;
+                            }
+                            if (newScrollY != oldScrollY) {
+                                setOwnScrollY(newScrollY);
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return super.onGenericMotionEvent(event);
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private boolean onScrollTouch(MotionEvent ev) {
+        if (!isScrollingEnabled()) {
+            return false;
+        }
+        if (isInsideQsContainer(ev) && !mIsBeingDragged) {
+            return false;
+        }
+        mForcedScroll = null;
+        initVelocityTrackerIfNotExists();
+        mVelocityTracker.addMovement(ev);
+
+        final int action = ev.getAction();
+
+        switch (action & MotionEvent.ACTION_MASK) {
+            case MotionEvent.ACTION_DOWN: {
+                if (getChildCount() == 0 || !isInContentBounds(ev)) {
+                    return false;
+                }
+                boolean isBeingDragged = !mScroller.isFinished();
+                setIsBeingDragged(isBeingDragged);
+                /*
+                 * If being flinged and user touches, stop the fling. isFinished
+                 * will be false if being flinged.
+                 */
+                if (!mScroller.isFinished()) {
+                    mScroller.forceFinished(true);
+                }
+
+                // Remember where the motion event started
+                mLastMotionY = (int) ev.getY();
+                mDownX = (int) ev.getX();
+                mActivePointerId = ev.getPointerId(0);
+                break;
+            }
+            case MotionEvent.ACTION_MOVE:
+                final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                if (activePointerIndex == -1) {
+                    Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
+                    break;
+                }
+
+                final int y = (int) ev.getY(activePointerIndex);
+                final int x = (int) ev.getX(activePointerIndex);
+                int deltaY = mLastMotionY - y;
+                final int xDiff = Math.abs(x - mDownX);
+                final int yDiff = Math.abs(deltaY);
+                if (!mIsBeingDragged && yDiff > mTouchSlop && yDiff > xDiff) {
+                    setIsBeingDragged(true);
+                    if (deltaY > 0) {
+                        deltaY -= mTouchSlop;
+                    } else {
+                        deltaY += mTouchSlop;
+                    }
+                }
+                if (mIsBeingDragged) {
+                    // Scroll to follow the motion event
+                    mLastMotionY = y;
+                    int range = getScrollRange();
+                    if (mExpandedInThisMotion) {
+                        range = Math.min(range, mMaxScrollAfterExpand);
+                    }
+
+                    float scrollAmount;
+                    if (deltaY < 0) {
+                        scrollAmount = overScrollDown(deltaY);
+                    } else {
+                        scrollAmount = overScrollUp(deltaY, range);
+                    }
+
+                    // Calling customOverScrollBy will call onCustomOverScrolled, which
+                    // sets the scrolling if applicable.
+                    if (scrollAmount != 0.0f) {
+                        // The scrolling motion could not be compensated with the
+                        // existing overScroll, we have to scroll the view
+                        customOverScrollBy((int) scrollAmount, mOwnScrollY,
+                                range, getHeight() / 2);
+                        // If we're scrolling, leavebehinds should be dismissed
+                        checkSnoozeLeavebehind();
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+                if (mIsBeingDragged) {
+                    final VelocityTracker velocityTracker = mVelocityTracker;
+                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                    int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
+
+                    if (shouldOverScrollFling(initialVelocity)) {
+                        onOverScrollFling(true, initialVelocity);
+                    } else {
+                        if (getChildCount() > 0) {
+                            if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
+                                float currentOverScrollTop = getCurrentOverScrollAmount(true);
+                                if (currentOverScrollTop == 0.0f || initialVelocity > 0) {
+                                    fling(-initialVelocity);
+                                } else {
+                                    onOverScrollFling(false, initialVelocity);
+                                }
+                            } else {
+                                if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0,
+                                        getScrollRange())) {
+                                    animateScroll();
+                                }
+                            }
+                        }
+                    }
+                    mActivePointerId = INVALID_POINTER;
+                    endDrag();
+                }
+
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                if (mIsBeingDragged && getChildCount() > 0) {
+                    if (mScroller.springBack(mScrollX, mOwnScrollY, 0, 0, 0, getScrollRange())) {
+                        animateScroll();
+                    }
+                    mActivePointerId = INVALID_POINTER;
+                    endDrag();
+                }
+                break;
+            case MotionEvent.ACTION_POINTER_DOWN: {
+                final int index = ev.getActionIndex();
+                mLastMotionY = (int) ev.getY(index);
+                mDownX = (int) ev.getX(index);
+                mActivePointerId = ev.getPointerId(index);
+                break;
+            }
+            case MotionEvent.ACTION_POINTER_UP:
+                onSecondaryPointerUp(ev);
+                mLastMotionY = (int) ev.getY(ev.findPointerIndex(mActivePointerId));
+                mDownX = (int) ev.getX(ev.findPointerIndex(mActivePointerId));
+                break;
+        }
+        return true;
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    protected boolean isInsideQsContainer(MotionEvent ev) {
+        return ev.getY() < mQsContainer.getBottom();
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private void onOverScrollFling(boolean open, int initialVelocity) {
+        if (mOverscrollTopChangedListener != null) {
+            mOverscrollTopChangedListener.flingTopOverscroll(initialVelocity, open);
+        }
+        mDontReportNextOverScroll = true;
+        setOverScrollAmount(0.0f, true, false);
+    }
+
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private void onSecondaryPointerUp(MotionEvent ev) {
+        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+                MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+        final int pointerId = ev.getPointerId(pointerIndex);
+        if (pointerId == mActivePointerId) {
+            // This was our active pointer going up. Choose a new
+            // active pointer and adjust accordingly.
+            // TODO: Make this decision more intelligent.
+            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+            mLastMotionY = (int) ev.getY(newPointerIndex);
+            mActivePointerId = ev.getPointerId(newPointerIndex);
+            if (mVelocityTracker != null) {
+                mVelocityTracker.clear();
+            }
+        }
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private void endDrag() {
+        setIsBeingDragged(false);
+
+        recycleVelocityTracker();
+
+        if (getCurrentOverScrollAmount(true /* onTop */) > 0) {
+            setOverScrollAmount(0, true /* onTop */, true /* animate */);
+        }
+        if (getCurrentOverScrollAmount(false /* onTop */) > 0) {
+            setOverScrollAmount(0, false /* onTop */, true /* animate */);
+        }
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private void transformTouchEvent(MotionEvent ev, View sourceView, View targetView) {
+        ev.offsetLocation(sourceView.getX(), sourceView.getY());
+        ev.offsetLocation(-targetView.getX(), -targetView.getY());
+    }
+
+    @Override
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        initDownStates(ev);
+        handleEmptySpaceClick(ev);
+        boolean expandWantsIt = false;
+        boolean swipingInProgress = mSwipeHelper.isSwipingInProgress();
+        if (!swipingInProgress && !mOnlyScrollingInThisMotion) {
+            expandWantsIt = mExpandHelper.onInterceptTouchEvent(ev);
+        }
+        boolean scrollWantsIt = false;
+        if (!swipingInProgress && !mExpandingNotification) {
+            scrollWantsIt = onInterceptTouchEventScroll(ev);
+        }
+        boolean swipeWantsIt = false;
+        if (!mIsBeingDragged
+                && !mExpandingNotification
+                && !mExpandedInThisMotion
+                && !mOnlyScrollingInThisMotion
+                && !mDisallowDismissInThisMotion) {
+            swipeWantsIt = mSwipeHelper.onInterceptTouchEvent(ev);
+        }
+        // Check if we need to clear any snooze leavebehinds
+        boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP;
+        NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
+        if (!NotificationSwipeHelper.isTouchInView(ev, guts) && isUp && !swipeWantsIt &&
+                !expandWantsIt && !scrollWantsIt) {
+            mCheckForLeavebehind = false;
+            mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
+                    false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
+                    false /* resetMenu */);
+        }
+        if (ev.getActionMasked() == MotionEvent.ACTION_UP) {
+            mCheckForLeavebehind = true;
+        }
+        return swipeWantsIt || scrollWantsIt || expandWantsIt || super.onInterceptTouchEvent(ev);
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private void handleEmptySpaceClick(MotionEvent ev) {
+        switch (ev.getActionMasked()) {
+            case MotionEvent.ACTION_MOVE:
+                if (mTouchIsClick && (Math.abs(ev.getY() - mInitialTouchY) > mTouchSlop
+                        || Math.abs(ev.getX() - mInitialTouchX) > mTouchSlop)) {
+                    mTouchIsClick = false;
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+                if (mStatusBarState != StatusBarState.KEYGUARD && mTouchIsClick &&
+                        isBelowLastNotification(mInitialTouchX, mInitialTouchY)) {
+                    mOnEmptySpaceClickListener.onEmptySpaceClicked(mInitialTouchX, mInitialTouchY);
+                }
+                break;
+        }
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private void initDownStates(MotionEvent ev) {
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+            mExpandedInThisMotion = false;
+            mOnlyScrollingInThisMotion = !mScroller.isFinished();
+            mDisallowScrollingInThisMotion = false;
+            mDisallowDismissInThisMotion = false;
+            mTouchIsClick = true;
+            mInitialTouchX = ev.getX();
+            mInitialTouchY = ev.getY();
+        }
+    }
+
+    @Override
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        super.requestDisallowInterceptTouchEvent(disallowIntercept);
+        if (disallowIntercept) {
+            cancelLongPress();
+        }
+    }
+
     @ShadeViewRefactor(RefactorComponent.INPUT)
     private boolean onInterceptTouchEventScroll(MotionEvent ev) {
         if (!isScrollingEnabled()) {
@@ -3713,11 +3636,6 @@
         return mIsBeingDragged;
     }
 
-    @ShadeViewRefactor(RefactorComponent.LAYOUT_ALGORITHM)
-    protected StackScrollAlgorithm createStackScrollAlgorithm(Context context) {
-        return new StackScrollAlgorithm(context);
-    }
-
     /**
      * @return Whether the specified motion event is actually happening over the content.
      */
@@ -3726,20 +3644,92 @@
         return isInContentBounds(event.getY());
     }
 
-    /**
-     * @return Whether a y coordinate is inside the content.
-     */
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean isInContentBounds(float y) {
-        return y < getHeight() - getEmptyBottomMargin();
-    }
 
+    @VisibleForTesting
     @ShadeViewRefactor(RefactorComponent.INPUT)
-    private void setIsBeingDragged(boolean isDragged) {
+    void setIsBeingDragged(boolean isDragged) {
         mIsBeingDragged = isDragged;
         if (isDragged) {
             requestDisallowInterceptTouchEvent(true);
             cancelLongPress();
+            resetExposedMenuView(true /* animate */, true /* force */);
+        }
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public void requestDisallowLongPress() {
+        cancelLongPress();
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public void requestDisallowDismiss() {
+        mDisallowDismissInThisMotion = true;
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public void cancelLongPress() {
+        mSwipeHelper.cancelLongPress();
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public void setOnEmptySpaceClickListener(OnEmptySpaceClickListener listener) {
+        mOnEmptySpaceClickListener = listener;
+    }
+
+    /** @hide */
+    @Override
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+        if (super.performAccessibilityActionInternal(action, arguments)) {
+            return true;
+        }
+        if (!isEnabled()) {
+            return false;
+        }
+        int direction = -1;
+        switch (action) {
+            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
+                // fall through
+            case android.R.id.accessibilityActionScrollDown:
+                direction = 1;
+                // fall through
+            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
+                // fall through
+            case android.R.id.accessibilityActionScrollUp:
+                final int viewportHeight = getHeight() - mPaddingBottom - mTopPadding - mPaddingTop
+                        - mShelf.getIntrinsicHeight();
+                final int targetScrollY = Math.max(0,
+                        Math.min(mOwnScrollY + direction * viewportHeight, getScrollRange()));
+                if (targetScrollY != mOwnScrollY) {
+                    mScroller.startScroll(mScrollX, mOwnScrollY, 0, targetScrollY - mOwnScrollY);
+                    animateScroll();
+                    return true;
+                }
+                break;
+        }
+        return false;
+    }
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    public void closeControlsIfOutsideTouch(MotionEvent ev) {
+        NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
+        NotificationMenuRowPlugin menuRow = mSwipeHelper.getCurrentMenuRow();
+        View translatingParentView = mSwipeHelper.getTranslatingParentView();
+        View view = null;
+        if (guts != null && !guts.getGutsContent().isLeavebehind()) {
+            // Only close visible guts if they're not a leavebehind.
+            view = guts;
+        } else if (menuRow != null && menuRow.isMenuVisible()
+                && translatingParentView != null) {
+            // Checking menu
+            view = translatingParentView;
+        }
+        if (view != null && !NotificationSwipeHelper.isTouchInView(ev, view)) {
+            // Touch was outside visible guts / menu notification, close what's visible
+            mNotificationGutsManager.closeAndSaveGuts(false /* removeLeavebehind */,
+                    false /* force */, true /* removeControls */, -1 /* x */, -1 /* y */,
+                    false /* resetMenu */);
+            resetExposedMenuView(true /* animate */, true /* force */);
         }
     }
 
@@ -3761,21 +3751,6 @@
         }
     }
 
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void requestDisallowLongPress() {
-        cancelLongPress();
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void requestDisallowDismiss() {
-        mDisallowDismissInThisMotion = true;
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void cancelLongPress() {
-        mSwipeHelper.cancelLongPress();
-    }
-
     @Override
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     public boolean isScrolledToTop() {
@@ -3869,6 +3844,7 @@
     public void onPanelTrackingStarted() {
         mPanelTracking = true;
         mAmbientState.setPanelTracking(true);
+        resetExposedMenuView(true /* animate */, true /* force */);
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -3916,7 +3892,6 @@
     }
 
     @Override
-    @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     public void onHeightChanged(ExpandableView view, boolean needsAnimation) {
         updateContentHeight();
         updateScrollPositionOnExpandInBottom(view);
@@ -3936,7 +3911,6 @@
     }
 
     @Override
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void onReset(ExpandableView view) {
         updateAnimationState(view);
         updateChronometerForChild(view);
@@ -3969,13 +3943,8 @@
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void setOnHeightChangedListener(
-            ExpandableView.OnHeightChangedListener mOnHeightChangedListener) {
-        this.mOnHeightChangedListener = mOnHeightChangedListener;
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void setOnEmptySpaceClickListener(OnEmptySpaceClickListener listener) {
-        mOnEmptySpaceClickListener = listener;
+            ExpandableView.OnHeightChangedListener onHeightChangedListener) {
+        this.mOnHeightChangedListener = onHeightChangedListener;
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4271,8 +4240,10 @@
         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();
             DozeParameters dozeParameters = DozeParameters.getInstance(mContext);
@@ -4283,6 +4254,9 @@
                 mIconAreaController.setFullyDark(nowFullyDark);
             }
         }
+        if (!wasDarkAtAll && nowDarkAtAll) {
+            resetExposedMenuView(true /* animate */, true /* animate */);
+        }
         updateAlgorithmHeightAndPadding();
         updateBackgroundDimming();
         updatePanelTranslation();
@@ -4460,7 +4434,7 @@
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void setGroupManager(NotificationGroupManager groupManager) {
         this.mGroupManager = groupManager;
-        mGroupManager.setOnGroupChangeListener(this);
+        mGroupManager.setOnGroupChangeListener(mOnGroupChangeListener);
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4503,33 +4477,6 @@
         return touchY > mTopPadding + mStackTranslation;
     }
 
-    @Override
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void onGroupExpansionChanged(ExpandableNotificationRow changedRow, boolean expanded) {
-        boolean animated = !mGroupExpandedForMeasure && mAnimationsEnabled
-                && (mIsExpanded || changedRow.isPinned());
-        if (animated) {
-            mExpandedGroupView = changedRow;
-            mNeedsAnimation = true;
-        }
-        changedRow.setChildrenExpanded(expanded, animated);
-        if (!mGroupExpandedForMeasure) {
-            onHeightChanged(changedRow, false /* needsAnimation */);
-        }
-        runAfterAnimationFinished(new Runnable() {
-            @Override
-            public void run() {
-                changedRow.onFinishedExpansionChange();
-            }
-        });
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void onGroupCreatedFromChildren(NotificationGroupManager.NotificationGroup group) {
-        mStatusBar.requestNotificationUpdate();
-    }
-
     /** @hide */
     @Override
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -4562,46 +4509,6 @@
         info.setClassName(ScrollView.class.getName());
     }
 
-    /** @hide */
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
-        if (super.performAccessibilityActionInternal(action, arguments)) {
-            return true;
-        }
-        if (!isEnabled()) {
-            return false;
-        }
-        int direction = -1;
-        switch (action) {
-            case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
-                // fall through
-            case android.R.id.accessibilityActionScrollDown:
-                direction = 1;
-                // fall through
-            case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
-                // fall through
-            case android.R.id.accessibilityActionScrollUp:
-                final int viewportHeight = getHeight() - mPaddingBottom - mTopPadding - mPaddingTop
-                        - mShelf.getIntrinsicHeight();
-                final int targetScrollY = Math.max(0,
-                        Math.min(mOwnScrollY + direction * viewportHeight, getScrollRange()));
-                if (targetScrollY != mOwnScrollY) {
-                    mScroller.startScroll(mScrollX, mOwnScrollY, 0, targetScrollY - mOwnScrollY);
-                    animateScroll();
-                    return true;
-                }
-                break;
-        }
-        return false;
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    public void onGroupsChanged() {
-        mStatusBar.requestNotificationUpdate();
-    }
-
     @ShadeViewRefactor(RefactorComponent.COORDINATOR)
     public void generateChildOrderChangedEvent() {
         if (mIsExpanded && mAnimationsEnabled) {
@@ -4644,7 +4551,7 @@
     public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
         mHeadsUpManager = headsUpManager;
         mHeadsUpManager.addListener(mRoundnessManager);
-        mHeadsUpManager.setAnimationStateHandler(this);
+        mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
     }
 
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4821,7 +4728,8 @@
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
-    private void setStatusBarState(int statusBarState) {
+    @VisibleForTesting
+    protected void setStatusBarState(int statusBarState) {
         mStatusBarState = statusBarState;
         mAmbientState.setStatusBarState(statusBarState);
     }
@@ -4844,7 +4752,7 @@
             activatedChild.makeInactive(false /* animate */);
         }
         updateFooter();
-        updateChildren();
+        requestChildrenUpdate();
         onUpdateRowStates();
 
         mEntryManager.updateNotifications();
@@ -4907,6 +4815,34 @@
                 mMaxTopPadding,
                 mShouldShowShelfOnly ? "T" : "f",
                 mQsExpansionFraction));
+        int childCount = getChildCount();
+        pw.println("  Number of children: " + childCount);
+        pw.println();
+
+        for (int i = 0; i < childCount; i++) {
+            ExpandableView child = (ExpandableView) getChildAt(i);
+            child.dump(fd, pw, args);
+            if (!(child instanceof ExpandableNotificationRow)) {
+                pw.println("  " + child.getClass().getSimpleName());
+                // Notifications dump it's viewstate as part of their dump to support children
+                ExpandableViewState viewState = mCurrentStackScrollState.getViewStateForView(
+                        child);
+                if (viewState == null) {
+                    pw.println("    no viewState!!!");
+                } else {
+                    pw.print("    ");
+                    viewState.dump(fd, pw, args);
+                    pw.println();
+                    pw.println();
+                }
+            }
+        }
+        pw.println("  Transient Views: " + childCount);
+        int transientViewCount = getTransientViewCount();
+        for (int i = 0; i < transientViewCount; i++) {
+            ExpandableView child = (ExpandableView) getTransientView(i);
+            child.dump(fd, pw, args);
+        }
     }
 
     @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -4995,7 +4931,7 @@
             return;
         }
 
-        mStatusBar.addPostCollapseAction(() -> {
+        mShadeController.addPostCollapseAction(() -> {
             setDismissAllInProgress(false);
             for (ExpandableNotificationRow rowToRemove : viewsToRemove) {
                 if (canChildBeDismissed(rowToRemove)) {
@@ -5095,6 +5031,10 @@
         mNotificationPanel = notificationPanelView;
     }
 
+    public void updateIconAreaViews() {
+        mIconAreaController.updateNotificationIcons();
+    }
+
     /**
      * A listener that is notified when the empty space below the notifications is clicked on
      */
@@ -5135,67 +5075,7 @@
         return !mEntryManager.getNotificationData().getActiveNotifications().isEmpty();
     }
 
-    // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
-
-
-    /* Only ever called as a consequence of a lockscreen expansion gesture. */
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean onDraggedDown(View startingChild, int dragLengthY) {
-        if (mStatusBarState == StatusBarState.KEYGUARD
-                && hasActiveNotifications() && (!mStatusBar.isDozing() || mStatusBar.isPulsing())) {
-            mLockscreenGestureLogger.write(
-                    MetricsEvent.ACTION_LS_SHADE,
-                    (int) (dragLengthY / mDisplayMetrics.density),
-                    0 /* velocityDp - N/A */);
-
-            // We have notifications, go to locked shade.
-            mStatusBar.goToLockedShade(startingChild);
-            if (startingChild instanceof ExpandableNotificationRow) {
-                ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild;
-                row.onExpandedByGesture(true /* drag down is always an open */);
-            }
-            return true;
-        } else {
-            // abort gesture.
-            return false;
-        }
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void onDragDownReset() {
-        setDimmed(true /* dimmed */, true /* animated */);
-        resetScrollPosition();
-        resetCheckSnoozeLeavebehind();
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void onCrossedThreshold(boolean above) {
-        setDimmed(!above /* dimmed */, true /* animate */);
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void onTouchSlopExceeded() {
-        cancelLongPress();
-        checkSnoozeLeavebehind();
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void setEmptyDragAmount(float amount) {
-        mNotificationPanel.setEmptyDragAmount(amount);
-    }
-
-    @Override
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public boolean isFalsingCheckNeeded() {
-        return mStatusBarState == StatusBarState.KEYGUARD;
-    }
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
     public void updateSpeedBumpIndex() {
         int speedBumpIndex = 0;
         int currentIndex = 0;
@@ -5236,30 +5116,6 @@
         mSwipeHelper.resetExposedMenuView(animate, force);
     }
 
-
-    @ShadeViewRefactor(RefactorComponent.INPUT)
-    public void closeControlsIfOutsideTouch(MotionEvent ev) {
-        NotificationGuts guts = mNotificationGutsManager.getExposedGuts();
-        NotificationMenuRowPlugin menuRow = mSwipeHelper.getCurrentMenuRow();
-        View translatingParentView = mSwipeHelper.getTranslatingParentView();
-        View view = null;
-        if (guts != null && !guts.getGutsContent().isLeavebehind()) {
-            // Only close visible guts if they're not a leavebehind.
-            view = guts;
-        } else if (menuRow != null && menuRow.isMenuVisible()
-                && translatingParentView != null) {
-            // Checking menu
-            view = translatingParentView;
-        }
-        if (view != null && !NotificationSwipeHelper.isTouchInView(ev, view)) {
-            // Touch was outside visible guts / menu notification, close what's visible
-            mNotificationGutsManager.closeAndSaveGuts(false /* removeLeavebehind */,
-                    false /* force */, true /* removeControls */, -1 /* x */, -1 /* y */,
-                    false /* resetMenu */);
-            resetExposedMenuView(true /* animate */, true /* force */);
-        }
-    }
-
     @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
     static class AnimationEvent {
 
@@ -5581,9 +5437,9 @@
       }
     };
 
-    class NotificationMenuListener implements NotificationMenuRowPlugin.OnMenuEventListener {
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private final OnMenuEventListener mMenuEventListener = new OnMenuEventListener() {
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public void onMenuClicked(View view, int x, int y, MenuItem item) {
             if (mLongPressListener == null) {
                 return;
@@ -5597,7 +5453,6 @@
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public void onMenuReset(View row) {
             View translatingParentView = mSwipeHelper.getTranslatingParentView();
             if (translatingParentView != null && row == translatingParentView) {
@@ -5607,7 +5462,6 @@
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public void onMenuShown(View row) {
             if (row instanceof ExpandableNotificationRow) {
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_REVEAL_GEAR,
@@ -5616,9 +5470,11 @@
             }
             mSwipeHelper.onMenuShown(row);
         }
-    }
+    };
 
-    class SwipeHelperCallback implements NotificationSwipeHelper.NotificationCallback {
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private final NotificationSwipeHelper.NotificationCallback mNotificationCallback =
+            new NotificationSwipeHelper.NotificationCallback() {
         @Override
         public void onDismiss() {
             mNotificationGutsManager.closeAndSaveGuts(true /* removeLeavebehind */,
@@ -5638,10 +5494,8 @@
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public void onDragCancelled(View v) {
             mFalsingManager.onNotificatonStopDismissing();
-            setSwipingInProgress(false);
         }
 
         /**
@@ -5649,7 +5503,6 @@
          * re-invoking dismiss logic in case the notification has not made its way out yet).
          */
         @Override
-        @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
         public void onChildDismissed(View view) {
             ExpandableNotificationRow row = (ExpandableNotificationRow) view;
             if (!row.isDismissed()) {
@@ -5668,7 +5521,6 @@
          * @param view view (e.g. notification) to dismiss from the layout
          */
 
-        @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
         public void handleChildViewDismissed(View view) {
             if (mDismissAllInProgress) {
                 return;
@@ -5676,7 +5528,6 @@
 
             boolean isBlockingHelperShown = false;
 
-            setSwipingInProgress(false);
             if (mDragAnimPendingChildren.contains(view)) {
                 // We start the swipe and finish it in the same frame; we don't want a drag
                 // animation.
@@ -5710,13 +5561,11 @@
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public boolean isAntiFalsingNeeded() {
             return onKeyguard();
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public View getChildAtPosition(MotionEvent ev) {
             View child = NotificationStackScrollLayout.this.getChildAtPosition(ev.getX(),
                     ev.getY());
@@ -5739,10 +5588,8 @@
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public void onBeginDrag(View v) {
             mFalsingManager.onNotificatonStartDismissing();
-            setSwipingInProgress(true);
             mAmbientState.onBeginDrag(v);
             updateContinuousShadowDrawing();
             if (mAnimationsEnabled && (mIsExpanded || !isPinnedHeadsUp(v))) {
@@ -5753,7 +5600,6 @@
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
         public void onChildSnappedBack(View animView, float targetLeft) {
             mAmbientState.onDragFinished(animView);
             updateContinuousShadowDrawing();
@@ -5775,7 +5621,6 @@
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public boolean updateSwipeProgress(View animView, boolean dismissable,
                 float swipeProgress) {
             // Returning true prevents alpha fading.
@@ -5783,7 +5628,6 @@
         }
 
         @Override
-        @ShadeViewRefactor(RefactorComponent.INPUT)
         public float getFalsingThresholdFactor() {
             return mStatusBar.isWakeUpComingFromTouch() ? 1.5f : 1.0f;
         }
@@ -5792,5 +5636,199 @@
         public boolean canChildBeDismissed(View v) {
             return NotificationStackScrollLayout.this.canChildBeDismissed(v);
         }
+    };
+
+    // ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
+
+    @ShadeViewRefactor(RefactorComponent.INPUT)
+    private final DragDownCallback mDragDownCallback = new DragDownCallback() {
+
+        /* Only ever called as a consequence of a lockscreen expansion gesture. */
+        @Override
+        public boolean onDraggedDown(View startingChild, int dragLengthY) {
+            if (mStatusBarState == StatusBarState.KEYGUARD
+                    && hasActiveNotifications()) {
+                mLockscreenGestureLogger.write(
+                        MetricsEvent.ACTION_LS_SHADE,
+                        (int) (dragLengthY / mDisplayMetrics.density),
+                        0 /* velocityDp - N/A */);
+
+                if (mNotificationPanel.onDraggedDown() || startingChild != null) {
+                    // We have notifications, go to locked shade.
+                    mShadeController.goToLockedShade(startingChild);
+                    if (startingChild instanceof ExpandableNotificationRow) {
+                        ExpandableNotificationRow row = (ExpandableNotificationRow) startingChild;
+                        row.onExpandedByGesture(true /* drag down is always an open */);
+                    }
+                }
+
+                return true;
+            } else {
+                // abort gesture.
+                return false;
+            }
+        }
+
+        @Override
+        public void onDragDownReset() {
+            setDimmed(true /* dimmed */, true /* animated */);
+            resetScrollPosition();
+            resetCheckSnoozeLeavebehind();
+        }
+
+        @Override
+        public void onCrossedThreshold(boolean above) {
+            setDimmed(!above /* dimmed */, true /* animate */);
+        }
+
+        @Override
+        public void onTouchSlopExceeded() {
+            cancelLongPress();
+            checkSnoozeLeavebehind();
+        }
+
+        @Override
+        public void setEmptyDragAmount(float amount) {
+            mNotificationPanel.setEmptyDragAmount(amount);
+        }
+
+        @Override
+        public boolean isFalsingCheckNeeded() {
+            return mStatusBarState == StatusBarState.KEYGUARD;
+        }
+    };
+
+    public DragDownCallback getDragDownCallback() { return mDragDownCallback; }
+
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    private final HeadsUpTouchHelper.Callback mHeadsUpCallback = new HeadsUpTouchHelper.Callback() {
+        @Override
+        public ExpandableView getChildAtRawPosition(float touchX, float touchY) {
+            return NotificationStackScrollLayout.this.getChildAtRawPosition(touchX, touchY);
+        }
+
+        @Override
+        public boolean isExpanded() {
+            return mIsExpanded;
+        }
+
+        @Override
+        public Context getContext() {
+            return mContext;
+        }
+    };
+
+    public HeadsUpTouchHelper.Callback getHeadsUpCallback() { return mHeadsUpCallback; }
+
+
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    private final OnGroupChangeListener mOnGroupChangeListener = new OnGroupChangeListener() {
+        @Override
+        public void onGroupExpansionChanged(ExpandableNotificationRow changedRow, boolean expanded) {
+            boolean animated = !mGroupExpandedForMeasure && mAnimationsEnabled
+                    && (mIsExpanded || changedRow.isPinned());
+            if (animated) {
+                mExpandedGroupView = changedRow;
+                mNeedsAnimation = true;
+            }
+            changedRow.setChildrenExpanded(expanded, animated);
+            if (!mGroupExpandedForMeasure) {
+                onHeightChanged(changedRow, false /* needsAnimation */);
+            }
+            runAfterAnimationFinished(new Runnable() {
+                @Override
+                public void run() {
+                    changedRow.onFinishedExpansionChange();
+                }
+            });
+        }
+
+        @Override
+        public void onGroupCreatedFromChildren(NotificationGroupManager.NotificationGroup group) {
+            mStatusBar.requestNotificationUpdate();
+        }
+
+        @Override
+        public void onGroupsChanged() {
+            mStatusBar.requestNotificationUpdate();
+        }
+    };
+
+    @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
+    private ExpandHelper.Callback mExpandHelperCallback = new ExpandHelper.Callback() {
+        @Override
+        public ExpandableView getChildAtPosition(float touchX, float touchY) {
+            return NotificationStackScrollLayout.this.getChildAtPosition(touchX, touchY);
+        }
+
+        @Override
+        public ExpandableView getChildAtRawPosition(float touchX, float touchY) {
+            return NotificationStackScrollLayout.this.getChildAtRawPosition(touchX, touchY);
+        }
+
+        @Override
+        public boolean canChildBeExpanded(View v) {
+            return v instanceof ExpandableNotificationRow
+                    && ((ExpandableNotificationRow) v).isExpandable()
+                    && !((ExpandableNotificationRow) v).areGutsExposed()
+                    && (mIsExpanded || !((ExpandableNotificationRow) v).isPinned());
+        }
+
+        /* Only ever called as a consequence of an expansion gesture in the shade. */
+        @Override
+        public void setUserExpandedChild(View v, boolean userExpanded) {
+            if (v instanceof ExpandableNotificationRow) {
+                ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+                if (userExpanded && onKeyguard()) {
+                    // Due to a race when locking the screen while touching, a notification may be
+                    // expanded even after we went back to keyguard. An example of this happens if
+                    // you click in the empty space while expanding a group.
+
+                    // We also need to un-user lock it here, since otherwise the content height
+                    // calculated might be wrong. We also can't invert the two calls since
+                    // un-userlocking it will trigger a layout switch in the content view.
+                    row.setUserLocked(false);
+                    updateContentHeight();
+                    notifyHeightChangeListener(row);
+                    return;
+                }
+                row.setUserExpanded(userExpanded, true /* allowChildrenExpansion */);
+                row.onExpandedByGesture(userExpanded);
+            }
+        }
+
+        @Override
+        public void setExpansionCancelled(View v) {
+            if (v instanceof ExpandableNotificationRow) {
+                ((ExpandableNotificationRow) v).setGroupExpansionChanging(false);
+            }
+        }
+
+        @Override
+        public void setUserLockedChild(View v, boolean userLocked) {
+            if (v instanceof ExpandableNotificationRow) {
+                ((ExpandableNotificationRow) v).setUserLocked(userLocked);
+            }
+            cancelLongPress();
+            requestDisallowInterceptTouchEvent(true);
+        }
+
+        @Override
+        public void expansionStateChanged(boolean isExpanding) {
+            mExpandingNotification = isExpanding;
+            if (!mExpandedInThisMotion) {
+                mMaxScrollAfterExpand = mOwnScrollY;
+                mExpandedInThisMotion = true;
+            }
+        }
+
+        @Override
+        public int getMaxExpandHeight(ExpandableView view) {
+            return view.getMaxContentHeight();
+        }
+    };
+
+    public ExpandHelper.Callback getExpandHelperCallback() {
+        return mExpandHelperCallback;
     }
 }
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 028957d..599da3b 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
@@ -31,11 +31,9 @@
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
-import com.android.systemui.statusbar.notification.ShadeViewRefactor;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 
-@ShadeViewRefactor(ShadeViewRefactor.RefactorComponent.INPUT)
 class NotificationSwipeHelper extends SwipeHelper
         implements NotificationSwipeActionHelper {
     @VisibleForTesting
@@ -229,6 +227,7 @@
         if (mCallback.isExpanded()) {
             // We don't want to quick-dismiss when it's a heads up as this might lead to closing
             // of the panel early.
+            mSwipingInProgress = false;
             mCallback.handleChildViewDismissed(view);
         }
         mCallback.onDismiss();
@@ -248,6 +247,7 @@
     @Override
     public void snapChild(final View animView, final float targetLeft, float velocity) {
         superSnapChild(animView, targetLeft, velocity);
+        mSwipingInProgress = false;
         mCallback.onDragCancelled(animView);
         if (targetLeft == 0) {
             handleMenuCoveredOrDismissed();
@@ -354,6 +354,7 @@
 
     public void onMenuShown(View animView) {
         setExposedMenuView(getTranslatingParentView());
+        mSwipingInProgress = false;
         mCallback.onDragCancelled(animView);
         Handler handler = getHandler();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
index 1f3244f..a15fd70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ViewState.java
@@ -25,6 +25,7 @@
 import android.view.View;
 import android.view.animation.Interpolator;
 
+import com.android.systemui.Dumpable;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -32,12 +33,17 @@
 import com.android.systemui.statusbar.notification.PropertyAnimator;
 import com.android.systemui.statusbar.policy.HeadsUpUtil;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
 /**
  * A state of a view. This can be used to apply a set of view properties to a view with
  * {@link com.android.systemui.statusbar.notification.stack.StackScrollState} or start
  * animations with {@link com.android.systemui.statusbar.notification.stack.StackStateAnimator}.
 */
-public class ViewState {
+public class ViewState implements Dumpable {
 
     /**
      * Some animation properties that can be used to update running animations but not creating
@@ -710,4 +716,39 @@
             animator.cancel();
         }
     }
+
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        StringBuilder result = new StringBuilder();
+        result.append("ViewState { ");
+
+        boolean first = true;
+        Class currentClass = this.getClass();
+        while (currentClass != null) {
+            Field[] fields = currentClass.getDeclaredFields();
+            // Print field names paired with their values
+            for (Field field : fields) {
+                int modifiers = field.getModifiers();
+                if (Modifier.isStatic(modifiers) || field.isSynthetic()
+                        || Modifier.isTransient(modifiers)) {
+                    continue;
+                }
+                if (!first) {
+                    result.append(", ");
+                }
+                try {
+                    result.append(field.getName());
+                    result.append(": ");
+                    //requires access to private field:
+                    field.setAccessible(true);
+                    result.append(field.get(this));
+                } catch (IllegalAccessException ex) {
+                }
+                first = false;
+            }
+            currentClass = currentClass.getSuperclass();
+        }
+        result.append(" }");
+        pw.print(result);
+    }
 }
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 c094669..8325bf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -32,6 +32,7 @@
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.statusbar.NotificationMediaManager;
 
 import java.io.PrintWriter;
 
@@ -95,6 +96,8 @@
      */
     private static final float BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR = 1.1f;
 
+    private final NotificationMediaManager mMediaManager =
+            Dependency.get(NotificationMediaManager.class);
     private PowerManager mPowerManager;
     private Handler mHandler = new Handler();
     private PowerManager.WakeLock mWakeLock;
@@ -264,7 +267,7 @@
             case MODE_WAKE_AND_UNLOCK:
                 if (mMode == MODE_WAKE_AND_UNLOCK_PULSING) {
                     Trace.beginSection("MODE_WAKE_AND_UNLOCK_PULSING");
-                    mStatusBar.updateMediaMetaData(false /* metaDataChanged */,
+                    mMediaManager.updateMediaMetaData(false /* metaDataChanged */,
                             true /* allowEnterAnimation */);
                 } else if (mMode == MODE_WAKE_AND_UNLOCK){
                     Trace.beginSection("MODE_WAKE_AND_UNLOCK");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
index 587b40d..4eca6bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -288,4 +288,10 @@
             }
         }
     }
+
+    /**
+     * Executes when button is detached from window.
+     */
+    protected void onDestroy() {
+    }
 }
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 a781be6..fa63831 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -64,11 +64,12 @@
     private StatusBar mStatusBarComponent;
     private DarkIconManager mDarkIconManager;
     private View mOperatorNameFrame;
+    private CommandQueue mCommandQueue;
 
     private SignalCallback mSignalCallback = new SignalCallback() {
         @Override
         public void setIsAirplaneMode(NetworkController.IconState icon) {
-            mStatusBarComponent.recomputeDisableFlags(true /* animate */);
+            mCommandQueue.recomputeDisableFlags(true /* animate */);
         }
     };
 
@@ -78,6 +79,7 @@
         mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
         mNetworkController = Dependency.get(NetworkController.class);
         mStatusBarComponent = SysUiServiceProvider.getComponent(getContext(), StatusBar.class);
+        mCommandQueue = SysUiServiceProvider.getComponent(getContext(), CommandQueue.class);
     }
 
     @Override
@@ -116,13 +118,13 @@
     @Override
     public void onResume() {
         super.onResume();
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
+        mCommandQueue.addCallbacks(this);
     }
 
     @Override
     public void onPause() {
         super.onPause();
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this);
+        mCommandQueue.removeCallbacks(this);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
index c7ab27b..5dded52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButton.java
@@ -18,8 +18,10 @@
 
 import android.annotation.DrawableRes;
 import android.annotation.IdRes;
+import android.annotation.NonNull;
 import android.content.Context;
 import android.view.View;
+
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 import com.android.systemui.statusbar.policy.KeyButtonView;
 
@@ -29,6 +31,9 @@
  */
 public class ContextualButton extends ButtonDispatcher {
 
+    private ContextButtonListener mListener;
+    private ContextualButtonGroup mGroup;
+
     protected final @DrawableRes int mIconResId;
 
     /**
@@ -64,6 +69,48 @@
             currentDrawable.clearAnimationCallbacks();
             currentDrawable.resetAnimation();
         }
+
+        if (mListener != null) {
+            mListener.onVisibilityChanged(this, visibility == View.VISIBLE);
+        }
+    }
+
+    public void setListener(ContextButtonListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Show this button based on its priority compared to other buttons in the group. If not
+     * attached to a group it will set its own visibility to be visible.
+     * @return if visible
+     */
+    public boolean show() {
+        if (mGroup == null) {
+            setVisibility(View.VISIBLE);
+            return true;
+        }
+        return mGroup.setButtonVisiblity(getId(), true /* visible */) == View.VISIBLE;
+    }
+
+    /**
+     * Hide this button.
+     * @return if visible
+     */
+    public boolean hide() {
+        if (mGroup == null) {
+            setVisibility(View.INVISIBLE);
+            return false;
+        }
+        return mGroup.setButtonVisiblity(getId(), false /* visible */) != View.VISIBLE;
+    }
+
+    /**
+     * Called when this button was added to the group. Keep a reference to the group to show based
+     * on priority compared to other buttons.
+     * @param group the holder of all the buttons
+     */
+    void attachToGroup(@NonNull ContextualButtonGroup group) {
+        mGroup = group;
     }
 
     protected KeyButtonDrawable getNewDrawable() {
@@ -79,4 +126,8 @@
     protected Context getContext() {
         return getCurrentView().getContext();
     }
+
+    public interface ContextButtonListener {
+        void onVisibilityChanged(ContextualButton button, boolean visible);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
index 1b03966..9703043 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ContextualButtonGroup.java
@@ -40,6 +40,7 @@
      * @param button the button added to the group
      */
     public void addButton(@NonNull ContextualButton button) {
+        button.attachToGroup(this);
         mButtonData.add(new ButtonData(button));
     }
 
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 9acaf21..c66bbb1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -48,6 +48,7 @@
     private final NotificationStackScrollLayout mStackScroller;
     private final HeadsUpStatusBarView mHeadsUpStatusBarView;
     private final View mClockView;
+    private final View mOperatorNameView;
     private final DarkIconDispatcher mDarkIconDispatcher;
     private final NotificationPanelView mPanelView;
     private final Consumer<ExpandableNotificationRow>
@@ -65,8 +66,10 @@
     private final View.OnLayoutChangeListener mStackScrollLayoutChangeListener =
             (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)
                     -> updatePanelTranslation();
+    private boolean mAnimationsEnabled = true;
     Point mPoint;
 
+
     public HeadsUpAppearanceController(
             NotificationIconAreaController notificationIconAreaController,
             HeadsUpManagerPhone headsUpManager,
@@ -75,7 +78,8 @@
                 statusbarView.findViewById(R.id.heads_up_status_bar_view),
                 statusbarView.findViewById(R.id.notification_stack_scroller),
                 statusbarView.findViewById(R.id.notification_panel),
-                statusbarView.findViewById(R.id.clock));
+                statusbarView.findViewById(R.id.clock),
+                statusbarView.findViewById(R.id.operator_name_frame));
     }
 
     @VisibleForTesting
@@ -85,7 +89,8 @@
             HeadsUpStatusBarView headsUpStatusBarView,
             NotificationStackScrollLayout stackScroller,
             NotificationPanelView panelView,
-            View clockView) {
+            View clockView,
+            View operatorNameView) {
         mNotificationIconAreaController = notificationIconAreaController;
         mHeadsUpManager = headsUpManager;
         mHeadsUpManager.addListener(this);
@@ -101,6 +106,7 @@
         mStackScroller.addOnLayoutChangeListener(mStackScrollLayoutChangeListener);
         mStackScroller.setHeadsUpAppearanceController(this);
         mClockView = clockView;
+        mOperatorNameView = operatorNameView;
         mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
         mDarkIconDispatcher.addDarkReceiver(this);
 
@@ -230,20 +236,52 @@
             mShown = isShown;
             if (isShown) {
                 mHeadsUpStatusBarView.setVisibility(View.VISIBLE);
-                CrossFadeHelper.fadeIn(mHeadsUpStatusBarView, CONTENT_FADE_DURATION /* duration */,
-                        CONTENT_FADE_DELAY /* delay */);
-                CrossFadeHelper.fadeOut(mClockView, CONTENT_FADE_DURATION/* duration */,
-                        0 /* delay */, () -> mClockView.setVisibility(View.INVISIBLE));
+                show(mHeadsUpStatusBarView);
+                hide(mClockView, View.INVISIBLE);
+                if (mOperatorNameView != null) {
+                    hide(mOperatorNameView, View.INVISIBLE);
+                }
             } else {
-                CrossFadeHelper.fadeIn(mClockView, CONTENT_FADE_DURATION /* duration */,
-                        CONTENT_FADE_DELAY /* delay */);
-                CrossFadeHelper.fadeOut(mHeadsUpStatusBarView, CONTENT_FADE_DURATION/* duration */,
-                        0 /* delay */, () -> mHeadsUpStatusBarView.setVisibility(View.GONE));
-
+                show(mClockView);
+                if (mOperatorNameView != null) {
+                    show(mOperatorNameView);
+                }
+                hide(mHeadsUpStatusBarView, View.GONE);
             }
         }
     }
 
+    /**
+     * Hides the view and sets the state to endState when finished.
+     *
+     * @param view The view to hide.
+     * @param endState One of {@link View#INVISIBLE} or {@link View#GONE}.
+     * @see View#setVisibility(int)
+     *
+     */
+    private void hide(View view, int endState) {
+        if (mAnimationsEnabled) {
+            CrossFadeHelper.fadeOut(view, CONTENT_FADE_DURATION /* duration */,
+                    0 /* delay */, () -> view.setVisibility(endState));
+        } else {
+            view.setVisibility(endState);
+        }
+    }
+
+    private void show(View view) {
+        if (mAnimationsEnabled) {
+            CrossFadeHelper.fadeIn(view, CONTENT_FADE_DURATION /* duration */,
+                    CONTENT_FADE_DELAY /* delay */);
+        } else {
+            view.setVisibility(View.VISIBLE);
+        }
+    }
+
+    @VisibleForTesting
+    void setAnimationsEnabled(boolean enabled) {
+        mAnimationsEnabled = enabled;
+    }
+
     @VisibleForTesting
     public boolean isShown() {
         return mShown;
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 cfc3271..976327a 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,8 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import androidx.collection.ArraySet;
+
+import android.graphics.Rect;
 import android.graphics.Region;
 import android.graphics.Region.Op;
 import android.util.Log;
@@ -324,11 +326,10 @@
 
         // Expand touchable region such that we also catch touches that just start below the notch
         // area.
-        Region bounds = ScreenDecorations.DisplayCutoutView.boundsFromDirection(
-                cutout, Gravity.TOP);
-        bounds.translate(0, mDisplayCutoutTouchableRegionSize);
+        Rect bounds = new Rect();
+        ScreenDecorations.DisplayCutoutView.boundsFromDirection(cutout, Gravity.TOP, bounds);
+        bounds.offset(0, mDisplayCutoutTouchableRegionSize);
         region.op(bounds, Op.UNION);
-        bounds.recycle();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 4df1e3b..e4a5caa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -32,7 +32,7 @@
 public class HeadsUpTouchHelper implements Gefingerpoken {
 
     private HeadsUpManagerPhone mHeadsUpManager;
-    private NotificationStackScrollLayout mStackScroller;
+    private Callback mCallback;
     private int mTrackingPointer;
     private float mTouchSlop;
     private float mInitialTouchX;
@@ -44,12 +44,12 @@
     private ExpandableNotificationRow mPickedChild;
 
     public HeadsUpTouchHelper(HeadsUpManagerPhone headsUpManager,
-            NotificationStackScrollLayout stackScroller,
+            Callback callback,
             NotificationPanelView notificationPanelView) {
         mHeadsUpManager = headsUpManager;
-        mStackScroller = stackScroller;
+        mCallback = callback;
         mPanel = notificationPanelView;
-        Context context = stackScroller.getContext();
+        Context context = mCallback.getContext();
         final ViewConfiguration configuration = ViewConfiguration.get(context);
         mTouchSlop = configuration.getScaledTouchSlop();
     }
@@ -75,13 +75,13 @@
                 mInitialTouchY = y;
                 mInitialTouchX = x;
                 setTrackingHeadsUp(false);
-                ExpandableView child = mStackScroller.getChildAtRawPosition(x, y);
+                ExpandableView child = mCallback.getChildAtRawPosition(x, y);
                 mTouchingHeadsUpView = false;
                 if (child instanceof ExpandableNotificationRow) {
                     mPickedChild = (ExpandableNotificationRow) child;
-                    mTouchingHeadsUpView = !mStackScroller.isExpanded()
+                    mTouchingHeadsUpView = !mCallback.isExpanded()
                             && mPickedChild.isHeadsUp() && mPickedChild.isPinned();
-                } else if (child == null && !mStackScroller.isExpanded()) {
+                } else if (child == null && !mCallback.isExpanded()) {
                     // We might touch above the visible heads up child, but then we still would
                     // like to capture it.
                     NotificationData.Entry topEntry = mHeadsUpManager.getTopEntry();
@@ -174,4 +174,10 @@
         mPickedChild = null;
         mTouchingHeadsUpView = false;
     }
+
+    public interface Callback {
+        ExpandableView getChildAtRawPosition(float touchX, float touchY);
+        boolean isExpanded();
+        Context getContext();
+    }
 }
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 e2f3319..49d421b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardAffordanceHelper.java
@@ -36,7 +36,6 @@
  */
 public class KeyguardAffordanceHelper {
 
-    public static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.5f;
     public static final long HINT_PHASE1_DURATION = 200;
     private static final long HINT_PHASE2_DURATION = 350;
     private static final float BACKGROUND_RADIUS_SCALE_FACTOR = 0.25f;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index f667726..5439497 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -29,7 +29,6 @@
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
 import android.app.admin.DevicePolicyManager;
-import android.hardware.biometrics.BiometricSourceType;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -41,6 +40,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
+import android.hardware.biometrics.BiometricSourceType;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -54,7 +54,6 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.MathUtils;
 import android.util.TypedValue;
 import android.view.View;
 import android.view.ViewGroup;
@@ -64,20 +63,19 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.EventLogTags;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.assist.AssistManager;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.IntentButtonProvider;
 import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
 import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
-import com.android.systemui.plugins.PluginListener;
-import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -231,6 +229,11 @@
         }
     };
 
+    public void initFrom(KeyguardBottomAreaView oldBottomArea) {
+        setKeyguardIndicationController(oldBottomArea.mIndicationController);
+        setStatusBar(oldBottomArea.mStatusBar);
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -563,7 +566,8 @@
             return;
         }
         mDarkAmount = darkAmount;
-        mIndicationArea.setAlpha(1f - darkAmount);
+        mIndicationController.setDarkAmount(darkAmount);
+        mLockIcon.setDarkAmount(darkAmount);
     }
 
     private static boolean isSuccessfulLaunch(int result) {
@@ -580,7 +584,8 @@
         }
     }
 
-    private void launchVoiceAssist() {
+    @VisibleForTesting
+    void launchVoiceAssist() {
         Runnable runnable = new Runnable() {
             @Override
             public void run() {
@@ -705,8 +710,6 @@
             startFinishDozeAnimationElement(mLeftAffordanceView, delay);
             delay += DOZE_ANIMATION_STAGGER_DELAY;
         }
-        startFinishDozeAnimationElement(mLockIcon, delay);
-        delay += DOZE_ANIMATION_STAGGER_DELAY;
         if (mRightAffordanceView.getVisibility() == View.VISIBLE) {
             startFinishDozeAnimationElement(mRightAffordanceView, delay);
         }
@@ -791,6 +794,10 @@
         mIndicationController = keyguardIndicationController;
     }
 
+    public void showTransientIndication(int id) {
+        mIndicationController.showTransientIndication(id);
+    }
+
     public void updateLeftAffordance() {
         updateLeftAffordanceIcon();
         updateLeftPreview();
@@ -823,10 +830,8 @@
         updateLeftAffordanceIcon();
 
         if (dozing) {
-            mLockIcon.setVisibility(INVISIBLE);
             mOverlayContainer.setVisibility(INVISIBLE);
         } else {
-            mLockIcon.setVisibility(VISIBLE);
             mOverlayContainer.setVisibility(VISIBLE);
             if (animate) {
                 startFinishDozeAnimation();
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 2a4595b..235629b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.keyguard.KeyguardHostView.OnDismissAction;
+import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
 
 import android.content.Context;
@@ -361,6 +361,8 @@
         } else if (fraction == EXPANSION_HIDDEN && oldExpansion != EXPANSION_HIDDEN) {
             onFullyHidden();
             mExpansionCallback.onFullyHidden();
+        } else if (fraction != EXPANSION_VISIBLE && oldExpansion == EXPANSION_VISIBLE) {
+            mExpansionCallback.onStartingToHide();
         }
     }
 
@@ -481,6 +483,7 @@
 
     public interface BouncerExpansionCallback {
         void onFullyShown();
+        void onStartingToHide();
         void onFullyHidden();
     }
 }
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 33bc164..4a7bc3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -108,11 +108,7 @@
      * Dozing and receiving a notification (AOD notification.)
      */
     private boolean mPulsing;
-
-    /**
-     * Distance in pixels between the top of the screen and the first view of the bouncer.
-     */
-    private int mBouncerTop;
+    private float mEmptyDragAmount;
 
     /**
      * Refreshes the dimension values.
@@ -131,9 +127,8 @@
     }
 
     public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
-            float panelExpansion, int parentHeight,
-            int keyguardStatusHeight, float dark, boolean secure, boolean pulsing,
-            int bouncerTop) {
+            float panelExpansion, int parentHeight, int keyguardStatusHeight, float dark,
+            boolean secure, boolean pulsing, float emptyDragAmount) {
         mMinTopMargin = minTopMargin + mContainerTopPadding;
         mMaxShadeBottom = maxShadeBottom;
         mNotificationStackHeight = notificationStackHeight;
@@ -143,14 +138,14 @@
         mDarkAmount = dark;
         mCurrentlySecure = secure;
         mPulsing = pulsing;
-        mBouncerTop = bouncerTop;
+        mEmptyDragAmount = emptyDragAmount;
     }
 
     public void run(Result result) {
         final int y = getClockY();
         result.clockY = y;
         result.clockAlpha = getClockAlpha(y);
-        result.stackScrollerPadding = y + (mPulsing ? 0 : mKeyguardStatusHeight);
+        result.stackScrollerPadding = y + (mPulsing ? mPulsingPadding : mKeyguardStatusHeight);
         result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount);
     }
 
@@ -194,15 +189,14 @@
         }
 
         float clockYRegular = getExpandedClockPosition();
-        boolean hasEnoughSpace = mMinTopMargin + mKeyguardStatusHeight < mBouncerTop;
-        float clockYTarget = mCurrentlySecure && hasEnoughSpace ?
-                mMinTopMargin : -mKeyguardStatusHeight;
+        float clockYBouncer = -mKeyguardStatusHeight;
 
         // Move clock up while collapsing the shade
         float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(mPanelExpansion);
-        final float clockY = MathUtils.lerp(clockYTarget, clockYRegular, shadeExpansion);
+        float clockY = MathUtils.lerp(clockYBouncer, clockYRegular, shadeExpansion);
+        clockYDark = MathUtils.lerp(clockYBouncer, clockYDark, shadeExpansion);
 
-        return (int) MathUtils.lerp(clockY, clockYDark, mDarkAmount);
+        return (int) (MathUtils.lerp(clockY, clockYDark, mDarkAmount) + 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 76ddca4..6111178 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
@@ -16,9 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
-import android.annotation.Nullable;
-
-import com.android.keyguard.KeyguardHostView.OnDismissAction;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 
 
 /** Executes actions that require the screen to be unlocked. */
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 d676692..462201c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
@@ -18,7 +18,7 @@
 
 import android.util.Log;
 
-import com.android.keyguard.KeyguardHostView.OnDismissAction;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 
 /**
  * Executes actions that require the screen to be unlocked. Delegates the actual handling to an
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java
new file mode 100644
index 0000000..b3423a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardEnvironmentImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
+import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG;
+
+import android.service.notification.StatusBarNotification;
+import android.util.Log;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+
+public class KeyguardEnvironmentImpl implements KeyguardEnvironment {
+
+    private static final String TAG = "KeyguardEnvironmentImpl";
+
+    private final NotificationLockscreenUserManager mLockscreenUserManager =
+            Dependency.get(NotificationLockscreenUserManager.class);
+    private final DeviceProvisionedController mDeviceProvisionedController =
+            Dependency.get(DeviceProvisionedController.class);
+    private final NotificationMediaManager mMediaManager =
+            Dependency.get(NotificationMediaManager.class);
+
+    public KeyguardEnvironmentImpl() {
+    }
+
+    @Override  // NotificationData.KeyguardEnvironment
+    public boolean isDeviceProvisioned() {
+        return mDeviceProvisionedController.isDeviceProvisioned();
+    }
+
+    @Override  // NotificationData.KeyguardEnvironment
+    public boolean isNotificationForCurrentProfiles(StatusBarNotification n) {
+        final int notificationUserId = n.getUserId();
+        if (DEBUG && MULTIUSER_DEBUG) {
+            Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d", n,
+                    mLockscreenUserManager.getCurrentUserId(), notificationUserId));
+        }
+        return mLockscreenUserManager.isCurrentProfile(notificationUserId);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index 7c84df9..e85ff8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -519,7 +519,14 @@
         mStatusIconContainer.setAlpha(alpha);
         mStatusIconContainer.setVisibility(visibility);
 
-        mSystemIconsContainer.setTranslationX(-mCurrentBurnInOffsetX * mDarkAmount);
+        float iconsX = -mCurrentBurnInOffsetX;
+        if (mMultiUserSwitch.getVisibility() == VISIBLE) {
+            // Squared alpha to add a nice easing curve and avoid overlap during animation.
+            mMultiUserAvatar.setAlpha(alpha * alpha);
+            iconsX += mMultiUserAvatar.getPaddingLeft() + mMultiUserAvatar.getWidth()
+                    + mMultiUserAvatar.getPaddingRight();
+        }
+        mSystemIconsContainer.setTranslationX(iconsX * mDarkAmount);
         mSystemIconsContainer.setTranslationY(mCurrentBurnInOffsetY * mDarkAmount);
         updateIconsAndTextColors();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 8928530..d5067b5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -18,13 +18,14 @@
 
 import android.content.Context;
 import android.content.res.Configuration;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
 import android.graphics.drawable.AnimatedVectorDrawable;
 import android.graphics.drawable.Drawable;
-import android.graphics.drawable.InsetDrawable;
 import android.util.AttributeSet;
-import android.view.View;
 import android.view.accessibility.AccessibilityNodeInfo;
 
+import com.android.internal.graphics.ColorUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
@@ -51,7 +52,6 @@
     private boolean mScreenOn;
     private boolean mLastScreenOn;
     private Drawable mUserAvatarIcon;
-    private TrustDrawable mTrustDrawable;
     private final UnlockMethodCache mUnlockMethodCache;
     private AccessibilityController mAccessibilityController;
     private boolean mHasFingerPrintIcon;
@@ -59,31 +59,14 @@
     private int mDensity;
 
     private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */);
+    private float mDarkAmount;
 
     public LockIcon(Context context, AttributeSet attrs) {
         super(context, attrs);
-        mTrustDrawable = new TrustDrawable(context);
-        setBackground(mTrustDrawable);
         mUnlockMethodCache = UnlockMethodCache.getInstance(context);
     }
 
     @Override
-    protected void onVisibilityChanged(View changedView, int visibility) {
-        super.onVisibilityChanged(changedView, visibility);
-        if (isShown()) {
-            mTrustDrawable.start();
-        } else {
-            mTrustDrawable.stop();
-        }
-    }
-
-    @Override
-    protected void onDetachedFromWindow() {
-        super.onDetachedFromWindow();
-        mTrustDrawable.stop();
-    }
-
-    @Override
     public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
         mUserAvatarIcon = picture;
         update();
@@ -110,9 +93,6 @@
         final int density = newConfig.densityDpi;
         if (density != mDensity) {
             mDensity = density;
-            mTrustDrawable.stop();
-            mTrustDrawable = new TrustDrawable(getContext());
-            setBackground(mTrustDrawable);
             update();
         }
     }
@@ -122,18 +102,9 @@
     }
 
     public void update(boolean force) {
-        boolean visible = isShown()
-                && KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
-        if (visible) {
-            mTrustDrawable.start();
-        } else {
-            mTrustDrawable.stop();
-        }
         int state = getState();
         boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
         mHasFaceUnlockIcon = state == STATE_FACE_UNLOCK;
-        boolean useAdditionalPadding = anyFingerprintIcon;
-        boolean trustHidden = anyFingerprintIcon;
         if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
                 || mScreenOn != mLastScreenOn || force) {
             int iconAnimRes =
@@ -142,16 +113,10 @@
             boolean isAnim = iconAnimRes != -1;
             if (iconAnimRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
                 anyFingerprintIcon = true;
-                useAdditionalPadding = true;
-                trustHidden = true;
             } else if (iconAnimRes == R.drawable.trusted_state_to_error_animation) {
                 anyFingerprintIcon = true;
-                useAdditionalPadding = false;
-                trustHidden = true;
             } else if (iconAnimRes == R.drawable.error_to_trustedstate_animation) {
                 anyFingerprintIcon = true;
-                useAdditionalPadding = false;
-                trustHidden = false;
             }
 
             Drawable icon;
@@ -166,21 +131,8 @@
             final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
                     ? (AnimatedVectorDrawable) icon
                     : null;
-            int iconHeight = getResources().getDimensionPixelSize(
-                    R.dimen.keyguard_affordance_icon_height);
-            int iconWidth = getResources().getDimensionPixelSize(
-                    R.dimen.keyguard_affordance_icon_width);
-            if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
-                    || icon.getIntrinsicWidth() != iconWidth)) {
-                icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
-            }
-            setPaddingRelative(0, 0, 0, useAdditionalPadding
-                    ? getResources().getDimensionPixelSize(
-                    R.dimen.fingerprint_icon_additional_padding)
-                    : 0);
-            setRestingAlpha(
-                    anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
             setImageDrawable(icon, false);
+            updateDarkTint();
             if (mHasFaceUnlockIcon) {
                 announceForAccessibility(getContext().getString(
                     R.string.accessibility_scanning_face));
@@ -204,9 +156,6 @@
             mLastScreenOn = mScreenOn;
         }
 
-        // Hide trust circle when fingerprint is running.
-        boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !trustHidden;
-        mTrustDrawable.setTrustManaged(trustManaged);
         updateClickability();
     }
 
@@ -250,27 +199,21 @@
     private Drawable getIconForState(int state, boolean screenOn, boolean deviceInteractive) {
         int iconRes;
         switch (state) {
+            case STATE_FINGERPRINT:
             case STATE_LOCKED:
-                iconRes = R.drawable.ic_lock_24dp;
+                iconRes = R.drawable.ic_lock;
                 break;
             case STATE_LOCK_OPEN:
                 if (mUnlockMethodCache.isTrustManaged() && mUnlockMethodCache.isTrusted()
                     && mUserAvatarIcon != null) {
                     return mUserAvatarIcon;
                 } else {
-                    iconRes = R.drawable.ic_lock_open_24dp;
+                    iconRes = R.drawable.ic_lock_open;
                 }
                 break;
             case STATE_FACE_UNLOCK:
                 iconRes = R.drawable.ic_face_unlock;
                 break;
-            case STATE_FINGERPRINT:
-                // If screen is off and device asleep, use the draw on animation so the first frame
-                // gets drawn.
-                iconRes = screenOn && deviceInteractive
-                        ? R.drawable.ic_fingerprint
-                        : R.drawable.lockscreen_fingerprint_draw_on_animation;
-                break;
             case STATE_FINGERPRINT_ERROR:
                 iconRes = R.drawable.ic_fingerprint_error;
                 break;
@@ -320,28 +263,14 @@
         }
     }
 
-    /**
-     * A wrapper around another Drawable that overrides the intrinsic size.
-     */
-    private static class IntrinsicSizeDrawable extends InsetDrawable {
+    public void setDarkAmount(float darkAmount) {
+        mDarkAmount = darkAmount;
+        updateDarkTint();
+    }
 
-        private final int mIntrinsicWidth;
-        private final int mIntrinsicHeight;
-
-        public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
-            super(drawable, 0);
-            mIntrinsicWidth = intrinsicWidth;
-            mIntrinsicHeight = intrinsicHeight;
-        }
-
-        @Override
-        public int getIntrinsicWidth() {
-            return mIntrinsicWidth;
-        }
-
-        @Override
-        public int getIntrinsicHeight() {
-            return mIntrinsicHeight;
-        }
+    private void updateDarkTint() {
+        Drawable drawable = getDrawable().mutate();
+        int color = ColorUtils.blendARGB(Color.TRANSPARENT, Color.WHITE, mDarkAmount);
+        drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index 40ddf5b..673cdb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -40,6 +40,8 @@
 import android.util.Log;
 
 import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dependency;
+import com.android.systemui.statusbar.NotificationMediaManager;
 
 import libcore.io.IoUtils;
 
@@ -52,6 +54,9 @@
 
     private static final String TAG = "LockscreenWallpaper";
 
+    private final NotificationMediaManager mMediaManager =
+            Dependency.get(NotificationMediaManager.class);
+
     private final StatusBar mBar;
     private final WallpaperManager mWallpaperManager;
     private final Handler mH;
@@ -193,7 +198,7 @@
                     mCached = true;
                     mCache = result.bitmap;
                     mUpdateMonitor.setHasLockscreenWallpaper(result.bitmap != null);
-                    mBar.updateMediaMetaData(
+                    mMediaManager.updateMediaMetaData(
                             true /* metaDataChanged */, true /* allowEnterAnimation */);
                 }
                 mLoader = null;
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 9c579da..6edde07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -19,26 +19,20 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
 
-import static com.android.internal.view.RotationPolicy.NATURAL_ROTATION;
-
+import static com.android.systemui.OverviewProxyService.OverviewProxyListener;
 import static com.android.systemui.shared.system.NavigationBarCompat.InteractionType;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.StatusBar.DEBUG_WINDOW_STATE;
 import static com.android.systemui.statusbar.phone.StatusBar.dumpBarTransitions;
-import static com.android.systemui.OverviewProxyService.OverviewProxyListener;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
 import android.annotation.IdRes;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
 import android.app.Fragment;
-import android.app.IActivityManager;
 import android.app.IActivityTaskManager;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
@@ -55,11 +49,9 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Message;
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
-import androidx.annotation.VisibleForTesting;
 import android.telecom.TelecomManager;
 import android.text.TextUtils;
 import android.util.Log;
@@ -72,16 +64,16 @@
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.WindowManager.LayoutParams;
-import android.view.WindowManagerGlobal;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener;
 
+import androidx.annotation.VisibleForTesting;
+
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.LatencyTracker;
 import com.android.systemui.Dependency;
-import com.android.systemui.Interpolators;
 import com.android.systemui.OverviewProxyService;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
@@ -90,21 +82,20 @@
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.TaskStackChangeListener;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CommandQueue.Callbacks;
-import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
-import com.android.systemui.statusbar.policy.KeyButtonDrawable;
-import com.android.systemui.statusbar.policy.KeyButtonView;
-import com.android.systemui.statusbar.policy.RotationLockController;
 import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
+import com.android.systemui.statusbar.phone.ContextualButton.ContextButtonListener;
+import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyButtonView;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.List;
 import java.util.Locale;
-import java.util.Optional;
+import java.util.function.Consumer;
 
 /**
  * Fragment containing the NavigationBarFragment. Contains logic for what happens
@@ -114,18 +105,15 @@
 
     public static final String TAG = "NavigationBar";
     private static final boolean DEBUG = false;
-    private static final boolean DEBUG_ROTATION = true;
     private static final String EXTRA_DISABLE_STATE = "disabled_state";
     private static final String EXTRA_DISABLE2_STATE = "disabled2_state";
 
-    private final static int BUTTON_FADE_IN_OUT_DURATION_MS = 100;
-    private final static int NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS = 20000;
-
-    private static final int NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION = 3;
-
     /** Allow some time inbetween the long press for back and recents. */
     private static final int LOCK_TO_APP_GESTURE_TOLERENCE = 200;
 
+    private final DeviceProvisionedController mDeviceProvisionedController =
+            Dependency.get(DeviceProvisionedController.class);
+
     protected NavigationBarView mNavigationBarView = null;
     protected AssistManager mAssistManager;
 
@@ -133,7 +121,6 @@
 
     private int mNavigationIconHints = 0;
     private int mNavigationBarMode;
-    private boolean mAccessibilityFeedbackEnabled;
     private AccessibilityManager mAccessibilityManager;
     private MagnificationContentObserver mMagnificationObserver;
     private ContentResolver mContentResolver;
@@ -158,18 +145,6 @@
 
     public boolean mHomeBlockedThisTouch;
 
-    private int mLastRotationSuggestion;
-    private boolean mPendingRotationSuggestion;
-    private boolean mHoveringRotationSuggestion;
-    private RotationLockController mRotationLockController;
-    private TaskStackListenerImpl mTaskStackListener;
-
-    private final Runnable mRemoveRotationProposal = () -> setRotateSuggestionButtonState(false);
-    private final Runnable mCancelPendingRotationProposal =
-            () -> mPendingRotationSuggestion = false;
-    private Animator mRotateHideAnimator;
-    private ViewRippler mViewRippler = new ViewRippler();
-
     private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
         @Override
         public void onConnectionChanged(boolean isConnected) {
@@ -180,7 +155,7 @@
         @Override
         public void onQuickStepStarted() {
             // Use navbar dragging as a signal to hide the rotate button
-            setRotateSuggestionButtonState(false);
+            mNavigationBarView.getRotateSuggestionButton().setRotateSuggestionButtonState(false);
 
             // Hide the notifications panel when quick step starts
             mStatusBar.collapsePanel(true /* animate */);
@@ -195,7 +170,7 @@
         @Override
         public void onBackButtonAlphaChanged(float alpha, boolean animate) {
             final ButtonDispatcher backButton = mNavigationBarView.getBackButton();
-            if (QuickStepController.shouldhideBackButton()) {
+            if (QuickStepController.shouldhideBackButton(getContext())) {
                 // If property was changed to hide/show back button, going home will trigger
                 // launcher to to change the back button alpha to reflect property change
                 backButton.setVisibility(View.GONE);
@@ -206,6 +181,17 @@
         }
     };
 
+    private final ContextButtonListener mRotationButtonListener = new ContextButtonListener() {
+        @Override
+        public void onVisibilityChanged(ContextualButton button, boolean visible) {
+            if (visible) {
+                // If the button will actually become visible and the navbar is about to hide,
+                // tell the statusbar to keep it around for longer
+                mStatusBar.touchAutoHide();
+            }
+        }
+    };
+
     // ----- Fragment Lifecycle Callbacks -----
 
     @Override
@@ -233,26 +219,6 @@
         }
         mAssistManager = Dependency.get(AssistManager.class);
         mOverviewProxyService = Dependency.get(OverviewProxyService.class);
-
-        try {
-            WindowManagerGlobal.getWindowManagerService()
-                    .watchRotation(mRotationWatcher, getContext().getDisplay().getDisplayId());
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
-        mRotationLockController = Dependency.get(RotationLockController.class);
-
-        // Reset user rotation pref to match that of the WindowManager if starting in locked mode
-        // This will automatically happen when switching from auto-rotate to locked mode
-        if (mRotationLockController.isRotationLocked()) {
-            final int winRotation = mWindowManager.getDefaultDisplay().getRotation();
-            mRotationLockController.setRotationLockedAtAngle(true, winRotation);
-        }
-
-        // Register the task stack listener
-        mTaskStackListener = new TaskStackListenerImpl();
-        ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
     }
 
     @Override
@@ -262,15 +228,6 @@
         Dependency.get(AccessibilityManagerWrapper.class).removeCallback(
                 mAccessibilityListener);
         mContentResolver.unregisterContentObserver(mMagnificationObserver);
-        try {
-            WindowManagerGlobal.getWindowManagerService()
-                    .removeRotationWatcher(mRotationWatcher);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-
-        // Unregister the task stack listener
-        ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
     }
 
     @Override
@@ -284,8 +241,8 @@
         super.onViewCreated(view, savedInstanceState);
         mNavigationBarView = (NavigationBarView) view;
 
-        mNavigationBarView.setDisabledFlags(mDisabledFlags1);
         mNavigationBarView.setComponents(mStatusBar.getPanel());
+        mNavigationBarView.setDisabledFlags(mDisabledFlags1);
         mNavigationBarView.setOnVerticalChangedListener(this::onVerticalChanged);
         mNavigationBarView.setOnTouchListener(this::onNavigationTouch);
         if (savedInstanceState != null) {
@@ -303,6 +260,17 @@
         getContext().registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, filter, null, null);
         notifyNavigationBarScreenOn();
         mOverviewProxyService.addCallback(mOverviewProxyListener);
+
+        RotationContextButton rotationButton = mNavigationBarView.getRotateSuggestionButton();
+        rotationButton.setListener(mRotationButtonListener);
+        rotationButton.addRotationCallback(mRotationWatcher);
+
+        // Reset user rotation pref to match that of the WindowManager if starting in locked mode
+        // This will automatically happen when switching from auto-rotate to locked mode
+        if (rotationButton.isRotationLocked()) {
+            final int winRotation = mWindowManager.getDefaultDisplay().getRotation();
+            rotationButton.setRotationLockedAtAngle(winRotation);
+        }
     }
 
     @Override
@@ -413,237 +381,42 @@
             mNavigationBarWindowState = state;
             if (DEBUG_WINDOW_STATE) Log.d(TAG, "Navigation bar " + windowStateToString(state));
 
-            // If the navbar is visible, show the rotate button if there's a pending suggestion
-            if (state == WINDOW_STATE_SHOWING && mPendingRotationSuggestion) {
-                showAndLogRotationSuggestion();
-            }
+            mNavigationBarView.getRotateSuggestionButton()
+                    .onNavigationBarWindowVisibilityChange(state == WINDOW_STATE_SHOWING);
         }
     }
 
     @Override
     public void onRotationProposal(final int rotation, boolean isValid) {
         final int winRotation = mWindowManager.getDefaultDisplay().getRotation();
-        final boolean rotateSuggestionsDisabled = hasDisable2RotateSuggestionFlag(mDisabledFlags2);
-        if (DEBUG_ROTATION) {
+        final boolean rotateSuggestionsDisabled = RotationContextButton
+                .hasDisable2RotateSuggestionFlag(mDisabledFlags2);
+        if (RotationContextButton.DEBUG_ROTATION) {
             Log.v(TAG, "onRotationProposal proposedRotation=" + Surface.rotationToString(rotation)
                     + ", winRotation=" + Surface.rotationToString(winRotation)
                     + ", isValid=" + isValid + ", mNavBarWindowState="
                     + StatusBarManager.windowStateToString(mNavigationBarWindowState)
                     + ", rotateSuggestionsDisabled=" + rotateSuggestionsDisabled
                     + ", isRotateButtonVisible=" + (mNavigationBarView == null ? "null" :
-                        mNavigationBarView.isRotateButtonVisible()));
+                        mNavigationBarView.getRotateSuggestionButton().isVisible()));
         }
 
         // Respect the disabled flag, no need for action as flag change callback will handle hiding
         if (rotateSuggestionsDisabled) return;
 
-        // This method will be called on rotation suggestion changes even if the proposed rotation
-        // is not valid for the top app. Use invalid rotation choices as a signal to remove the
-        // rotate button if shown.
-        if (!isValid) {
-            setRotateSuggestionButtonState(false);
-            return;
-        }
-
-        // If window rotation matches suggested rotation, remove any current suggestions
-        if (rotation == winRotation) {
-            getView().removeCallbacks(mRemoveRotationProposal);
-            setRotateSuggestionButtonState(false);
-            return;
-        }
-
-        // Prepare to show the navbar icon by updating the icon style to change anim params
-        mLastRotationSuggestion = rotation; // Remember rotation for click
-        if (mNavigationBarView != null) {
-            final boolean rotationCCW = isRotationAnimationCCW(winRotation, rotation);
-            int style;
-            if (winRotation == Surface.ROTATION_0 || winRotation == Surface.ROTATION_180) {
-                style = rotationCCW ? R.style.RotateButtonCCWStart90 :
-                        R.style.RotateButtonCWStart90;
-            } else { // 90 or 270
-                style = rotationCCW ? R.style.RotateButtonCCWStart0 :
-                        R.style.RotateButtonCWStart0;
-            }
-            mNavigationBarView.updateRotateSuggestionButtonStyle(style);
-        }
-
-        if (mNavigationBarWindowState != WINDOW_STATE_SHOWING) {
-            // If the navbar isn't shown, flag the rotate icon to be shown should the navbar become
-            // visible given some time limit.
-            mPendingRotationSuggestion = true;
-            getView().removeCallbacks(mCancelPendingRotationProposal);
-            getView().postDelayed(mCancelPendingRotationProposal,
-                    NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS);
-
-        } else { // The navbar is visible so show the icon right away
-            showAndLogRotationSuggestion();
-        }
-    }
-
-    private void onRotationSuggestionsDisabled() {
-        // Immediately hide the rotate button and clear any planned removal
-        setRotateSuggestionButtonState(false, true);
-
-        // This method can be called before view setup is done, ensure getView isn't null
-        final View v = getView();
-        if (v != null) v.removeCallbacks(mRemoveRotationProposal);
-    }
-
-    private void showAndLogRotationSuggestion() {
-        setRotateSuggestionButtonState(true);
-        rescheduleRotationTimeout(false);
-        mMetricsLogger.visible(MetricsEvent.ROTATION_SUGGESTION_SHOWN);
-    }
-
-    private boolean isRotationAnimationCCW(int from, int to) {
-        // All 180deg WM rotation animations are CCW, match that
-        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_90) return false;
-        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_180) return true; //180d so CCW
-        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_270) return true;
-        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_0) return true;
-        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_180) return false;
-        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_270) return true; //180d so CCW
-        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_0) return true; //180d so CCW
-        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_90) return true;
-        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_270) return false;
-        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_0) return false;
-        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_90) return true; //180d so CCW
-        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_180) return true;
-        return false; // Default
-    }
-
-    public void setRotateSuggestionButtonState(final boolean visible) {
-        setRotateSuggestionButtonState(visible, false);
-    }
-
-    public void setRotateSuggestionButtonState(final boolean visible, final boolean force) {
-        if (mNavigationBarView == null) return;
-
-        // At any point the the button can become invisible because an a11y service became active.
-        // Similarly, a call to make the button visible may be rejected because an a11y service is
-        // active. Must account for this.
-
-        ButtonDispatcher rotBtn = mNavigationBarView.getRotateSuggestionButton();
-        final boolean currentlyVisible = mNavigationBarView.isRotateButtonVisible();
-
-        // Rerun a show animation to indicate change but don't rerun a hide animation
-        if (!visible && !currentlyVisible) return;
-
-        View view = rotBtn.getCurrentView();
-        if (view == null) return;
-
-        KeyButtonDrawable kbd = rotBtn.getImageDrawable();
-        if (kbd == null) return;
-
-        // Clear any pending suggestion flag as it has either been nullified or is being shown
-        mPendingRotationSuggestion = false;
-        if (getView() != null) getView().removeCallbacks(mCancelPendingRotationProposal);
-
-        // Handle the visibility change and animation
-        if (visible) { // Appear and change (cannot force)
-            // Stop and clear any currently running hide animations
-            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
-                mRotateHideAnimator.cancel();
-            }
-            mRotateHideAnimator = null;
-
-            // Reset the alpha if any has changed due to hide animation
-            view.setAlpha(1f);
-
-            // Run the rotate icon's animation if it has one
-            if (kbd.canAnimate()) {
-                kbd.resetAnimation();
-                kbd.startAnimation();
-            }
-
-            if (!isRotateSuggestionIntroduced()) mViewRippler.start(view);
-
-            // Set visibility, may fail if a11y service is active.
-            // If invisible, call will stop animation.
-            int appliedVisibility = mNavigationBarView.setRotateButtonVisibility(true);
-            if (appliedVisibility == View.VISIBLE) {
-                // If the button will actually become visible and the navbar is about to hide,
-                // tell the statusbar to keep it around for longer
-                mStatusBar.touchAutoHide();
-            }
-
-        } else { // Hide
-
-            mViewRippler.stop(); // Prevent any pending ripples, force hide or not
-
-            if (force) {
-                // If a hide animator is running stop it and make invisible
-                if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
-                    mRotateHideAnimator.pause();
-                }
-                mNavigationBarView.setRotateButtonVisibility(false);
-                return;
-            }
-
-            // Don't start any new hide animations if one is running
-            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) return;
-
-            ObjectAnimator fadeOut = ObjectAnimator.ofFloat(view, "alpha",
-                    0f);
-            fadeOut.setDuration(BUTTON_FADE_IN_OUT_DURATION_MS);
-            fadeOut.setInterpolator(Interpolators.LINEAR);
-            fadeOut.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    mNavigationBarView.setRotateButtonVisibility(false);
-                }
-            });
-
-            mRotateHideAnimator = fadeOut;
-            fadeOut.start();
-        }
-    }
-
-    private void rescheduleRotationTimeout(final boolean reasonHover) {
-        // 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
-            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) return;
-            // Don't reschedule if not visible
-            if (!mNavigationBarView.isRotateButtonVisible()) return;
-        }
-
-        getView().removeCallbacks(mRemoveRotationProposal); // Stop any pending removal
-        getView().postDelayed(mRemoveRotationProposal,
-                computeRotationProposalTimeout()); // Schedule timeout
-    }
-
-    private int computeRotationProposalTimeout() {
-        if (mAccessibilityFeedbackEnabled) return 20000;
-        if (mHoveringRotationSuggestion) return 16000;
-        return 10000;
-    }
-
-    private boolean isRotateSuggestionIntroduced() {
-        ContentResolver cr = getContext().getContentResolver();
-        return Settings.Secure.getInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0)
-                >= NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION;
-    }
-
-    private void incrementNumAcceptedRotationSuggestionsIfNeeded() {
-        // Get the number of accepted suggestions
-        ContentResolver cr = getContext().getContentResolver();
-        final int numSuggestions = Settings.Secure.getInt(cr,
-                Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0);
-
-        // Increment the number of accepted suggestions only if it would change intro mode
-        if (numSuggestions < NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION) {
-            Settings.Secure.putInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED,
-                    numSuggestions + 1);
-        }
+        mNavigationBarView.getRotateSuggestionButton()
+                .onRotationProposal(rotation, winRotation, isValid);
     }
 
     // Injected from StatusBar at creation.
     public void setCurrentSysuiVisibility(int systemUiVisibility) {
         mSystemUiVisibility = systemUiVisibility;
-        mNavigationBarMode = mStatusBar.computeBarMode(0, mSystemUiVisibility,
+        final int barMode = mStatusBar.computeBarMode(0, mSystemUiVisibility,
                 View.NAVIGATION_BAR_TRANSIENT, View.NAVIGATION_BAR_TRANSLUCENT,
                 View.NAVIGATION_BAR_TRANSPARENT);
+        if (barMode != -1) {
+            mNavigationBarMode = barMode;
+        }
         checkNavBarModes();
         mStatusBar.touchAutoHide();
         mLightBarController.onNavigationVisibilityChanged(mSystemUiVisibility, 0 /* mask */,
@@ -705,12 +478,7 @@
 
     private void setDisabled2Flags(int state2) {
         // Method only called on change of disable2 flags
-        final boolean rotateSuggestionsDisabled = hasDisable2RotateSuggestionFlag(state2);
-        if (rotateSuggestionsDisabled) onRotationSuggestionsDisabled();
-    }
-
-    private boolean hasDisable2RotateSuggestionFlag(int disable2Flags) {
-        return (disable2Flags & StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS) != 0;
+        mNavigationBarView.getRotateSuggestionButton().onDisable2FlagChanged(state2);
     }
 
     // ----- Internal stuffz -----
@@ -722,7 +490,7 @@
     }
 
     private boolean shouldDisableNavbarGestures() {
-        return !mStatusBar.isDeviceProvisioned()
+        return !mDeviceProvisionedController.isDeviceProvisioned()
                 || (mDisabledFlags1 & StatusBarManager.DISABLE_SEARCH) != 0;
     }
 
@@ -775,9 +543,6 @@
         accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
         updateAccessibilityServicesState(mAccessibilityManager);
 
-        ButtonDispatcher rotateSuggestionButton = mNavigationBarView.getRotateSuggestionButton();
-        rotateSuggestionButton.setOnClickListener(this::onRotateSuggestionClick);
-        rotateSuggestionButton.setOnHoverListener(this::onRotateSuggestionHover);
         updateScreenPinningGestures();
     }
 
@@ -997,27 +762,14 @@
             }
         }
 
-        mAccessibilityFeedbackEnabled = feedbackEnabled;
+        mNavigationBarView.getRotateSuggestionButton()
+                .setAccessibilityFeedbackEnabled(feedbackEnabled);
 
         final boolean showAccessibilityButton = requestingServices >= 1;
         final boolean targetSelection = requestingServices >= 2;
         mNavigationBarView.setAccessibilityButtonState(showAccessibilityButton, targetSelection);
     }
 
-    private void onRotateSuggestionClick(View v) {
-        mMetricsLogger.action(MetricsEvent.ACTION_ROTATION_SUGGESTION_ACCEPTED);
-        incrementNumAcceptedRotationSuggestionsIfNeeded();
-        mRotationLockController.setRotationLockedAtAngle(true, mLastRotationSuggestion);
-    }
-
-    private boolean onRotateSuggestionHover(View v, MotionEvent event) {
-        final int action = event.getActionMasked();
-        mHoveringRotationSuggestion = (action == MotionEvent.ACTION_HOVER_ENTER)
-                || (action == MotionEvent.ACTION_HOVER_MOVE);
-        rescheduleRotationTimeout(true);
-        return false; // Must return false so a11y hover events are dispatched correctly.
-    }
-
     // ----- Methods that StatusBar talks to (should be minimized) -----
 
     public void setLightBarController(LightBarController lightBarController) {
@@ -1063,36 +815,10 @@
         }
     }
 
-    private final Stub mRotationWatcher = new Stub() {
-        @Override
-        public void onRotationChanged(final int rotation) throws RemoteException {
-            // We need this to be scheduled as early as possible to beat the redrawing of
-            // window in response to the orientation change.
-            Handler h = getView().getHandler();
-            Message msg = Message.obtain(h, () -> {
-
-                // If the screen rotation changes while locked, potentially update lock to flow with
-                // new screen rotation and hide any showing suggestions.
-                if (mRotationLockController.isRotationLocked()) {
-                    if (shouldOverrideUserLockPrefs(rotation)) {
-                        mRotationLockController.setRotationLockedAtAngle(true, rotation);
-                    }
-                    setRotateSuggestionButtonState(false, true);
-                }
-
-                if (mNavigationBarView != null
-                        && mNavigationBarView.needsReorient(rotation)) {
-                    repositionNavigationBar();
-                }
-            });
-            msg.setAsynchronous(true);
-            h.sendMessageAtFrontOfQueue(msg);
-        }
-
-        private boolean shouldOverrideUserLockPrefs(final int rotation) {
-            // Only override user prefs when returning to the natural rotation (normally portrait).
-            // Don't let apps that force landscape or 180 alter user lock.
-            return rotation == NATURAL_ROTATION;
+    private final Consumer<Integer> mRotationWatcher = rotation -> {
+        if (mNavigationBarView != null
+                && mNavigationBarView.needsReorient(rotation)) {
+            repositionNavigationBar();
         }
     };
 
@@ -1111,69 +837,6 @@
         }
     };
 
-    class TaskStackListenerImpl extends TaskStackChangeListener {
-        // Invalidate any rotation suggestion on task change or activity orientation change
-        // Note: all callbacks happen on main thread
-
-        @Override
-        public void onTaskStackChanged() {
-            setRotateSuggestionButtonState(false);
-        }
-
-        @Override
-        public void onTaskRemoved(int taskId) {
-            setRotateSuggestionButtonState(false);
-        }
-
-        @Override
-        public void onTaskMovedToFront(int taskId) {
-            setRotateSuggestionButtonState(false);
-        }
-
-        @Override
-        public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) {
-            // Only hide the icon if the top task changes its requestedOrientation
-            // Launcher can alter its requestedOrientation while it's not on top, don't hide on this
-            Optional.ofNullable(ActivityManagerWrapper.getInstance())
-                    .map(ActivityManagerWrapper::getRunningTask)
-                    .ifPresent(a -> {
-                        if (a.id == taskId) setRotateSuggestionButtonState(false);
-                    });
-        }
-    }
-
-    private class ViewRippler {
-        private static final int RIPPLE_OFFSET_MS = 50;
-        private static final int RIPPLE_INTERVAL_MS = 2000;
-        private View mRoot;
-
-        public void start(View root) {
-            stop(); // Stop any pending ripple animations
-
-            mRoot = root;
-
-            // Schedule pending ripples, offset the 1st to avoid problems with visibility change
-            mRoot.postOnAnimationDelayed(mRipple, RIPPLE_OFFSET_MS);
-            mRoot.postOnAnimationDelayed(mRipple, RIPPLE_INTERVAL_MS);
-            mRoot.postOnAnimationDelayed(mRipple, 2*RIPPLE_INTERVAL_MS);
-            mRoot.postOnAnimationDelayed(mRipple, 3*RIPPLE_INTERVAL_MS);
-            mRoot.postOnAnimationDelayed(mRipple, 4*RIPPLE_INTERVAL_MS);
-        }
-
-        public void stop() {
-            if (mRoot != null) mRoot.removeCallbacks(mRipple);
-        }
-
-        private final Runnable mRipple = new Runnable() {
-            @Override
-            public void run() { // Cause the ripple to fire via false presses
-                if (!mRoot.isAttachedToWindow()) return;
-                mRoot.setPressed(true);
-                mRoot.setPressed(false);
-            }
-        };
-    }
-
     public static View create(Context context, FragmentListener listener) {
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
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 16b2987..2ab5958 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -29,7 +29,6 @@
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.annotation.DrawableRes;
-import android.annotation.StyleRes;
 import android.app.StatusBarManager;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -60,7 +59,6 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.OverviewProxyService;
 import com.android.systemui.R;
-import com.android.systemui.RecentsComponent;
 import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.plugins.PluginManager;
@@ -71,7 +69,6 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.NavigationBarCompat;
 import com.android.systemui.shared.system.WindowManagerWrapper;
-import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.policy.DeadZone;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
 
@@ -140,6 +137,7 @@
     private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
     private final ContextualButtonGroup mContextualButtonGroup;
     private Configuration mConfiguration;
+    private Configuration mTmpLastConfiguration;
 
     private NavigationBarInflaterView mNavigationInflaterView;
     private RecentsOnboarding mRecentsOnboarding;
@@ -272,7 +270,7 @@
         final ContextualButton imeSwitcherButton = new ContextualButton(R.id.ime_switcher,
                 R.drawable.ic_ime_switcher_default);
         final RotationContextButton rotateSuggestionButton = new RotationContextButton(
-                R.id.rotate_suggestion, R.drawable.ic_sysbar_rotate_button,
+                R.id.rotate_suggestion, R.drawable.ic_sysbar_rotate_button, getContext(),
                 R.style.RotateButtonCCWStart90);
         final ContextualButton accessibilityButton =
                 new ContextualButton(R.id.accessibility_button,
@@ -286,6 +284,7 @@
         mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService);
 
         mConfiguration = new Configuration();
+        mTmpLastConfiguration = new Configuration();
         mConfiguration.updateFrom(context.getResources().getConfiguration());
 
         mScreenPinningNotify = new ScreenPinningNotify(mContext);
@@ -350,7 +349,7 @@
     @Override
     public boolean onTouchEvent(MotionEvent event) {
         shouldDeadZoneConsumeTouchEvents(event);
-        if (mGestureHelper.onTouchEvent(event)) {
+        if (mGestureHelper != null && mGestureHelper.onTouchEvent(event)) {
             return true;
         }
         return super.onTouchEvent(event);
@@ -418,8 +417,9 @@
         return mButtonDispatchers.get(R.id.accessibility_button);
     }
 
-    public ButtonDispatcher getRotateSuggestionButton() {
-        return mButtonDispatchers.get(R.id.rotate_suggestion);
+    public RotationContextButton getRotateSuggestionButton() {
+        return (RotationContextButton) mContextualButtonGroup
+                .getContextButton(R.id.rotate_suggestion);
     }
 
     public SparseArray<ButtonDispatcher> getButtonDispatchers() {
@@ -445,13 +445,13 @@
     }
 
     private void reloadNavIcons() {
-        updateIcons(Configuration.EMPTY, mConfiguration);
+        updateIcons(Configuration.EMPTY);
     }
 
-    private void updateIcons(Configuration oldConfig, Configuration newConfig) {
-        final boolean orientationChange = oldConfig.orientation != newConfig.orientation;
-        final boolean densityChange = oldConfig.densityDpi != newConfig.densityDpi;
-        final boolean dirChange = oldConfig.getLayoutDirection() != newConfig.getLayoutDirection();
+    private void updateIcons(Configuration oldConfig) {
+        final boolean orientationChange = oldConfig.orientation != mConfiguration.orientation;
+        final boolean densityChange = oldConfig.densityDpi != mConfiguration.densityDpi;
+        final boolean dirChange = oldConfig.getLayoutDirection() != mConfiguration.getLayoutDirection();
 
         if (orientationChange || densityChange) {
             mDockedIcon = getDrawable(R.drawable.ic_sysbar_docked);
@@ -485,7 +485,7 @@
     private void orientBackButton(KeyButtonDrawable drawable) {
         final boolean useAltBack =
                 (mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
-        final boolean isRtl = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+        final boolean isRtl = mConfiguration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
         float degrees = useAltBack
                 ? (isRtl ? 270 : -90)
                 : (isRtl ? 180 : 0);
@@ -594,7 +594,7 @@
         // Always disable recents when alternate car mode UI is active.
         boolean disableRecent = mUseCarModeUi || !isOverviewEnabled();
 
-        boolean disableBack = QuickStepController.shouldhideBackButton()
+        boolean disableBack = QuickStepController.shouldhideBackButton(getContext())
                 || (((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) && !useAltBack);
 
         // When screen pinning, don't hide back and home when connected service or back and
@@ -680,7 +680,9 @@
     }
 
     public void onNavigationButtonLongPress(View v) {
-        mGestureHelper.onNavigationButtonLongPress(v);
+        if (mGestureHelper != null) {
+            mGestureHelper.onNavigationButtonLongPress(v);
+        }
     }
 
     public void onPanelExpandedChange(boolean expanded) {
@@ -744,27 +746,12 @@
         mContextualButtonGroup.setButtonVisiblity(R.id.menu, show);
     }
 
-    public void updateRotateSuggestionButtonStyle(@StyleRes int style) {
-        RotationContextButton button = (RotationContextButton) mContextualButtonGroup
-                .getContextButton(R.id.rotate_suggestion);
-        button.setStyle(style);
-        button.updateIcon();
-    }
-
     public void setAccessibilityButtonState(final boolean visible, final boolean longClickable) {
         mLongClickableAccessibilityButton = longClickable;
         getAccessibilityButton().setLongClickable(longClickable);
         mContextualButtonGroup.setButtonVisiblity(R.id.accessibility_button, visible);
     }
 
-    public int setRotateButtonVisibility(boolean visible) {
-        return mContextualButtonGroup.setButtonVisiblity(R.id.rotate_suggestion, visible);
-    }
-
-    public boolean isRotateButtonVisible() {
-        return getRotateSuggestionButton().isVisible();
-    }
-
     void hideRecentsOnboarding() {
         mRecentsOnboarding.hide(true);
     }
@@ -807,7 +794,9 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        mGestureHelper.onDraw(canvas);
+        if (mGestureHelper != null) {
+            mGestureHelper.onDraw(canvas);
+        }
         mDeadZone.onDraw(canvas);
         super.onDraw(canvas);
     }
@@ -819,7 +808,9 @@
         updateButtonLocationOnScreen(getHomeButton(), mHomeButtonBounds);
         updateButtonLocationOnScreen(getRecentsButton(), mRecentsButtonBounds);
         updateButtonLocationOnScreen(getRotateSuggestionButton(), mRotationButtonBounds);
-        mGestureHelper.onLayout(changed, left, top, right, bottom);
+        if (mGestureHelper != null) {
+            mGestureHelper.onLayout(changed, left, top, right, bottom);
+        }
         mRecentsOnboarding.setNavBarHeight(getMeasuredHeight());
     }
 
@@ -946,26 +937,27 @@
     @Override
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
-        boolean uiCarModeChanged = updateCarMode(newConfig);
+        mTmpLastConfiguration.updateFrom(mConfiguration);
+        mConfiguration.updateFrom(newConfig);
+        boolean uiCarModeChanged = updateCarMode();
         updateTaskSwitchHelper();
-        updateIcons(mConfiguration, newConfig);
+        updateIcons(mTmpLastConfiguration);
         updateRecentsIcon();
-        mRecentsOnboarding.onConfigurationChanged(newConfig);
-        if (uiCarModeChanged || mConfiguration.densityDpi != newConfig.densityDpi
-                || mConfiguration.getLayoutDirection() != newConfig.getLayoutDirection()) {
+        mRecentsOnboarding.onConfigurationChanged(mConfiguration);
+        if (uiCarModeChanged || mTmpLastConfiguration.densityDpi != mConfiguration.densityDpi
+                || mTmpLastConfiguration.getLayoutDirection() != mConfiguration.getLayoutDirection()) {
             // If car mode or density changes, we need to reset the icons.
             updateNavButtonIcons();
         }
-        mConfiguration.updateFrom(newConfig);
     }
 
     /**
      * If the configuration changed, update the carmode and return that it was updated.
      */
-    private boolean updateCarMode(Configuration newConfig) {
+    private boolean updateCarMode() {
         boolean uiCarModeChanged = false;
-        if (newConfig != null) {
-            int uiMode = newConfig.uiMode & Configuration.UI_MODE_TYPE_MASK;
+        if (mConfiguration != null) {
+            int uiMode = mConfiguration.uiMode & Configuration.UI_MODE_TYPE_MASK;
             final boolean isCarMode = (uiMode == Configuration.UI_MODE_TYPE_CAR);
 
             if (isCarMode != mInCarMode) {
@@ -1051,6 +1043,9 @@
             mGestureHelper.destroy();
         }
         setUpSwipeUpOnboarding(false);
+        for (int i = 0; i < mButtonDispatchers.size(); ++i) {
+            mButtonDispatchers.valueAt(i).onDestroy();
+        }
     }
 
     private void setUpSwipeUpOnboarding(boolean connectedToOverviewProxy) {
@@ -1100,10 +1095,11 @@
                         visibilityToString(getCurrentView().getVisibility()),
                         getCurrentView().getAlpha()));
 
-        pw.println(String.format("      disabled=0x%08x vertical=%s menu=%s",
+        pw.println(String.format("      disabled=0x%08x vertical=%s menu=%s darkIntensity=%.2f",
                         mDisabledFlags,
                         mVertical ? "true" : "false",
-                        getMenuButton().isVisible() ? "true" : "false"));
+                        getMenuButton().isVisible() ? "true" : "false",
+                        getLightTransitionsController().getCurrentDarkIntensity()));
 
         dumpButton(pw, "back", getBackButton());
         dumpButton(pw, "home", getHomeButton());
@@ -1115,7 +1111,9 @@
         pw.println("    }");
 
         mContextualButtonGroup.dump(pw);
-        mGestureHelper.dump(pw);
+        if (mGestureHelper != null) {
+            mGestureHelper.dump(pw);
+        }
         mRecentsOnboarding.dump(pw);
     }
 
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 b19f57d0..21b98db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -49,7 +49,6 @@
     private ViewGroup mNotificationScrollLayout;
     private Context mContext;
     private boolean mFullyDark;
-    private boolean mHasShelfIconsWhenFullyDark;
 
     public NotificationIconAreaController(Context context, StatusBar statusBar) {
         mStatusBar = statusBar;
@@ -176,33 +175,10 @@
 
         updateStatusBarIcons();
         updateShelfIcons();
-        updateHasShelfIconsWhenFullyDark();
 
         applyNotificationIconsTint();
     }
 
-    private void updateHasShelfIconsWhenFullyDark() {
-        boolean hasIconsWhenFullyDark = false;
-        for (int i = 0; i < mNotificationScrollLayout.getChildCount(); i++) {
-            View view = mNotificationScrollLayout.getChildAt(i);
-            if (view instanceof ExpandableNotificationRow) {
-                NotificationData.Entry ent = ((ExpandableNotificationRow) view).getEntry();
-                if (shouldShowNotificationIcon(ent,
-                        NotificationShelf.SHOW_AMBIENT_ICONS /* showAmbient */,
-                        false /* hideDismissed */,
-                        true /* hideReplied */)) {
-                    hasIconsWhenFullyDark = true;
-                    break;
-                }
-            }
-        }
-        mHasShelfIconsWhenFullyDark = hasIconsWhenFullyDark;
-    }
-
-    public boolean hasShelfIconsWhenFullyDark() {
-        return mHasShelfIconsWhenFullyDark;
-    }
-
     private void updateShelfIcons() {
         updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons,
                 NotificationShelf.SHOW_AMBIENT_ICONS, false /* hideDismissed */,
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 3a4c218..31facb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.systemui.SysUiServiceProvider.getComponent;
 import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator
         .ExpandAnimationParameters;
 
@@ -38,6 +39,7 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.os.PowerManager;
+import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Log;
@@ -64,10 +66,12 @@
 import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.QSFragment;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.FlingAnimationUtils;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarState;
@@ -104,6 +108,11 @@
 
     private static final boolean DEBUG = false;
 
+    private static final boolean EXPAND_ON_WAKE_UP = SystemProperties.getBoolean(
+            "persist.sysui.expand_shade_on_wake_up", true);
+    private static final boolean WAKE_UP_TO_SHADE = SystemProperties.getBoolean(
+            "persist.sysui.go_to_shade_on_wake_up", true);
+
     /**
      * Fling expanding QS.
      */
@@ -124,8 +133,6 @@
     private static final int CAP_HEIGHT = 1456;
     private static final int FONT_HEIGHT = 2163;
 
-    private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
-
     static final String COUNTER_PANEL_OPEN = "panel_open";
     static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
     private static final String COUNTER_PANEL_OPEN_PEEK = "panel_open_peek";
@@ -282,6 +289,12 @@
      */
     private float mLinearDarkAmount;
 
+    /**
+     * State where the device isn't dozing anymore, but the lock screen isn't fully awake.
+     * The screen will be dimmed down with the shade collapsed.
+     */
+    private boolean mSemiAwake;
+
     private float mDarkAmountTarget;
     private boolean mPulsing;
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
@@ -327,6 +340,11 @@
             Dependency.get(NotificationEntryManager.class);
 
     private final StateListener mListener = this::setBarState;
+    private final CommandQueue mCommandQueue;
+    private final NotificationLockscreenUserManager mLockscreenUserManager =
+            Dependency.get(NotificationLockscreenUserManager.class);
+    private final ShadeController mShadeController =
+            Dependency.get(ShadeController.class);
 
     public NotificationPanelView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -337,6 +355,7 @@
         setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
         mAlphaPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
         setPanelAlpha(255, false /* animate */);
+        mCommandQueue = getComponent(context, CommandQueue.class);
     }
 
     private void setStatusBar(StatusBar bar) {
@@ -448,10 +467,12 @@
         // Update keyguard bottom area
         index = indexOfChild(mKeyguardBottomArea);
         removeView(mKeyguardBottomArea);
+        KeyguardBottomAreaView oldBottomArea = mKeyguardBottomArea;
         mKeyguardBottomArea = (KeyguardBottomAreaView) LayoutInflater.from(mContext).inflate(
                 R.layout.keyguard_bottom_area,
                 this,
                 false);
+        mKeyguardBottomArea.initFrom(oldBottomArea);
         addView(mKeyguardBottomArea, index);
         initBottomArea();
         setDarkAmount(mLinearDarkAmount, mInterpolatedDarkAmount);
@@ -575,7 +596,7 @@
                     mInterpolatedDarkAmount,
                     mStatusBar.isKeyguardCurrentlySecure(),
                     mPulsing,
-                    mBouncerTop);
+                    mEmptyDragAmount);
             mClockPositionAlgorithm.run(mClockPositionResult);
             PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.X,
                     mClockPositionResult.clockX, CLOCK_ANIMATION_PROPERTIES, animateClock);
@@ -620,7 +641,7 @@
             if (suppressedSummary) {
                 continue;
             }
-            if (!mStatusBar.getNotificationLockscreenUserManager().shouldShowOnKeyguard(
+            if (!mLockscreenUserManager.shouldShowOnKeyguard(
                     row.getStatusBarNotification())) {
                 continue;
             }
@@ -733,7 +754,11 @@
             mQsExpandImmediate = true;
             mNotificationStackScroller.setShouldShowShelfOnly(true);
         }
-        expand(true /* animate */);
+        if (isFullyCollapsed()){
+            expand(true /* animate */);
+        } else {
+            flingSettings(0 /* velocity */, FLING_EXPAND);
+        }
     }
 
     public void expandWithoutQs() {
@@ -1233,6 +1258,12 @@
         if (keyguardShowing) {
             updateDozingVisibilities(false /* animate */);
         }
+
+        // Expand notification shade if the device was is semi-awake state
+        if (mBarState == StatusBarState.SHADE && isSemiAwake()) {
+            mNotificationStackScroller.setDark(false /* dark */, false /* animated */,
+                    null /* touchLocation */);
+        }
         resetVerticalPanelPosition();
         updateQsState();
     }
@@ -1780,13 +1811,9 @@
             KeyguardAffordanceView lockIcon = mKeyguardBottomArea.getLockIcon();
             if (active && !mUnlockIconActive && mTracking) {
                 lockIcon.setImageAlpha(1.0f, true, 150, Interpolators.FAST_OUT_LINEAR_IN, null);
-                lockIcon.setImageScale(LOCK_ICON_ACTIVE_SCALE, true, 150,
-                        Interpolators.FAST_OUT_LINEAR_IN);
             } else if (!active && mUnlockIconActive && mTracking) {
                 lockIcon.setImageAlpha(lockIcon.getRestingAlpha(), true /* animate */,
                         150, Interpolators.FAST_OUT_LINEAR_IN, null);
-                lockIcon.setImageScale(1.0f, true, 150,
-                        Interpolators.FAST_OUT_LINEAR_IN);
             }
             mUnlockIconActive = active;
         }
@@ -2337,13 +2364,7 @@
     }
 
     public void setEmptyDragAmount(float amount) {
-        float factor = 0.8f;
-        if (mNotificationStackScroller.getNotGoneChildCount() > 0) {
-            factor = 0.4f;
-        } else if (!mStatusBar.hasActiveNotifications()) {
-            factor = 0.4f;
-        }
-        mEmptyDragAmount = amount * factor;
+        mEmptyDragAmount = amount * 0.2f;
         positionClockAndNotifications();
     }
 
@@ -2404,7 +2425,7 @@
                 return true;
             case StatusBarState.SHADE_LOCKED:
                 if (!mQsExpanded) {
-                    mStatusBar.goToKeyguard();
+                    mShadeController.goToKeyguard();
                 }
                 return true;
             case StatusBarState.SHADE:
@@ -2523,8 +2544,8 @@
     @Override
     public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
         super.setHeadsUpManager(headsUpManager);
-        mHeadsUpTouchHelper = new HeadsUpTouchHelper(headsUpManager, mNotificationStackScroller,
-                this);
+        mHeadsUpTouchHelper = new HeadsUpTouchHelper(headsUpManager,
+                mNotificationStackScroller.getHeadsUpCallback(), this);
     }
 
     public void setTrackedHeadsUp(ExpandableNotificationRow pickedChild) {
@@ -2607,7 +2628,7 @@
         }
         if (showIconsWhenExpanded != mShowIconsWhenExpanded) {
             mShowIconsWhenExpanded = showIconsWhenExpanded;
-            mStatusBar.recomputeDisableFlags(false);
+            mCommandQueue.recomputeDisableFlags(false);
         }
     }
 
@@ -2771,11 +2792,14 @@
         mNotificationStackScroller.setAnimationsEnabled(!disabled);
     }
 
-    public void setDozing(boolean dozing, boolean animate,
-            PointF wakeUpTouchLocation) {
-        mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
+    public void setDozing(boolean dozing, boolean animate, PointF wakeUpTouchLocation,
+            boolean passiveInterrupted) {
         if (dozing == mDozing) return;
         mDozing = dozing;
+        mSemiAwake = !EXPAND_ON_WAKE_UP && !mDozing && passiveInterrupted;
+        if (!mSemiAwake) {
+            mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
+        }
 
         if (mBarState == StatusBarState.KEYGUARD
                 || mBarState == StatusBarState.SHADE_LOCKED) {
@@ -2789,24 +2813,38 @@
             } else {
                 mDarkAnimator.cancel();
             }
+            if (mSemiAwake) {
+                setDarkAmount(0, 0);
+            }
         }
         mDarkAmountTarget = darkAmount;
-        if (animate) {
-            if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) {
-                mDarkInterpolator = dozing
-                        ? Interpolators.FAST_OUT_SLOW_IN
-                        : Interpolators.TOUCH_RESPONSE_REVERSE;
+        if (!mSemiAwake) {
+            if (animate) {
+                startDarkAnimation();
+            } else {
+                setDarkAmount(darkAmount, darkAmount);
             }
-            mNotificationStackScroller.notifyDarkAnimationStart(dozing);
-            mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, darkAmount);
-            mDarkAnimator.setInterpolator(Interpolators.LINEAR);
-            mDarkAnimator.setDuration(mNotificationStackScroller.getDarkAnimationDuration(dozing));
-            mDarkAnimator.start();
-        } else {
-            setDarkAmount(darkAmount, darkAmount);
         }
     }
 
+    public boolean isSemiAwake() {
+        return mSemiAwake;
+    }
+
+    private void startDarkAnimation() {
+        if (mInterpolatedDarkAmount == 0f || mInterpolatedDarkAmount == 1f) {
+            mDarkInterpolator = mDozing
+                    ? Interpolators.FAST_OUT_SLOW_IN
+                    : Interpolators.TOUCH_RESPONSE_REVERSE;
+        }
+        mNotificationStackScroller.notifyDarkAnimationStart(mDozing);
+        mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozing ? 1 : 0);
+        mDarkAnimator.setInterpolator(Interpolators.LINEAR);
+        mDarkAnimator.setDuration(
+                mNotificationStackScroller.getDarkAnimationDuration(mDozing));
+        mDarkAnimator.start();
+    }
+
     private void setDarkAmount(float linearAmount, float amount) {
         mInterpolatedDarkAmount = amount;
         mLinearDarkAmount = linearAmount;
@@ -2877,7 +2915,7 @@
             if (hideIcons != mHideIconsDuringNotificationLaunch) {
                 mHideIconsDuringNotificationLaunch = hideIcons;
                 if (!hideIcons) {
-                    mStatusBar.recomputeDisableFlags(true /* animate */);
+                    mCommandQueue.recomputeDisableFlags(true /* animate */);
                 }
             }
         }
@@ -2945,6 +2983,7 @@
         mNotificationStackScroller.updateSpeedBumpIndex();
         mNotificationStackScroller.updateFooter();
         updateShowEmptyShadeView();
+        mNotificationStackScroller.updateIconAreaViews();
     }
 
     public void onUpdateRowStates() {
@@ -2991,4 +3030,26 @@
         mNotificationStackScroller.setScrimController(scrimController);
         updateShowEmptyShadeView();
     }
+
+    public void showTransientIndication(int id) {
+        mKeyguardBottomArea.showTransientIndication(id);
+    }
+
+    /**
+     * Whenever a user drags down on the empty area (pulling down the shade and clock) and lets go.
+     *
+     * @return {@code true} if dragging down should take the user to SHADE_LOCKED.
+     */
+    public boolean onDraggedDown() {
+        if (isSemiAwake()) {
+            mSemiAwake = false;
+            mNotificationStackScroller.setDark(false /* dark */, true /* animate */,
+                    null /* touchLocation */);
+            startDarkAnimation();
+            mStatusBar.updateScrimController();
+
+            return WAKE_UP_TO_SHADE;
+        }
+        return true;
+    }
 }
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 59863ec..2129835 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -19,6 +19,7 @@
 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 
 import static com.android.systemui.ScreenDecorations.DisplayCutoutView.boundsFromDirection;
+import static com.android.systemui.SysUiServiceProvider.getComponent;
 
 import android.annotation.Nullable;
 import android.content.Context;
@@ -42,6 +43,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.policy.DarkIconDispatcher;
 import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
 
@@ -52,6 +54,7 @@
     private static final boolean DEBUG = StatusBar.DEBUG;
     private static final boolean DEBUG_GESTURES = false;
     private static final int NO_VALUE = Integer.MIN_VALUE;
+    private final CommandQueue mCommandQueue;
 
     StatusBar mBar;
 
@@ -82,6 +85,7 @@
         super(context, attrs);
 
         mBarTransitions = new PhoneStatusBarTransitions(this);
+        mCommandQueue = getComponent(context, CommandQueue.class);
     }
 
     public BarTransitions getBarTransitions() {
@@ -166,7 +170,7 @@
 
     @Override
     public boolean panelEnabled() {
-        return mBar.panelsEnabled();
+        return mCommandQueue.panelsEnabled();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index bce52a2..fd5403f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -42,7 +42,7 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.SystemClock;
-import android.os.SystemProperties;
+import android.provider.Settings;
 import android.util.FloatProperty;
 import android.util.Log;
 import android.util.Slog;
@@ -77,10 +77,11 @@
     private static final float GRADIENT_WIDTH = .75f;
 
     /** Experiment to swipe home button left to execute a back key press */
-    private static final String PULL_HOME_GO_BACK_PROP = "persist.quickstepcontroller.homegoesback";
-    private static final String HIDE_BACK_BUTTON_PROP = "persist.quickstepcontroller.hideback";
+    private static final String PULL_HOME_GO_BACK_PROP = "quickstepcontroller_homegoesback";
+    private static final String HIDE_BACK_BUTTON_PROP = "quickstepcontroller_hideback";
     private static final String BACK_AFTER_END_PROP
-            = "persist.quickstepcontroller.homegoesbackwhenend";
+            = "quickstepcontroller_homegoesbackwhenend";
+    private static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled";
     private static final long BACK_BUTTON_FADE_OUT_ALPHA = 60;
     private static final long BACK_BUTTON_FADE_IN_ALPHA = 150;
     private static final long BACK_GESTURE_POLL_TIMEOUT = 1000;
@@ -124,14 +125,6 @@
     private final Matrix mTransformLocalMatrix = new Matrix();
     private final Paint mTrackPaint = new Paint();
 
-    public static boolean swipeHomeGoBackGestureEnabled() {
-        return SystemProperties.getBoolean(PULL_HOME_GO_BACK_PROP, false);
-    }
-    public static boolean shouldhideBackButton() {
-        return swipeHomeGoBackGestureEnabled()
-            && SystemProperties.getBoolean(HIDE_BACK_BUTTON_PROP, false);
-    }
-
     private final FloatProperty<QuickStepController> mTrackAlphaProperty =
             new FloatProperty<QuickStepController>("TrackAlpha") {
         @Override
@@ -211,7 +204,7 @@
     public void setComponents(NavigationBarView navigationBarView) {
         mNavigationBarView = navigationBarView;
 
-        mNavigationBarView.getBackButton().setVisibility(shouldhideBackButton()
+        mNavigationBarView.getBackButton().setVisibility(shouldhideBackButton(mContext)
                 ? View.GONE
                 : View.VISIBLE);
     }
@@ -344,7 +337,7 @@
                     // Passing the drag slop then touch slop will start quick step
                     if (allowDrag) {
                         startQuickScrub();
-                    } else if (swipeHomeGoBackGestureEnabled()
+                    } else if (swipeHomeGoBackGestureEnabled(mContext)
                             && mNavigationBarView.getDownHitTarget() == HIT_TARGET_HOME
                             && mDragPositive ? pos < touchDown : pos > touchDown) {
                         startBackGesture();
@@ -607,10 +600,9 @@
         if (!mBackGestureActive) {
             mBackGestureActive = true;
             mNavigationBarView.getHomeButton().abortCurrentGesture();
-            final boolean runBackMidGesture
-                    = !SystemProperties.getBoolean(BACK_AFTER_END_PROP, false);
+            final boolean runBackMidGesture = !shouldExecuteBackOnUp(mContext);
             if (mCanPerformBack) {
-                if (!shouldhideBackButton()) {
+                if (!shouldhideBackButton(mContext)) {
                     mNavigationBarView.getBackButton().setAlpha(0 /* alpha */, true /* animate */,
                             BACK_BUTTON_FADE_OUT_ALPHA);
                 }
@@ -638,11 +630,11 @@
                 mHomeAnimator.translationX(0);
             }
             mHomeAnimator.start();
-            if (!shouldhideBackButton()) {
+            if (!shouldhideBackButton(mContext)) {
                 mNavigationBarView.getBackButton().setAlpha(
                         mOverviewEventSender.getBackButtonAlpha(), true /* animate */);
             }
-            if (SystemProperties.getBoolean(BACK_AFTER_END_PROP, false)) {
+            if (shouldExecuteBackOnUp(mContext)) {
                 performBack();
             }
         }
@@ -709,7 +701,8 @@
     }
 
     private boolean canPerformHomeBackGesture() {
-        return swipeHomeGoBackGestureEnabled() && mOverviewEventSender.getBackButtonAlpha() > 0;
+        return swipeHomeGoBackGestureEnabled(mContext)
+                && mOverviewEventSender.getBackButtonAlpha() > 0;
     }
 
     private void performBack() {
@@ -746,4 +739,23 @@
         }
         return false;
     }
+
+    private static boolean getBoolGlobalSetting(Context context, String key) {
+        return Settings.Global.getInt(context.getContentResolver(), key, 0) != 0;
+    }
+
+    public static boolean swipeHomeGoBackGestureEnabled(Context context) {
+        return !getBoolGlobalSetting(context, NAVBAR_EXPERIMENTS_DISABLED)
+            && getBoolGlobalSetting(context, PULL_HOME_GO_BACK_PROP);
+    }
+
+    public static boolean shouldhideBackButton(Context context) {
+        return swipeHomeGoBackGestureEnabled(context)
+            && getBoolGlobalSetting(context, HIDE_BACK_BUTTON_PROP);
+    }
+
+    public static boolean shouldExecuteBackOnUp(Context context) {
+        return !getBoolGlobalSetting(context, NAVBAR_EXPERIMENTS_DISABLED)
+            && getBoolGlobalSetting(context, BACK_AFTER_END_PROP);
+    }
 }
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 15e189c..855592f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/RotationContextButton.java
@@ -16,29 +16,269 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static com.android.internal.view.RotationPolicy.NATURAL_ROTATION;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import android.annotation.DrawableRes;
 import android.annotation.IdRes;
 import android.annotation.NonNull;
 import android.annotation.StyleRes;
+import android.app.StatusBarManager;
+import android.content.ContentResolver;
 import android.content.Context;
-import android.content.ContextWrapper;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.provider.Settings;
 import android.view.ContextThemeWrapper;
+import android.view.IRotationWatcher.Stub;
+import android.view.MotionEvent;
+import android.view.Surface;
 import android.view.View;
+import android.view.WindowManagerGlobal;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.Interpolators;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.systemui.R;
+import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.statusbar.policy.KeyButtonDrawable;
-import com.android.systemui.util.Utils;
+import com.android.systemui.statusbar.policy.RotationLockController;
+
+import java.util.Optional;
+import java.util.function.Consumer;
 
 public class RotationContextButton extends ContextualButton {
+    public static final boolean DEBUG_ROTATION = false;
+
+    private static final int BUTTON_FADE_IN_OUT_DURATION_MS = 100;
+    private static final int NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS = 20000;
+
+    private static final int NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION = 3;
 
     private @StyleRes int mStyleRes;
 
-    public RotationContextButton(@IdRes int buttonResId, @DrawableRes int iconResId,
-            @StyleRes int style) {
-        super(buttonResId, iconResId);
-        mStyleRes = style;
+    private int mLastRotationSuggestion;
+    private boolean mPendingRotationSuggestion;
+    private boolean mHoveringRotationSuggestion;
+    private RotationLockController mRotationLockController;
+    private TaskStackListenerImpl mTaskStackListener;
+    private Consumer<Integer> mRotWatcherListener;
+    private boolean mIsNavigationBarShowing;
+
+    private final Runnable mRemoveRotationProposal =
+            () -> setRotateSuggestionButtonState(false /* visible */);
+    private final Runnable mCancelPendingRotationProposal =
+            () -> mPendingRotationSuggestion = false;
+    private Animator mRotateHideAnimator;
+    private boolean mAccessibilityFeedbackEnabled;
+
+    private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
+    private final ViewRippler mViewRippler = new ViewRippler();
+
+    private final Stub mRotationWatcher = new Stub() {
+        @Override
+        public void onRotationChanged(final int rotation) throws RemoteException {
+            // We need this to be scheduled as early as possible to beat the redrawing of
+            // window in response to the orientation change.
+            Handler h = getCurrentView().getHandler();
+            Message msg = Message.obtain(h, () -> {
+                // If the screen rotation changes while locked, potentially update lock to flow with
+                // new screen rotation and hide any showing suggestions.
+                if (mRotationLockController.isRotationLocked()) {
+                    if (shouldOverrideUserLockPrefs(rotation)) {
+                        setRotationLockedAtAngle(rotation);
+                    }
+                    setRotateSuggestionButtonState(false /* visible */, true /* forced */);
+                }
+
+                if (mRotWatcherListener != null) {
+                    mRotWatcherListener.accept(rotation);
+                }
+            });
+            msg.setAsynchronous(true);
+            h.sendMessageAtFrontOfQueue(msg);
+        }
+    };
+
+    /**
+     * Determines if rotation suggestions disabled2 flag exists in flag
+     * @param disable2Flags see if rotation suggestion flag exists in this flag
+     * @return whether flag exists
+     */
+    static boolean hasDisable2RotateSuggestionFlag(int disable2Flags) {
+        return (disable2Flags & StatusBarManager.DISABLE2_ROTATE_SUGGESTIONS) != 0;
     }
 
-    public void setStyle(@StyleRes int styleRes) {
-        mStyleRes = styleRes;
+    public RotationContextButton(@IdRes int buttonResId, @DrawableRes int iconResId,
+            @NonNull Context context, @StyleRes int style) {
+        super(buttonResId, iconResId);
+
+        mStyleRes = style;
+        mIsNavigationBarShowing = true;
+        mRotationLockController = Dependency.get(RotationLockController.class);
+
+        // Register the task stack listener
+        mTaskStackListener = new TaskStackListenerImpl();
+        ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
+        setOnClickListener(this::onRotateSuggestionClick);
+        setOnHoverListener(this::onRotateSuggestionHover);
+
+        try {
+            WindowManagerGlobal.getWindowManagerService()
+                    .watchRotation(mRotationWatcher, context.getDisplay().getDisplayId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    public void addRotationCallback(Consumer<Integer> watcher) {
+        mRotWatcherListener = watcher;
+    }
+
+    public void setRotateSuggestionButtonState(boolean visible) {
+        setRotateSuggestionButtonState(visible, false /* force */);
+    }
+
+    public void setRotateSuggestionButtonState(final boolean visible, final boolean force) {
+        // At any point the the button can become invisible because an a11y service became active.
+        // Similarly, a call to make the button visible may be rejected because an a11y service is
+        // active. Must account for this.
+        // Rerun a show animation to indicate change but don't rerun a hide animation
+        if (!visible && !isVisible()) return;
+
+        final View view = getCurrentView();
+        if (view == null) return;
+
+        final KeyButtonDrawable currentDrawable = getImageDrawable();
+        if (currentDrawable == null) return;
+
+        // Clear any pending suggestion flag as it has either been nullified or is being shown
+        mPendingRotationSuggestion = false;
+        view.removeCallbacks(mCancelPendingRotationProposal);
+
+        // Handle the visibility change and animation
+        if (visible) { // Appear and change (cannot force)
+            // Stop and clear any currently running hide animations
+            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
+                mRotateHideAnimator.cancel();
+            }
+            mRotateHideAnimator = null;
+
+            // Reset the alpha if any has changed due to hide animation
+            view.setAlpha(1f);
+
+            // Run the rotate icon's animation if it has one
+            if (currentDrawable.canAnimate()) {
+                currentDrawable.resetAnimation();
+                currentDrawable.startAnimation();
+            }
+
+            if (!isRotateSuggestionIntroduced()) mViewRippler.start(view);
+
+            // Set visibility unless a11y service is active.
+            show();
+        } else { // Hide
+            mViewRippler.stop(); // Prevent any pending ripples, force hide or not
+
+            if (force) {
+                // If a hide animator is running stop it and make invisible
+                if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) {
+                    mRotateHideAnimator.pause();
+                }
+                hide();
+                return;
+            }
+
+            // Don't start any new hide animations if one is running
+            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) return;
+
+            ObjectAnimator fadeOut = ObjectAnimator.ofFloat(view, "alpha", 0f);
+            fadeOut.setDuration(BUTTON_FADE_IN_OUT_DURATION_MS);
+            fadeOut.setInterpolator(Interpolators.LINEAR);
+            fadeOut.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    hide();
+                }
+            });
+
+            mRotateHideAnimator = fadeOut;
+            fadeOut.start();
+        }
+    }
+
+    public void setAccessibilityFeedbackEnabled(boolean flag) {
+        mAccessibilityFeedbackEnabled = flag;
+    }
+
+    public void setRotationLockedAtAngle(int rotationSuggestion) {
+        mRotationLockController.setRotationLockedAtAngle(true /* locked */, rotationSuggestion);
+    }
+
+    public boolean isRotationLocked() {
+        return mRotationLockController.isRotationLocked();
+    }
+
+    public void onRotationProposal(int rotation, int windowRotation, boolean isValid) {
+        // This method will be called on rotation suggestion changes even if the proposed rotation
+        // is not valid for the top app. Use invalid rotation choices as a signal to remove the
+        // rotate button if shown.
+        if (!isValid) {
+            setRotateSuggestionButtonState(false /* visible */);
+            return;
+        }
+
+        // If window rotation matches suggested rotation, remove any current suggestions
+        if (rotation == windowRotation) {
+            getCurrentView().removeCallbacks(mRemoveRotationProposal);
+            setRotateSuggestionButtonState(false /* visible */);
+            return;
+        }
+
+        // Prepare to show the navbar icon by updating the icon style to change anim params
+        mLastRotationSuggestion = rotation; // Remember rotation for click
+        final boolean rotationCCW = isRotationAnimationCCW(windowRotation, rotation);
+        int style;
+        if (windowRotation == Surface.ROTATION_0 || windowRotation == Surface.ROTATION_180) {
+            style = rotationCCW ? R.style.RotateButtonCCWStart90 : R.style.RotateButtonCWStart90;
+        } else { // 90 or 270
+            style = rotationCCW ? R.style.RotateButtonCCWStart0 : R.style.RotateButtonCWStart0;
+        }
+        mStyleRes = style;
+        updateIcon();
+
+        if (mIsNavigationBarShowing) {
+            // The navbar is visible so show the icon right away
+            showAndLogRotationSuggestion();
+        } else {
+            // If the navbar isn't shown, flag the rotate icon to be shown should the navbar become
+            // visible given some time limit.
+            mPendingRotationSuggestion = true;
+            getCurrentView().removeCallbacks(mCancelPendingRotationProposal);
+            getCurrentView().postDelayed(mCancelPendingRotationProposal,
+                    NAVBAR_HIDDEN_PENDING_ICON_TIMEOUT_MS);
+        }
+    }
+
+    public void onDisable2FlagChanged(int state2) {
+        final boolean rotateSuggestionsDisabled = hasDisable2RotateSuggestionFlag(state2);
+        if (rotateSuggestionsDisabled) onRotationSuggestionsDisabled();
+    }
+
+    public void onNavigationBarWindowVisibilityChange(boolean showing) {
+        if (mIsNavigationBarShowing != showing) {
+            mIsNavigationBarShowing = showing;
+
+            // If the navbar is visible, show the rotate button if there's a pending suggestion
+            if (showing && mPendingRotationSuggestion) {
+                showAndLogRotationSuggestion();
+            }
+        }
     }
 
     @Override
@@ -58,4 +298,168 @@
         Context context = new ContextThemeWrapper(getContext().getApplicationContext(), mStyleRes);
         return KeyButtonDrawable.create(context, mIconResId, false /* shadow */);
     }
+
+    @Override
+    public void onDestroy() {
+        // Unregister the task stack listener
+        ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
+
+        try {
+            WindowManagerGlobal.getWindowManagerService().removeRotationWatcher(mRotationWatcher);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private void onRotateSuggestionClick(View v) {
+        mMetricsLogger.action(MetricsEvent.ACTION_ROTATION_SUGGESTION_ACCEPTED);
+        incrementNumAcceptedRotationSuggestionsIfNeeded();
+        setRotationLockedAtAngle(mLastRotationSuggestion);
+    }
+
+    private boolean onRotateSuggestionHover(View v, MotionEvent event) {
+        final int action = event.getActionMasked();
+        mHoveringRotationSuggestion = (action == MotionEvent.ACTION_HOVER_ENTER)
+                || (action == MotionEvent.ACTION_HOVER_MOVE);
+        rescheduleRotationTimeout(true /* reasonHover */);
+        return false; // Must return false so a11y hover events are dispatched correctly.
+    }
+
+    private void onRotationSuggestionsDisabled() {
+        // Immediately hide the rotate button and clear any planned removal
+        setRotateSuggestionButtonState(false /* visible */, true /* force */);
+        getCurrentView().removeCallbacks(mRemoveRotationProposal);
+    }
+
+    private void showAndLogRotationSuggestion() {
+        setRotateSuggestionButtonState(true /* visible */);
+        rescheduleRotationTimeout(false /* reasonHover */);
+        mMetricsLogger.visible(MetricsEvent.ROTATION_SUGGESTION_SHOWN);
+    }
+
+    private boolean shouldOverrideUserLockPrefs(final int rotation) {
+        // Only override user prefs when returning to the natural rotation (normally portrait).
+        // Don't let apps that force landscape or 180 alter user lock.
+        return rotation == NATURAL_ROTATION;
+    }
+
+    private boolean isRotationAnimationCCW(int from, int to) {
+        // All 180deg WM rotation animations are CCW, match that
+        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_90) return false;
+        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_180) return true; //180d so CCW
+        if (from == Surface.ROTATION_0 && to == Surface.ROTATION_270) return true;
+        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_0) return true;
+        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_180) return false;
+        if (from == Surface.ROTATION_90 && to == Surface.ROTATION_270) return true; //180d so CCW
+        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_0) return true; //180d so CCW
+        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_90) return true;
+        if (from == Surface.ROTATION_180 && to == Surface.ROTATION_270) return false;
+        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_0) return false;
+        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_90) return true; //180d so CCW
+        if (from == Surface.ROTATION_270 && to == Surface.ROTATION_180) return true;
+        return false; // Default
+    }
+
+    private void rescheduleRotationTimeout(final boolean reasonHover) {
+        // 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
+            if (mRotateHideAnimator != null && mRotateHideAnimator.isRunning()) return;
+            // Don't reschedule if not visible
+            if (!isVisible()) return;
+        }
+
+        // Stop any pending removal
+        getCurrentView().removeCallbacks(mRemoveRotationProposal);
+        // Schedule timeout
+        getCurrentView().postDelayed(mRemoveRotationProposal, computeRotationProposalTimeout());
+    }
+
+    private int computeRotationProposalTimeout() {
+        if (mAccessibilityFeedbackEnabled) return 20000;
+        if (mHoveringRotationSuggestion) return 16000;
+        return 10000;
+    }
+
+    private boolean isRotateSuggestionIntroduced() {
+        ContentResolver cr = getContext().getContentResolver();
+        return Settings.Secure.getInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0)
+                >= NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION;
+    }
+
+    private void incrementNumAcceptedRotationSuggestionsIfNeeded() {
+        // Get the number of accepted suggestions
+        ContentResolver cr = getContext().getContentResolver();
+        final int numSuggestions = Settings.Secure.getInt(cr,
+                Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED, 0);
+
+        // Increment the number of accepted suggestions only if it would change intro mode
+        if (numSuggestions < NUM_ACCEPTED_ROTATION_SUGGESTIONS_FOR_INTRODUCTION) {
+            Settings.Secure.putInt(cr, Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED,
+                    numSuggestions + 1);
+        }
+    }
+
+    private class TaskStackListenerImpl extends SysUiTaskStackChangeListener {
+        // Invalidate any rotation suggestion on task change or activity orientation change
+        // Note: all callbacks happen on main thread
+
+        @Override
+        public void onTaskStackChanged() {
+            setRotateSuggestionButtonState(false /* visible */);
+        }
+
+        @Override
+        public void onTaskRemoved(int taskId) {
+            setRotateSuggestionButtonState(false /* visible */);
+        }
+
+        @Override
+        public void onTaskMovedToFront(int taskId) {
+            setRotateSuggestionButtonState(false /* visible */);
+        }
+
+        @Override
+        public void onActivityRequestedOrientationChanged(int taskId, int requestedOrientation) {
+            // Only hide the icon if the top task changes its requestedOrientation
+            // Launcher can alter its requestedOrientation while it's not on top, don't hide on this
+            Optional.ofNullable(ActivityManagerWrapper.getInstance())
+                    .map(ActivityManagerWrapper::getRunningTask)
+                    .ifPresent(a -> {
+                        if (a.id == taskId) setRotateSuggestionButtonState(false /* visible */);
+                    });
+        }
+    }
+
+    private class ViewRippler {
+        private static final int RIPPLE_OFFSET_MS = 50;
+        private static final int RIPPLE_INTERVAL_MS = 2000;
+        private View mRoot;
+
+        public void start(View root) {
+            stop(); // Stop any pending ripple animations
+
+            mRoot = root;
+
+            // Schedule pending ripples, offset the 1st to avoid problems with visibility change
+            mRoot.postOnAnimationDelayed(mRipple, RIPPLE_OFFSET_MS);
+            mRoot.postOnAnimationDelayed(mRipple, RIPPLE_INTERVAL_MS);
+            mRoot.postOnAnimationDelayed(mRipple, 2 * RIPPLE_INTERVAL_MS);
+            mRoot.postOnAnimationDelayed(mRipple, 3 * RIPPLE_INTERVAL_MS);
+            mRoot.postOnAnimationDelayed(mRipple, 4 * RIPPLE_INTERVAL_MS);
+        }
+
+        public void stop() {
+            if (mRoot != null) mRoot.removeCallbacks(mRipple);
+        }
+
+        private final Runnable mRipple = new Runnable() {
+            @Override
+            public void run() { // Cause the ripple to fire via false presses
+                if (!mRoot.isAttachedToWindow()) return;
+                mRoot.setPressed(true /* pressed */);
+                mRoot.setPressed(false /* pressed */);
+            }
+        };
+    }
 }
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 e3a7b75..1bed26d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -63,7 +63,7 @@
 public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnColorsChangedListener,
         Dumpable {
 
-    private static final String TAG = "ScrimController";
+    static final String TAG = "ScrimController";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     /**
@@ -96,6 +96,11 @@
      */
     public static final float GRADIENT_SCRIM_ALPHA_BUSY = 0.70f;
     /**
+     * A scrim varies its opacity based on a busyness factor, for example
+     * how many notifications are currently visible.
+     */
+    public static final float GRADIENT_SCRIM_DARK_KEYGUARD = 0.80f;
+    /**
      * The most common scrim, the one under the keyguard.
      */
     protected static final float SCRIM_BEHIND_ALPHA_KEYGUARD = GRADIENT_SCRIM_ALPHA;
@@ -361,7 +366,7 @@
             mExpansionFraction = fraction;
 
             final boolean keyguardOrUnlocked = mState == ScrimState.UNLOCKED
-                    || mState == ScrimState.KEYGUARD;
+                    || mState == ScrimState.KEYGUARD || mState == ScrimState.DARK_KEYGUARD;
             if (!keyguardOrUnlocked || !mExpansionAffectsAlpha) {
                 return;
             }
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 085f7b6..ade063d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -49,6 +49,8 @@
                     // fade it out afterwards.
                     mBlankScreen = true;
                 }
+            } else if (previousState == ScrimState.KEYGUARD) {
+                mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
             } else {
                 mAnimationDuration = ScrimController.ANIMATION_DURATION;
             }
@@ -59,8 +61,24 @@
         @Override
         public float getBehindAlpha(float busynessFactor) {
             return MathUtils.map(0 /* start */, 1 /* stop */,
-                   mScrimBehindAlphaKeyguard, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
-                   busynessFactor);
+                    mScrimBehindAlphaKeyguard, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
+                    busynessFactor);
+        }
+    },
+
+    /**
+     * On semi-awake lock screen.
+     */
+    DARK_KEYGUARD(7) {
+
+        @Override
+        public void prepare(ScrimState previousState) {
+            mBlankScreen = mDisplayRequiresBlanking && previousState != ScrimState.AOD;
+            mAnimationDuration = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
+            mCurrentBehindAlpha = ScrimController.GRADIENT_SCRIM_DARK_KEYGUARD;
+            mCurrentInFrontAlpha = 0;
+            mCurrentInFrontTint = Color.BLACK;
+            mCurrentBehindTint = Color.BLACK;
         }
     },
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
new file mode 100644
index 0000000..e546119
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadeController.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import android.view.View;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
+
+/**
+ * {@link ShadeController} is an abstraction of the work that used to be hard-coded in
+ * {@link StatusBar}. The shade itself represents the concept of the status bar window state, and
+ * can be in multiple states: dozing, locked, showing the bouncer, occluded, etc. All/some of these
+ * are coordinated with {@link StatusBarKeyguardViewManager} via
+ * {@link com.android.systemui.keyguard.KeyguardViewMediator} and others.
+ */
+public interface ShadeController {
+
+    /**
+     * Shows the keyguard bouncer - the password challenge on the lock screen
+     *
+     * @param scrimmed true when the bouncer should show scrimmed, false when the user will be
+     * dragging it and translation should be deferred {@see KeyguardBouncer#show(boolean, boolean)}
+     */
+    void showBouncer(boolean scrimmed);
+
+    /**
+     * Make our window larger and the panel expanded
+     */
+    void instantExpandNotificationsPanel();
+
+    /**
+     * If the notifications panel is not fully expanded, collapse it animated.
+     *
+     * @return Seems to always return false
+     */
+    boolean closeShadeIfOpen();
+
+    /**
+     * Add a runnable for NotificationPanelView to post when the panel is expanded.
+     *
+     * @param action the action to post
+     */
+    void postOnShadeExpanded(Runnable action);
+
+    /**
+     * Add a runnable to be executed after the shade collapses. Post-collapse runnables are
+     * aggregated and run serially.
+     *
+     * @param action the action to execute
+     */
+    void addPostCollapseAction(Runnable action);
+
+    /**
+     * Ask shade controller to set the state to {@link StatusBarState#KEYGUARD}, but only from
+     * {@link StatusBarState#SHADE_LOCKED}
+     */
+    void goToKeyguard();
+
+    /**
+     * When the keyguard is showing and covered by something (bouncer, keyguard activity, etc.) it
+     * is occluded. This is controlled by {@link com.android.server.policy.PhoneWindowManager}
+     *
+     * @return whether the keyguard is currently occluded
+     */
+    boolean isOccluded();
+
+    /**
+     * Notify the shade controller that the current user changed
+     *
+     * @param newUserId userId of the new user
+     */
+    void setLockscreenUser(int newUserId);
+
+    /**
+     * Dozing is when the screen is in AOD or asleep
+     *
+     * @return true if we are dozing
+     */
+    boolean isDozing();
+
+    /**
+     * Ask the display to wake up if currently dozing, else do nothing
+     *
+     * @param time when to wake up
+     * @param view the view requesting the wakeup
+     */
+    void wakeUpIfDozing(long time, View view);
+
+    /**
+     * If secure with redaction: Show bouncer, go to unlocked shade.
+     *
+     * <p>If secure without redaction or no security: Go to {@link StatusBarState#SHADE_LOCKED}.</p>
+     *
+     * @param startingChild The view to expand after going to the shade.
+     */
+    void goToLockedShade(View startingChild);
+
+    /**
+     * Adds a {@param runnable} to be executed after Keyguard is gone.
+     */
+    void addAfterKeyguardGoneRunnable(Runnable runnable);
+
+    /**
+     * Close the shade if it was open
+     *
+     * @return true if the shade was open, else false
+     */
+    boolean collapsePanel();
+
+    /**
+     * If {@param animate}, does the same as {@link #collapsePanel()}. Otherwise, instantly collapse
+     * the panel. Post collapse runnables will be executed
+     *
+     * @param animate
+     */
+    void collapsePanel(boolean animate);
+
+    /**
+     * Callback to tell the shade controller that an activity launch animation was canceled
+     */
+    void onLaunchAnimationCancelled();
+
+    /**
+     * When notifications update, give the shade controller a chance to do thing in response to
+     * the new data set
+     */
+    void updateAreThereNotifications();
+
+    /**
+     * Callback to notify the shade controller that a {@link ActivatableNotificationView} has become
+     * inactive
+     */
+    void onActivationReset();
+
+}
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 c3b87af..b9ca949 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -26,10 +26,8 @@
 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.WindowManagerWrapper.NAV_BAR_POS_LEFT;
 import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_INVALID;
-import static com.android.systemui.statusbar.NotificationLockscreenUserManager
-        .NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION;
+import static com.android.systemui.shared.system.WindowManagerWrapper.NAV_BAR_POS_LEFT;
 import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF;
 import static com.android.systemui.statusbar.NotificationMediaManager.DEBUG_MEDIA;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
@@ -54,7 +52,6 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.StatusBarManager;
-import android.app.TaskStackBuilder;
 import android.app.UiModeManager;
 import android.app.WallpaperInfo;
 import android.app.WallpaperManager;
@@ -65,31 +62,21 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.IntentSender;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.PointF;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
-import android.graphics.drawable.BitmapDrawable;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
 import android.media.AudioAttributes;
-import android.media.MediaMetadata;
 import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RemoteException;
@@ -105,14 +92,10 @@
 import android.service.dreams.DreamService;
 import android.service.dreams.IDreamManager;
 import android.service.notification.StatusBarNotification;
-import android.service.vr.IVrManager;
-import android.service.vr.IVrStateCallbacks;
-import android.text.TextUtils;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.view.Display;
 import android.view.IWindowManager;
 import android.view.KeyEvent;
@@ -122,7 +105,6 @@
 import android.view.ThreadedRenderer;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.view.ViewTreeObserver;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
@@ -130,19 +112,15 @@
 import android.view.animation.AccelerateInterpolator;
 import android.widget.DateTimeView;
 import android.widget.ImageView;
-import android.widget.TextView;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.colorextraction.ColorExtractor;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.internal.statusbar.NotificationVisibility;
 import com.android.internal.statusbar.StatusBarIcon;
-import com.android.internal.widget.LockPatternUtils;
 import com.android.internal.widget.MessagingGroup;
 import com.android.internal.widget.MessagingMessage;
-import com.android.keyguard.KeyguardHostView.OnDismissAction;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.ViewMediatorCallback;
@@ -152,11 +130,11 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.Dumpable;
 import com.android.systemui.EventLogTags;
+import com.android.systemui.InitController;
 import com.android.systemui.Interpolators;
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.RecentsComponent;
-import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.UiOffloadThread;
@@ -185,38 +163,34 @@
 import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.stackdivider.WindowManagerProxy;
-import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.AmbientPulseManager;
-import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
-import com.android.systemui.statusbar.notification.AppOpsListener;
 import com.android.systemui.statusbar.BackDropView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.EmptyShadeView;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyboardShortcuts;
 import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.notification.NotificationData;
-import com.android.systemui.statusbar.notification.NotificationData.Entry;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
-import com.android.systemui.statusbar.notification.row.NotificationInfo;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.NotificationViewHierarchyManager;
-import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.ScrimView;
+import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.notification.AboveShelfObserver;
 import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.notification.AppOpsListener;
+import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.NotificationData.Entry;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
@@ -230,7 +204,6 @@
 import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
 import com.android.systemui.statusbar.policy.ExtensionController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
-import com.android.systemui.statusbar.policy.HeadsUpUtil;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
@@ -253,9 +226,9 @@
 public class StatusBar extends SystemUI implements DemoMode,
         ActivityStarter, OnUnlockMethodChangedListener,
         OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
-        ColorExtractor.OnColorsChangedListener, ConfigurationListener, NotificationPresenter,
-        StatusBarStateController.StateListener,  AmbientPulseManager.OnAmbientChangedListener,
-        ActivityLaunchAnimator.Callback {
+        ColorExtractor.OnColorsChangedListener, ConfigurationListener,
+        StatusBarStateController.StateListener, ShadeController,
+        ActivityLaunchAnimator.Callback, AmbientPulseManager.OnAmbientChangedListener {
     public static final boolean MULTIUSER_DEBUG = false;
 
     public static final boolean ENABLE_CHILD_NOTIFICATIONS
@@ -324,10 +297,10 @@
 
     /** If true, the system is in the half-boot-to-decryption-screen state.
      * Prudently disable QS and notifications.  */
-    private static final boolean ONLY_CORE_APPS;
+    public static final boolean ONLY_CORE_APPS;
 
     /** If true, the lockscreen will show a distinct wallpaper */
-    private static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
+    public static final boolean ENABLE_LOCKSCREEN_WALLPAPER = true;
 
     static {
         boolean onlyCoreApps;
@@ -376,7 +349,6 @@
 
     // expanded notifications
     protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
-    private TextView mNotificationPanelDebugText;
 
     // settings
     private QSPanel mQSPanel;
@@ -385,15 +357,12 @@
 
     // RemoteInputView to be activated after unlock
     private View mPendingRemoteInputView;
-    private View mPendingWorkRemoteInputView;
 
     private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler =
             Dependency.get(RemoteInputQuickSettingsDisabler.class);
 
     private View mReportRejectedTouch;
 
-    private int mMaxAllowedKeyguardNotifications;
-
     private boolean mExpandedVisible;
 
     private final int[] mAbsPos = new int[2];
@@ -460,7 +429,6 @@
     private int mInteractingWindows;
     private boolean mAutohideSuspended;
     private int mStatusBarMode;
-    private int mMaxKeyguardNotifications;
 
     private ViewMediatorCallback mKeyguardViewMediatorCallback;
     protected ScrimController mScrimController;
@@ -479,9 +447,6 @@
 
     protected BackDropView mBackdrop;
     protected ImageView mBackdropFront, mBackdropBack;
-    protected final PorterDuffXfermode mSrcXferMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
-    protected final PorterDuffXfermode mSrcOverXferMode =
-            new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER);
 
     private NotificationMediaManager mMediaManager;
     protected NotificationLockscreenUserManager mLockscreenUserManager;
@@ -556,13 +521,9 @@
     private BatteryController mBatteryController;
     protected boolean mPanelExpanded;
     private UiModeManager mUiModeManager;
-    private boolean mKeyguardRequested;
     private boolean mIsKeyguard;
     private LogMaker mStatusBarStateLog;
-    private final LockscreenGestureLogger mLockscreenGestureLogger =
-            Dependency.get(LockscreenGestureLogger.class);
     protected NotificationIconAreaController mNotificationIconAreaController;
-    private boolean mReinflateNotificationsOnUserSwitched;
     @Nullable private View mAmbientIndicationContainer;
     private SysuiColorExtractor mColorExtractor;
     private ScreenLifecycle mScreenLifecycle;
@@ -597,10 +558,10 @@
 
     private NavigationBarFragment mNavigationBar;
     private View mNavigationBarView;
-    protected ActivityLaunchAnimator mActivityLaunchAnimator;
     private HeadsUpAppearanceController mHeadsUpAppearanceController;
     private boolean mVibrateOnOpening;
     private VibratorHelper mVibratorHelper;
+    protected NotificationPresenter mPresenter;
 
     @Override
     public void start() {
@@ -625,11 +586,11 @@
         mEntryManager = Dependency.get(NotificationEntryManager.class);
         mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class);
         mAppOpsListener = Dependency.get(AppOpsListener.class);
-        mAppOpsListener.setUpWithPresenter(this, mEntryManager);
         mZenController = Dependency.get(ZenModeController.class);
         mKeyguardViewMediator = getComponent(KeyguardViewMediator.class);
-
         mColorExtractor = Dependency.get(SysuiColorExtractor.class);
+        mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
+
         mColorExtractor.addOnColorsChangedListener(this);
         mStatusBarStateController.addListener(this, StatusBarStateController.RANK_STATUS_BAR);
 
@@ -658,17 +619,12 @@
 
         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
 
-        mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
-
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
 
         mRecents = getComponent(Recents.class);
 
         mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-        mLockPatternUtils = new LockPatternUtils(mContext);
-
-        mMediaManager.setUpWithPresenter(this, mEntryManager);
 
         // Connect in to the status bar manager service
         mCommandQueue = getComponent(CommandQueue.class);
@@ -695,8 +651,9 @@
                 wallpaperChangedFilter, null /* broadcastPermission */, null /* scheduler */);
         mWallpaperChangedReceiver.onReceive(mContext, null);
 
-        mLockscreenUserManager.setUpWithPresenter(this, mEntryManager);
-        mCommandQueue.disable(switches[0], switches[6], false /* animate */);
+        // Set up the initial notification state. This needs to happen before CommandQueue.disable()
+        setUpPresenter();
+
         setSystemUiVisibility(switches[1], switches[7], switches[8], 0xffffffff,
                 fullscreenStackBounds, dockedStackBounds);
         topAppWindowChanged(switches[2] != 0);
@@ -709,8 +666,6 @@
             mCommandQueue.setIcon(iconSlots.get(i), icons.get(i));
         }
 
-        // Set up the initial notification state.
-        mNotificationListener.setUpWithPresenter(this, mEntryManager);
 
         if (DEBUG) {
             Log.d(TAG, String.format(
@@ -723,24 +678,12 @@
                    ));
         }
 
-        setHeadsUpUser(mLockscreenUserManager.getCurrentUserId());
-
         IntentFilter internalFilter = new IntentFilter();
         internalFilter.addAction(BANNER_ACTION_CANCEL);
         internalFilter.addAction(BANNER_ACTION_SETUP);
         mContext.registerReceiver(mBannerActionBroadcastReceiver, internalFilter, PERMISSION_SELF,
                 null);
 
-        IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
-                Context.VR_SERVICE));
-        if (vrManager != null) {
-            try {
-                vrManager.registerListener(mVrStateCallbacks);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Failed to register VR mode state listener: " + e);
-            }
-        }
-
         IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface(
                 ServiceManager.getService(Context.WALLPAPER_SERVICE));
         try {
@@ -768,6 +711,13 @@
         Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
 
         Dependency.get(ConfigurationController.class).addCallback(this);
+
+        // set the initial view visibility
+        Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications);
+        Dependency.get(InitController.class).addPostInitTask(() -> {
+            setUpDisableFlags(switches[0], switches[6]);
+        });
+
     }
 
     // ================================================================================
@@ -787,24 +737,9 @@
         // into fragments, but the rest here, it leaves some awkward lifecycle and whatnot.
         mNotificationPanel = mStatusBarWindow.findViewById(R.id.notification_panel);
         mStackScroller = mStatusBarWindow.findViewById(R.id.notification_stack_scroller);
-        NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
         mZenController.addCallback(this);
-        mActivityLaunchAnimator = new ActivityLaunchAnimator(mStatusBarWindow,
-                this,
-                mNotificationPanel,
-                notifListContainer);
-        mGutsManager.setUpWithPresenter(this, notifListContainer, mCheckSaveListener,
-                key -> {
-                    try {
-                        mBarService.onNotificationSettingsViewed(key);
-                    } catch (RemoteException e) {
-                        // if we're here we're dead
-                    }
-                });
-        mNotificationLogger.setUpWithEntryManager(mEntryManager, notifListContainer);
-        mAboveShelfObserver = new AboveShelfObserver(mStackScroller);
-        mAboveShelfObserver.setListener(mStatusBarWindow.findViewById(
-                R.id.notification_container_parent));
+        NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
+        mNotificationLogger.setUpWithContainer(notifListContainer);
 
         mNotificationIconAreaController = SystemUIFactory.getInstance()
                 .createNotificationIconAreaController(context, this);
@@ -849,7 +784,7 @@
                             mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow);
                     mHeadsUpAppearanceController.readFrom(oldController);
                     mStatusBarWindow.setStatusBarView(mStatusBarView);
-                    setAreThereNotifications();
+                    updateAreThereNotifications();
                     checkBarModes();
                 }).getFragmentManager()
                 .beginTransaction()
@@ -871,13 +806,6 @@
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
         putComponent(HeadsUpManager.class, mHeadsUpManager);
 
-        mEntryManager.setUpWithPresenter(this, notifListContainer, this, mHeadsUpManager);
-        mViewHierarchyManager.setUpWithPresenter(this, mEntryManager, notifListContainer);
-
-        if (MULTIUSER_DEBUG) {
-            mNotificationPanelDebugText = mNotificationPanel.findViewById(R.id.header_debug_info);
-            mNotificationPanelDebugText.setVisibility(View.VISIBLE);
-        }
 
         try {
             boolean showNav = mWindowManagerService.hasNavigationBar();
@@ -889,10 +817,6 @@
             // no window manager? good luck with that
         }
 
-        mBackdrop = mStatusBarWindow.findViewById(R.id.backdrop);
-        mBackdropFront = mBackdrop.findViewById(R.id.backdrop_front);
-        mBackdropBack = mBackdrop.findViewById(R.id.backdrop_back);
-
         if (ENABLE_LOCKSCREEN_WALLPAPER) {
             mLockscreenWallpaper = new LockscreenWallpaper(mContext, this, mHandler);
         }
@@ -907,9 +831,6 @@
         mAmbientIndicationContainer = mStatusBarWindow.findViewById(
                 R.id.ambient_indication_container);
 
-        // set the initial view visibility
-        setAreThereNotifications();
-
         // TODO: Find better place for this callback.
         mBatteryController.addCallback(new BatteryStateChangeCallback() {
             @Override
@@ -947,6 +868,12 @@
         mDozeScrimController = new DozeScrimController(mScrimController, context,
                 DozeParameters.getInstance(context));
 
+        mBackdrop = mStatusBarWindow.findViewById(R.id.backdrop);
+        mBackdropFront = mBackdrop.findViewById(R.id.backdrop_front);
+        mBackdropBack = mBackdrop.findViewById(R.id.backdrop_back);
+        mMediaManager.setup(mBackdrop, mBackdropFront, mBackdropBack,
+                mScrimController, mLockscreenWallpaper);
+
         // Other icons
         mVolumeComponent = getComponent(VolumeComponent.class);
 
@@ -1052,6 +979,50 @@
         ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
     }
 
+    protected void setUpPresenter() {
+        // Set up the initial notification state.
+        mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
+                mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
+                mScrimController, this);
+        mAppOpsListener.setUpWithPresenter(mPresenter);
+        mNotificationListener.setUpWithPresenter(mPresenter);
+        mNotificationShelf.setOnActivatedListener(mPresenter);
+        mRemoteInputManager.getController().addCallback(mStatusBarWindowController);
+    }
+
+    /**
+     * Post-init task of {@link #start()}
+     * @param state1 disable1 flags
+     * @param state2 disable2 flags
+     */
+    protected void setUpDisableFlags(int state1, int state2) {
+        mCommandQueue.disable(state1, state2, false /* animate */);
+    }
+
+    @Override
+    public void addAfterKeyguardGoneRunnable(Runnable runnable) {
+        mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
+    }
+
+    @Override
+    public boolean isDozing() {
+        return mDozing && mNotificationPanel.isFullyDark();
+    }
+
+    @Override
+    public void wakeUpIfDozing(long time, View where) {
+        if (mDozing) {
+            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+            pm.wakeUp(time, "com.android.systemui:NODOZE");
+            mWakeUpComingFromTouch = true;
+            where.getLocationInWindow(mTmpInt2);
+            mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
+                    mTmpInt2[1] + where.getHeight() / 2);
+            mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
+            mFalsingManager.onScreenOnFromTouch();
+        }
+    }
+
     protected void createNavigationBar() {
         mNavigationBarView = NavigationBarFragment.create(mContext, (tag, fragment) -> {
             mNavigationBar = (NavigationBarFragment) fragment;
@@ -1083,7 +1054,6 @@
         mNotificationShelf =
                 (NotificationShelf) LayoutInflater.from(mContext).inflate(
                         R.layout.status_bar_notification_shelf, mStackScroller, false);
-        mNotificationShelf.setOnActivatedListener(this);
         mNotificationShelf.setOnClickListener(mGoToLockedShadeListener);
     }
 
@@ -1091,13 +1061,6 @@
     public void onDensityOrFontScaleChanged() {
         MessagingMessage.dropCache();
         MessagingGroup.dropCache();
-        // start old BaseStatusBar.onDensityOrFontScaleChanged().
-        if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
-            mEntryManager.updateNotificationsOnDensityOrFontScaleChanged();
-        } else {
-            mReinflateNotificationsOnUserSwitched = true;
-        }
-        // end old BaseStatusBar.onDensityOrFontScaleChanged().
         // TODO: Remove this.
         if (mBrightnessMirrorController != null) {
             mBrightnessMirrorController.onDensityOrFontScaleChanged();
@@ -1168,8 +1131,6 @@
                 mScrimController, this, UnlockMethodCache.getInstance(mContext));
         mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
                 getBouncerContainer(), mNotificationPanel, mBiometricUnlockController);
-        //TODO: Can we put the keyguard view manager in Dependency?
-        mLockscreenUserManager.setKeyguardViewManager(mStatusBarKeyguardViewManager);
         mKeyguardIndicationController
                 .setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
         mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
@@ -1177,6 +1138,7 @@
 
         mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
         mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
+        mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
         Dependency.get(KeyguardDismissUtil.class).setDismissHandler(this::executeWhenUnlocked);
         Trace.endSection();
     }
@@ -1233,73 +1195,13 @@
         return true;
     }
 
-    @Override
-    public void onPerformRemoveNotification(StatusBarNotification n) {
-        if (mNotificationPanel.hasPulsingNotifications() &&
-                    !mAmbientPulseManager.hasNotifications()) {
-            // We were showing a pulse for a notification, but no notifications are pulsing anymore.
-            // Finish the pulse.
-            mDozeScrimController.pulseOutNow();
-        }
-    }
-
-    @Override
-    public void updateNotificationViews() {
-        // The function updateRowStates depends on both of these being non-null, so check them here.
-        // We may be called before they are set from DeviceProvisionedController's callback.
-        if (mScrimController == null) return;
-
-        // Do not modify the notifications during collapse.
-        if (isCollapsing()) {
-            addPostCollapseAction(this::updateNotificationViews);
-            return;
-        }
-
-        mViewHierarchyManager.updateNotificationViews();
-
-        mNotificationPanel.updateNotificationViews();
-
-        updateQsExpansionEnabled();
-
-        // Let's also update the icons
-        mNotificationIconAreaController.updateNotificationIcons();
-    }
-
-    @Override
-    public void onNotificationAdded(Entry shadeEntry) {
-        // Recalculate the position of the sliding windows and the titles.
-        setAreThereNotifications();
-    }
-
-    @Override
-    public void onNotificationUpdated(StatusBarNotification notification) {
-        setAreThereNotifications();
-    }
-
-    @Override
-    public void onNotificationRemoved(String key, StatusBarNotification old) {
-        if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
-
-        if (old != null) {
-            if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
-                    && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
-                if (mState == StatusBarState.SHADE) {
-                    animateCollapsePanels();
-                } else if (mState == StatusBarState.SHADE_LOCKED && !isCollapsing()) {
-                    goToKeyguard();
-                }
-            }
-        }
-        setAreThereNotifications();
-    }
-
     /**
      * Disable QS if device not provisioned.
      * If the user switcher is simple then disable QS during setup because
      * the user intends to use the lock screen user switcher, QS in not needed.
      */
     private void updateQsExpansionEnabled() {
-        mNotificationPanel.setQsExpansionEnabled(isDeviceProvisioned()
+        mNotificationPanel.setQsExpansionEnabled(mDeviceProvisionedController.isDeviceProvisioned()
                 && (mUserSetup || mUserSwitcherController == null
                         || !mUserSwitcherController.isSimpleUserSwitcher())
                 && ((mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0)
@@ -1336,12 +1238,11 @@
         mEntryManager.updateNotifications();
     }
 
-    protected void setAreThereNotifications() {
-
+    public void updateAreThereNotifications() {
         if (SPEW) {
             final boolean clearable = hasActiveNotifications() &&
                     mNotificationPanel.hasActiveClearableNotifications();
-            Log.d(TAG, "setAreThereNotifications: N=" +
+            Log.d(TAG, "updateAreThereNotifications: N=" +
                     mEntryManager.getNotificationData().getActiveNotifications().size() + " any=" +
                     hasActiveNotifications() + " clearable=" + clearable);
         }
@@ -1367,192 +1268,9 @@
                         .start();
             }
         }
-
         mMediaManager.findAndUpdateMediaNotifications();
     }
 
-
-    /**
-     * Hide the album artwork that is fading out and release its bitmap.
-     */
-    protected final Runnable mHideBackdropFront = new Runnable() {
-        @Override
-        public void run() {
-            if (DEBUG_MEDIA) {
-                Log.v(TAG, "DEBUG_MEDIA: removing fade layer");
-            }
-            mBackdropFront.setVisibility(View.INVISIBLE);
-            mBackdropFront.animate().cancel();
-            mBackdropFront.setImageDrawable(null);
-        }
-    };
-
-    // TODO: Move this to NotificationMediaManager.
-    /**
-     * Refresh or remove lockscreen artwork from media metadata or the lockscreen wallpaper.
-     */
-    @Override
-    public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
-        Trace.beginSection("StatusBar#updateMediaMetaData");
-        if (!SHOW_LOCKSCREEN_MEDIA_ARTWORK) {
-            Trace.endSection();
-            return;
-        }
-
-        if (mBackdrop == null) {
-            Trace.endSection();
-            return; // called too early
-        }
-
-        boolean wakeAndUnlock = mBiometricUnlockController != null
-            && mBiometricUnlockController.isWakeAndUnlock();
-        if (mLaunchTransitionFadingAway || wakeAndUnlock) {
-            mBackdrop.setVisibility(View.INVISIBLE);
-            Trace.endSection();
-            return;
-        }
-
-        MediaMetadata mediaMetadata = mMediaManager.getMediaMetadata();
-
-        if (DEBUG_MEDIA) {
-            Log.v(TAG, "DEBUG_MEDIA: updating album art for notification "
-                    + mMediaManager.getMediaNotificationKey()
-                    + " metadata=" + mediaMetadata
-                    + " metaDataChanged=" + metaDataChanged
-                    + " state=" + mState);
-        }
-
-        Drawable artworkDrawable = null;
-        if (mediaMetadata != null) {
-            Bitmap artworkBitmap = mediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
-            if (artworkBitmap == null) {
-                artworkBitmap = mediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
-                // might still be null
-            }
-            if (artworkBitmap != null) {
-                artworkDrawable = new BitmapDrawable(mBackdropBack.getResources(), artworkBitmap);
-            }
-        }
-        boolean allowWhenShade = false;
-        if (ENABLE_LOCKSCREEN_WALLPAPER && artworkDrawable == null) {
-            Bitmap lockWallpaper = mLockscreenWallpaper.getBitmap();
-            if (lockWallpaper != null) {
-                artworkDrawable = new LockscreenWallpaper.WallpaperDrawable(
-                        mBackdropBack.getResources(), lockWallpaper);
-                // We're in the SHADE mode on the SIM screen - yet we still need to show
-                // the lockscreen wallpaper in that mode.
-                allowWhenShade = mStatusBarKeyguardViewManager != null
-                        && mStatusBarKeyguardViewManager.isShowing();
-            }
-        }
-
-        boolean hideBecauseOccluded = mStatusBarKeyguardViewManager != null
-                && mStatusBarKeyguardViewManager.isOccluded();
-
-        final boolean hasArtwork = artworkDrawable != null;
-        mColorExtractor.setHasBackdrop(hasArtwork);
-        if (mScrimController != null) {
-            mScrimController.setHasBackdrop(hasArtwork);
-        }
-
-        if ((hasArtwork || DEBUG_MEDIA_FAKE_ARTWORK)
-                && (mState != StatusBarState.SHADE || allowWhenShade)
-                && mBiometricUnlockController.getMode()
-                        != BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
-                && !hideBecauseOccluded) {
-            // time to show some art!
-            if (mBackdrop.getVisibility() != View.VISIBLE) {
-                mBackdrop.setVisibility(View.VISIBLE);
-                if (allowEnterAnimation) {
-                    mBackdrop.setAlpha(0);
-                    mBackdrop.animate().alpha(1f);
-                } else {
-                    mBackdrop.animate().cancel();
-                    mBackdrop.setAlpha(1f);
-                }
-                mStatusBarWindowController.setBackdropShowing(true);
-                metaDataChanged = true;
-                if (DEBUG_MEDIA) {
-                    Log.v(TAG, "DEBUG_MEDIA: Fading in album artwork");
-                }
-            }
-            if (metaDataChanged) {
-                if (mBackdropBack.getDrawable() != null) {
-                    Drawable drawable =
-                            mBackdropBack.getDrawable().getConstantState()
-                                    .newDrawable(mBackdropFront.getResources()).mutate();
-                    mBackdropFront.setImageDrawable(drawable);
-                    mBackdropFront.setAlpha(1f);
-                    mBackdropFront.setVisibility(View.VISIBLE);
-                } else {
-                    mBackdropFront.setVisibility(View.INVISIBLE);
-                }
-
-                if (DEBUG_MEDIA_FAKE_ARTWORK) {
-                    final int c = 0xFF000000 | (int)(Math.random() * 0xFFFFFF);
-                    Log.v(TAG, String.format("DEBUG_MEDIA: setting new color: 0x%08x", c));
-                    mBackdropBack.setBackgroundColor(0xFFFFFFFF);
-                    mBackdropBack.setImageDrawable(new ColorDrawable(c));
-                } else {
-                    mBackdropBack.setImageDrawable(artworkDrawable);
-                }
-
-                if (mBackdropFront.getVisibility() == View.VISIBLE) {
-                    if (DEBUG_MEDIA) {
-                        Log.v(TAG, "DEBUG_MEDIA: Crossfading album artwork from "
-                                + mBackdropFront.getDrawable()
-                                + " to "
-                                + mBackdropBack.getDrawable());
-                    }
-                    mBackdropFront.animate()
-                            .setDuration(250)
-                            .alpha(0f).withEndAction(mHideBackdropFront);
-                }
-            }
-        } else {
-            // need to hide the album art, either because we are unlocked, on AOD
-            // or because the metadata isn't there to support it
-            if (mBackdrop.getVisibility() != View.GONE) {
-                if (DEBUG_MEDIA) {
-                    Log.v(TAG, "DEBUG_MEDIA: Fading out album artwork");
-                }
-                boolean cannotAnimateDoze = mDozing && !ScrimState.AOD.getAnimateChange();
-                if (mBiometricUnlockController.getMode()
-                        == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING
-                        || hideBecauseOccluded || cannotAnimateDoze) {
-
-                    // We are unlocking directly - no animation!
-                    mBackdrop.setVisibility(View.GONE);
-                    mBackdropBack.setImageDrawable(null);
-                    mStatusBarWindowController.setBackdropShowing(false);
-                } else {
-                    mStatusBarWindowController.setBackdropShowing(false);
-                    mBackdrop.animate()
-                            .alpha(0)
-                            .setInterpolator(Interpolators.ACCELERATE_DECELERATE)
-                            .setDuration(300)
-                            .setStartDelay(0)
-                            .withEndAction(() -> {
-                                mBackdrop.setVisibility(View.GONE);
-                                mBackdropFront.animate().cancel();
-                                mBackdropBack.setImageDrawable(null);
-                                mHandler.post(mHideBackdropFront);
-                            });
-                    if (mKeyguardMonitor.isKeyguardFadingAway()) {
-                        mBackdrop.animate()
-                                // Make it disappear faster, as the focus should be on the activity
-                                // behind.
-                                .setDuration(mKeyguardMonitor.getKeyguardFadingAwayDuration() / 2)
-                                .setStartDelay(mKeyguardMonitor.getKeyguardFadingAwayDelay())
-                                .setInterpolator(Interpolators.LINEAR)
-                                .start();
-                    }
-                }
-            }
-        }
-        Trace.endSection();
-    }
-
     private void updateReportRejectedTouchVisibility() {
         if (mReportRejectedTouch == null) {
             return;
@@ -1645,15 +1363,6 @@
         }
     }
 
-    /**
-     * Reapplies the disable flags as last requested by StatusBarManager.
-     *
-     * This needs to be called if state used by adjustDisableFlags changes.
-     */
-    public void recomputeDisableFlags(boolean animate) {
-        mCommandQueue.recomputeDisableFlags(animate);
-    }
-
     protected H createHandler() {
         return new StatusBar.H();
     }
@@ -1694,53 +1403,6 @@
         return mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
     }
 
-    @Override
-    public boolean isDozing() {
-        return mDozing && mNotificationPanel.isFullyDark();
-    }
-
-    @Override
-    public boolean canHeadsUp(Entry entry, StatusBarNotification sbn) {
-        if (isDozing()) {
-            return false;
-        }
-
-        if (mIsOccluded) {
-            boolean devicePublic = mLockscreenUserManager.
-                    isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
-            boolean userPublic = devicePublic
-                    || mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
-            boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
-            if (userPublic && needsRedaction) {
-                return false;
-            }
-        }
-
-        if (!panelsEnabled()) {
-            if (DEBUG) {
-                Log.d(TAG, "No heads up: disabled panel : " + sbn.getKey());
-            }
-            return false;
-        }
-
-        if (sbn.getNotification().fullScreenIntent != null) {
-            if (mAccessibilityManager.isTouchExplorationEnabled()) {
-                if (DEBUG) Log.d(TAG, "No heads up: accessible fullscreen: " + sbn.getKey());
-                return false;
-            } else {
-                // we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
-                return !mStatusBarKeyguardViewManager.isShowing()
-                        || mStatusBarKeyguardViewManager.isOccluded();
-            }
-        }
-        return true;
-    }
-
-    @Override  // NotificationData.Environment
-    public String getCurrentMediaNotificationKey() {
-        return mMediaManager.getMediaNotificationKey();
-    }
-
     /**
      * To be called when there's a state change in StatusBarKeyguardViewManager.
      */
@@ -1814,12 +1476,6 @@
         }
     }
 
-    protected void setHeadsUpUser(int newUserId) {
-        if (mHeadsUpManager != null) {
-            mHeadsUpManager.setUser(newUserId);
-        }
-    }
-
     public boolean isKeyguardCurrentlySecure() {
         return !mUnlockMethodCache.canSkipBouncer();
     }
@@ -1867,6 +1523,11 @@
         return mAmbientIndicationContainer;
     }
 
+    @Override
+    public boolean isOccluded() {
+        return mIsOccluded;
+    }
+
     public void setOccluded(boolean occluded) {
         mIsOccluded = occluded;
         mScrimController.setKeyguardOccluded(occluded);
@@ -1900,10 +1561,10 @@
                 mWereIconsJustHidden = true;
                 mHandler.postDelayed(() -> {
                     mWereIconsJustHidden = false;
-                    recomputeDisableFlags(true);
+                    mCommandQueue.recomputeDisableFlags(true);
                 }, 500);
             } else {
-                recomputeDisableFlags(animate);
+                mCommandQueue.recomputeDisableFlags(animate);
             }
         }
         if (shouldHideIconsForBouncer) {
@@ -1911,20 +1572,21 @@
         }
     }
 
-    @Override
-    public void onLaunchAnimationCancelled() {
-        if (!isCollapsing()) {
-            onClosingFinished();
-        }
-    }
-
     public boolean isHeadsUpShouldBeVisible() {
         return mHeadsUpAppearanceController.shouldBeVisible();
     }
 
+    //TODO: These can / should probably be moved to NotificationPresenter or ShadeController
+    @Override
+    public void onLaunchAnimationCancelled() {
+        if (!mPresenter.isCollapsing()) {
+            onClosingFinished();
+        }
+    }
+
     @Override
     public void onExpandAnimationFinished(boolean launchIsFullScreen) {
-        if (!isCollapsing()) {
+        if (!mPresenter.isCollapsing()) {
             onClosingFinished();
         }
         if (launchIsFullScreen) {
@@ -1934,8 +1596,9 @@
 
     @Override
     public void onExpandAnimationTimedOut() {
-        if (isPresenterFullyCollapsed() && !isCollapsing()
-                && !mActivityLaunchAnimator.isLaunchForActivity()) {
+        ActivityLaunchAnimator animator = mPresenter.getActivityLaunchAnimator();
+        if (mPresenter.isPresenterFullyCollapsed() && !mPresenter.isCollapsing()
+                && animator != null && !animator.isLaunchForActivity()) {
             onClosingFinished();
         } else {
             collapsePanel(true /* animate */);
@@ -1947,6 +1610,14 @@
         return mState == StatusBarState.SHADE;
     }
 
+    public boolean isDeviceInVrMode() {
+        return mPresenter.isDeviceInVrMode();
+    }
+
+    public NotificationPresenter getPresenter() {
+        return mPresenter;
+    }
+
     /**
      * All changes to the status bar and notifications funnel through here and are batched.
      */
@@ -2004,7 +1675,7 @@
     @Override
     public void handleSystemKey(int key) {
         if (SPEW) Log.d(TAG, "handleNavigationKey: " + key);
-        if (!panelsEnabled() || !mKeyguardMonitor.isDeviceInteractive()
+        if (!mCommandQueue.panelsEnabled() || !mKeyguardMonitor.isDeviceInteractive()
                 || mKeyguardMonitor.isShowing() && !mKeyguardMonitor.isOccluded()) {
             return;
         }
@@ -2046,15 +1717,9 @@
         }
     }
 
-    boolean panelsEnabled() {
-        return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0
-                && (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0
-                && !ONLY_CORE_APPS;
-    }
-
     void makeExpandedVisible(boolean force) {
         if (SPEW) Log.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible);
-        if (!force && (mExpandedVisible || !panelsEnabled())) {
+        if (!force && (mExpandedVisible || !mCommandQueue.panelsEnabled())) {
             return;
         }
 
@@ -2065,7 +1730,7 @@
         mStatusBarWindowController.setPanelVisible(true);
 
         visibilityChanged(true);
-        recomputeDisableFlags(!force /* animate */);
+        mCommandQueue.recomputeDisableFlags(!force /* animate */);
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, true);
     }
 
@@ -2098,12 +1763,12 @@
         }
     }
 
-    @Override
     public void animateCollapsePanels(int flags) {
         animateCollapsePanels(flags, false /* force */, false /* delayed */,
                 1.0f /* speedUpFactor */);
     }
 
+    @Override
     public void animateCollapsePanels(int flags, boolean force) {
         animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
     }
@@ -2154,7 +1819,7 @@
     }
 
     public void dispatchNotificationsPanelTouchEvent(MotionEvent ev) {
-        if (!panelsEnabled()) {
+        if (!mCommandQueue.panelsEnabled()) {
             return;
         }
         mNotificationPanel.dispatchTouchEvent(ev);
@@ -2172,7 +1837,7 @@
     @Override
     public void animateExpandNotificationsPanel() {
         if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
-        if (!panelsEnabled()) {
+        if (!mCommandQueue.panelsEnabled()) {
             return ;
         }
 
@@ -2184,7 +1849,7 @@
     @Override
     public void animateExpandSettingsPanel(@Nullable String subPanel) {
         if (SPEW) Log.d(TAG, "animateExpand: mExpandedVisible=" + mExpandedVisible);
-        if (!panelsEnabled()) {
+        if (!mCommandQueue.panelsEnabled()) {
             return;
         }
 
@@ -2232,8 +1897,13 @@
 
         runPostCollapseRunnables();
         setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false);
-        showBouncerIfKeyguard();
-        recomputeDisableFlags(mNotificationPanel.hideStatusBarIconsWhenExpanded() /* animate */);
+        if (!mPresenter.isCollapsingToShowActivityOverLockscreen()) {
+            showBouncerIfKeyguard();
+        } else if (DEBUG) {
+            Log.d(TAG, "Not showing bouncer due to activity showing over lockscreen");
+        }
+        mCommandQueue.recomputeDisableFlags(
+                mNotificationPanel.hideStatusBarIconsWhenExpanded() /* animate */);
 
         // Trimming will happen later if Keyguard is showing - doing it here might cause a jank in
         // the bouncer appear animation.
@@ -2325,7 +1995,7 @@
 
             // update low profile
             if ((diff & View.SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
-                setAreThereNotifications();
+                updateAreThereNotifications();
             }
 
             // ready to unhide
@@ -2698,9 +2368,6 @@
     private void addStatusBarWindow() {
         makeStatusBarView();
         mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
-        mRemoteInputManager.setUpWithPresenter(this, mEntryManager, this,
-                mNotificationPanel.createRemoteInputDelegate());
-        mRemoteInputManager.getController().addCallback(mStatusBarWindowController);
         mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());
     }
 
@@ -2745,7 +2412,7 @@
     public void startActivityDismissingKeyguard(final Intent intent, boolean onlyProvisioned,
             final boolean dismissShade, final boolean disallowEnterPictureInPictureWhileLaunching,
             final Callback callback, int flags) {
-        if (onlyProvisioned && !isDeviceProvisioned()) return;
+        if (onlyProvisioned && !mDeviceProvisionedController.isDeviceProvisioned()) return;
 
         final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
                 mContext, intent, mLockscreenUserManager.getCurrentUserId());
@@ -2852,6 +2519,9 @@
                 }
             }
             else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+                if (mStatusBarWindowController != null) {
+                    mStatusBarWindowController.setNotTouchable(false);
+                }
                 finishBarAnimations();
                 resetUserExpandedStates();
             }
@@ -2880,7 +2550,7 @@
                 }
             } else if (ACTION_FAKE_ARTWORK.equals(action)) {
                 if (DEBUG_MEDIA_FAKE_ARTWORK) {
-                    updateMediaMetaData(true, true);
+                    mPresenter.updateMediaMetaData(true, true);
                 }
             }
         }
@@ -2909,7 +2579,8 @@
         dismissKeyguardThenExecute(action, null /* cancelRunnable */, afterKeyguardGone);
     }
 
-    private void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
+    @Override
+    public void dismissKeyguardThenExecute(OnDismissAction action, Runnable cancelAction,
             boolean afterKeyguardGone) {
         if (mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP
                 && mUnlockMethodCache.canSkipBouncer()
@@ -2943,38 +2614,10 @@
     }
 
     @Override
-    public void onUserSwitched(int newUserId) {
-        // Begin old BaseStatusBar.userSwitched
-        setHeadsUpUser(newUserId);
-        // End old BaseStatusBar.userSwitched
-        if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
-        animateCollapsePanels();
-        if (mReinflateNotificationsOnUserSwitched) {
-            mEntryManager.updateNotificationsOnDensityOrFontScaleChanged();
-            mReinflateNotificationsOnUserSwitched = false;
-        }
-        updateNotificationViews();
-        mMediaManager.clearCurrentMediaNotification();
-        setLockscreenUser(newUserId);
-        mWallpaperChangedReceiver.onReceive(mContext, null);
-    }
-
-    @Override
-    public NotificationLockscreenUserManager getNotificationLockscreenUserManager() {
-        return mLockscreenUserManager;
-    }
-
-    @Override
-    public void onBindRow(Entry entry, PackageManager pmUser,
-            StatusBarNotification sbn, ExpandableNotificationRow row) {
-        row.setAboveShelfChangedListener(mAboveShelfObserver);
-        row.setSecureStateProvider(this::isKeyguardCurrentlySecure);
-    }
-
-    protected void setLockscreenUser(int newUserId) {
+    public void setLockscreenUser(int newUserId) {
         mLockscreenWallpaper.setCurrentUser(newUserId);
         mScrimController.setCurrentUser(newUserId);
-        updateMediaMetaData(true, false);
+        mWallpaperChangedReceiver.onReceive(mContext, null);
     }
 
     /**
@@ -3012,8 +2655,6 @@
         if (mStatusBarWindowController != null && mNaturalBarHeight != oldBarHeight) {
             mStatusBarWindowController.setBarHeight(mNaturalBarHeight);
         }
-        mMaxAllowedKeyguardNotifications = res.getInteger(
-                R.integer.keyguard_max_notification_count);
 
         if (DEBUG) Log.v(TAG, "defineSlots");
     }
@@ -3050,12 +2691,12 @@
         if (visibleToUser) {
             boolean pinnedHeadsUp = mHeadsUpManager.hasPinnedHeadsUp();
             boolean clearNotificationEffects =
-                    !isPresenterFullyCollapsed() &&
+                    !mPresenter.isPresenterFullyCollapsed() &&
                             (mState == StatusBarState.SHADE
                                     || mState == StatusBarState.SHADE_LOCKED);
             int notificationLoad = mEntryManager.getNotificationData().getActiveNotifications()
                     .size();
-            if (pinnedHeadsUp && isPresenterFullyCollapsed()) {
+            if (pinnedHeadsUp && mPresenter.isPresenterFullyCollapsed()) {
                 notificationLoad = 1;
             }
             final int finalNotificationLoad = notificationLoad;
@@ -3290,13 +2931,8 @@
         }
     }
 
-    @Override
-    public boolean isPresenterFullyCollapsed() {
-        return mNotificationPanel.isFullyCollapsed();
-    }
-
     public void showKeyguard() {
-        mKeyguardRequested = true;
+        mStatusBarStateController.setKeyguardRequested(true);
         mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
         mPendingRemoteInputView = null;
         updateIsKeyguard();
@@ -3304,11 +2940,12 @@
     }
 
     public boolean hideKeyguard() {
-        mKeyguardRequested = false;
+        mStatusBarStateController.setKeyguardRequested(false);
         return updateIsKeyguard();
     }
 
     /**
+     * stop(tag)
      * @return True if StatusBar state is FULLSCREEN_USER_SWITCHER.
      */
     public boolean isFullScreenUserSwitcherState() {
@@ -3325,7 +2962,8 @@
         // turned off fully.
         boolean keyguardForDozing = mDozingRequested &&
                 (!mDeviceInteractive || isGoingToSleep() && (isScreenFullyOff() || mIsKeyguard));
-        boolean shouldBeKeyguard = (mKeyguardRequested || keyguardForDozing) && !wakeAndUnlocking;
+        boolean shouldBeKeyguard = (mStatusBarStateController.isKeyguardRequested()
+                || keyguardForDozing) && !wakeAndUnlocking;
         if (keyguardForDozing) {
             updatePanelExpansionForKeyguard();
         }
@@ -3377,13 +3015,7 @@
         releaseGestureWakeLock();
         runLaunchTransitionEndRunnable();
         mLaunchTransitionFadingAway = false;
-        updateMediaMetaData(true /* metaDataChanged */, true);
-    }
-
-    public boolean isCollapsing() {
-        return mNotificationPanel.isCollapsing()
-                || mActivityLaunchAnimator.isAnimationPending()
-                || mActivityLaunchAnimator.isAnimationRunning();
+        mPresenter.updateMediaMetaData(true /* metaDataChanged */, true);
     }
 
     public void addPostCollapseAction(Runnable r) {
@@ -3407,12 +3039,13 @@
         mHandler.removeMessages(MSG_LAUNCH_TRANSITION_TIMEOUT);
         mLaunchTransitionEndRunnable = endRunnable;
         Runnable hideRunnable = () -> {
+            mKeyguardMonitor.setLaunchTransitionFadingAway(true);
             mLaunchTransitionFadingAway = true;
             if (beforeFading != null) {
                 beforeFading.run();
             }
             updateScrimController();
-            updateMediaMetaData(false, true);
+            mPresenter.updateMediaMetaData(false, true);
             mNotificationPanel.setAlpha(1);
             mNotificationPanel.animate()
                     .alpha(0)
@@ -3497,9 +3130,8 @@
             mLockscreenUserManager.updatePublicMode();
             mEntryManager.updateNotifications();
         }
-        View viewToClick = null;
         if (mStatusBarStateController.leaveOpenOnKeyguardHide()) {
-            if (!mKeyguardRequested) {
+            if (!mStatusBarStateController.isKeyguardRequested()) {
                 mStatusBarStateController.setLeaveOpenOnKeyguardHide(false);
             }
             long delay = mKeyguardMonitor.calculateGoingToFullShadeDelay();
@@ -3508,10 +3140,6 @@
                 mDraggedDownRow.setUserLocked(false);
                 mDraggedDownRow = null;
             }
-            if (!mKeyguardRequested) {
-                viewToClick = mPendingRemoteInputView;
-                mPendingRemoteInputView = null;
-            }
 
             // Disable layout transitions in navbar for this transition because the load is just
             // too heavy for the CPU and GPU on any device.
@@ -3522,10 +3150,6 @@
             instantCollapseNotificationPanel();
         }
 
-        if (viewToClick != null && viewToClick.isAttachedToWindow()) {
-            viewToClick.callOnClick();
-        }
-
         // Keyguard state has changed, but QS is not listening anymore. Make sure to update the tile
         // visibilities so next time we open the panel we know the correct height already.
         if (mQSPanel != null) {
@@ -3567,7 +3191,7 @@
         mCommandQueue.appTransitionStarting(startTime + fadeoutDuration
                         - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
                 LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
-        recomputeDisableFlags(fadeoutDuration > 0 /* animate */);
+        mCommandQueue.recomputeDisableFlags(fadeoutDuration > 0 /* animate */);
         mCommandQueue.appTransitionStarting(
                     startTime - LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION,
                     LightBarTransitionsController.DEFAULT_TINT_ANIMATION_DURATION, true);
@@ -3609,7 +3233,8 @@
 
         mDozeScrimController.setDozing(mDozing);
         mKeyguardIndicationController.setDozing(mDozing);
-        mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation);
+        mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation,
+                mDozeServiceHost.wasPassivelyInterrupted());
         mNotificationLogger.setDozing(mDozing);
         mGroupManager.setDozing(mDozing);
         updateQsExpansionEnabled();
@@ -3688,15 +3313,43 @@
         }
     }
 
-    protected void showBouncer(boolean scrimmed) {
+    @Override
+    public void showBouncer(boolean scrimmed) {
         mStatusBarKeyguardViewManager.showBouncer(scrimmed);
     }
 
-    private void instantExpandNotificationsPanel() {
+    @Override
+    public void instantExpandNotificationsPanel() {
         // Make our window larger and the panel expanded.
         makeExpandedVisible(true);
         mNotificationPanel.expand(false /* animate */);
-        recomputeDisableFlags(false /* animate */);
+        mCommandQueue.recomputeDisableFlags(false /* animate */);
+    }
+
+    @Override
+    public boolean closeShadeIfOpen() {
+        if (!mNotificationPanel.isFullyCollapsed()) {
+            mCommandQueue.animateCollapsePanels(
+                    CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
+            visibilityChanged(false);
+            mAssistManager.hideAssist();
+        }
+        return false;
+    }
+
+    @Override
+    public void postOnShadeExpanded(Runnable executable) {
+        mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener(
+                new ViewTreeObserver.OnGlobalLayoutListener() {
+                    @Override
+                    public void onGlobalLayout() {
+                        if (getStatusBarWindow().getHeight() != getStatusBarHeight()) {
+                            mNotificationPanel.getViewTreeObserver()
+                                    .removeOnGlobalLayoutListener(this);
+                            mNotificationPanel.post(executable);
+                        }
+                    }
+                });
     }
 
     private void instantCollapseNotificationPanel() {
@@ -3705,25 +3358,7 @@
     }
 
     @Override
-    public void onActivated(ActivatableNotificationView view) {
-        onActivated((View) view);
-        mNotificationPanel.setActivatedChild(view);
-    }
-
-    public void onActivated(View view) {
-        mLockscreenGestureLogger.write(
-                MetricsEvent.ACTION_LS_NOTE,
-                0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
-        mKeyguardIndicationController.showTransientIndication(R.string.notification_tap_again);
-        ActivatableNotificationView previousView = mNotificationPanel.getActivatedChild();
-        if (previousView != null) {
-            previousView.makeInactive(true /* animate */);
-        }
-    }
-
-    @Override
     public void onStatePreChange(int oldState, int newState) {
-
         // If we're visible and switched to SHADE_LOCKED (the user dragged
         // down on the lockscreen), clear notification LED, vibration,
         // ringing.
@@ -3748,9 +3383,6 @@
         Trace.beginSection("StatusBar#updateKeyguardState");
         if (mState == StatusBarState.KEYGUARD) {
             mKeyguardIndicationController.setVisible(true);
-            boolean dozingAnimated = mDozingRequested
-                    && DozeParameters.getInstance(mContext).shouldControlScreenOff();
-            mNotificationPanel.resetViews(dozingAnimated);
             if (mKeyguardUserSwitcher != null) {
                 mKeyguardUserSwitcher.setKeyguard(true,
                         mStatusBarStateController.fromShadeLocked());
@@ -3774,7 +3406,7 @@
         updateDozingState();
         checkBarModes();
         updateScrimController();
-        updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
+        mPresenter.updateMediaMetaData(false, mState != StatusBarState.KEYGUARD);
         mKeyguardMonitor.notifyKeyguardState(mStatusBarKeyguardViewManager.isShowing(),
                 mUnlockMethodCache.isMethodSecure(),
                 mStatusBarKeyguardViewManager.isOccluded());
@@ -3782,14 +3414,48 @@
     }
 
     @Override
-    public void onActivationReset(ActivatableNotificationView view) {
-        if (view == mNotificationPanel.getActivatedChild()) {
-            mNotificationPanel.setActivatedChild(null);
-            onActivationReset((View)view);
+    public void onDozingChanged(boolean isDozing) {
+        Trace.beginSection("StatusBar#updateDozing");
+        mDozing = isDozing;
+
+        // Collapse the notification panel if open
+        boolean dozingAnimated = mDozingRequested
+                && DozeParameters.getInstance(mContext).shouldControlScreenOff();
+        mNotificationPanel.resetViews(dozingAnimated);
+
+        updateQsExpansionEnabled();
+        mKeyguardViewMediator.setAodShowing(mDozing);
+
+        //TODO: make these folks listeners of StatusBarStateController.onDozingChanged
+        mStatusBarWindowController.setDozing(mDozing);
+        mStatusBarKeyguardViewManager.setDozing(mDozing);
+        if (mAmbientIndicationContainer instanceof DozeReceiver) {
+            ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
         }
+
+        mEntryManager.updateNotifications();
+        updateDozingState();
+        updateScrimController();
+        updateReportRejectedTouchVisibility();
+        Trace.endSection();
     }
 
-    public void onActivationReset(View view) {
+    private void updateDozing() {
+        // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
+        boolean dozing = mDozingRequested && mState == StatusBarState.KEYGUARD
+                || mBiometricUnlockController.getMode()
+                == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
+        // When in wake-and-unlock we may not have received a change to mState
+        // but we still should not be dozing, manually set to false.
+        if (mBiometricUnlockController.getMode() ==
+                BiometricUnlockController.MODE_WAKE_AND_UNLOCK) {
+            dozing = false;
+        }
+
+        mStatusBarStateController.setIsDozing(dozing);
+    }
+
+    public void onActivationReset() {
         mKeyguardIndicationController.hideTransientIndication();
     }
 
@@ -3799,7 +3465,7 @@
 
     public void onClosingFinished() {
         runPostCollapseRunnables();
-        if (!isPresenterFullyCollapsed()) {
+        if (!mPresenter.isPresenterFullyCollapsed()) {
             // if we set it not to be focusable when collapsing, we have to undo it when we aborted
             // the closing
             mStatusBarWindowController.setStatusBarFocusable(true);
@@ -3839,22 +3505,6 @@
         }
     }
 
-    @Override
-    public int getMaxNotificationsWhileLocked(boolean recompute) {
-        if (recompute) {
-            mMaxKeyguardNotifications = Math.max(1,
-                    mNotificationPanel.computeMaxKeyguardNotifications(
-                            mMaxAllowedKeyguardNotifications));
-            return mMaxKeyguardNotifications;
-        }
-        return mMaxKeyguardNotifications;
-    }
-
-    @Override
-    public void onUpdateRowStates() {
-        mNotificationPanel.onUpdateRowStates();
-    }
-
     // TODO: Figure out way to remove these.
     public NavigationBarView getNavigationBarView() {
         return (mNavigationBar != null ? (NavigationBarView) mNavigationBar.getView() : null);
@@ -3911,184 +3561,6 @@
         }
     }
 
-    public void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {
-        mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
-        dismissKeyguardThenExecute(dismissAction, true /* afterKeyguardGone */);
-    }
-
-    @Override
-    public void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
-        mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
-        showBouncer(true /* scrimmed */);
-        mPendingRemoteInputView = clicked;
-    }
-
-    @Override
-    public void onMakeExpandedVisibleForRemoteInput(ExpandableNotificationRow row,
-            View clickedView) {
-        if (isKeyguardShowing()) {
-            onLockedRemoteInput(row, clickedView);
-        } else {
-            row.setUserExpanded(true);
-            row.getPrivateLayout().setOnExpandedVisibleListener(clickedView::performClick);
-        }
-    }
-
-    @Override
-    public boolean shouldHandleRemoteInput(View view, PendingIntent pendingIntent) {
-        // Skip remote input as doing so will expand the notification shade.
-        return (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0;
-    }
-
-    @Override
-    public boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
-            Intent fillInIntent, NotificationRemoteInputManager.ClickHandler defaultHandler) {
-        final boolean isActivity = pendingIntent.isActivity();
-        if (isActivity) {
-            final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
-                    mContext, pendingIntent.getIntent(), mLockscreenUserManager.getCurrentUserId());
-            dismissKeyguardThenExecute(() -> {
-                try {
-                    ActivityManager.getService().resumeAppSwitches();
-                } catch (RemoteException e) {
-                }
-
-                boolean handled = defaultHandler.handleClick();
-
-                // close the shade if it was open
-                if (handled && !mNotificationPanel.isFullyCollapsed()) {
-                    animateCollapsePanels(
-                            CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */);
-                    visibilityChanged(false);
-                    mAssistManager.hideAssist();
-
-                    // Wait for activity start.
-                    return true;
-                } else {
-                    return false;
-                }
-
-            }, afterKeyguardGone);
-            return true;
-        } else {
-            return defaultHandler.handleClick();
-        }
-    }
-
-    protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
-            String notificationKey) {
-        // Clear pending remote view, as we do not want to trigger pending remote input view when
-        // it's called by other code
-        mPendingWorkRemoteInputView = null;
-        // Begin old BaseStatusBar.startWorkChallengeIfNecessary.
-        final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null,
-                null, userId);
-        if (newIntent == null) {
-            return false;
-        }
-        final Intent callBackIntent = new Intent(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
-        callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender);
-        callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey);
-        callBackIntent.setPackage(mContext.getPackageName());
-
-        PendingIntent callBackPendingIntent = PendingIntent.getBroadcast(
-                mContext,
-                0,
-                callBackIntent,
-                PendingIntent.FLAG_CANCEL_CURRENT |
-                        PendingIntent.FLAG_ONE_SHOT |
-                        PendingIntent.FLAG_IMMUTABLE);
-        newIntent.putExtra(
-                Intent.EXTRA_INTENT,
-                callBackPendingIntent.getIntentSender());
-        try {
-            ActivityManager.getService().startConfirmDeviceCredentialIntent(newIntent,
-                    null /*options*/);
-        } catch (RemoteException ex) {
-            // ignore
-        }
-        return true;
-        // End old BaseStatusBar.startWorkChallengeIfNecessary.
-    }
-
-    @Override
-    public void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row,
-            View clicked) {
-        // Collapse notification and show work challenge
-        animateCollapsePanels();
-        startWorkChallengeIfNecessary(userId, null, null);
-        // Add pending remote input view after starting work challenge, as starting work challenge
-        // will clear all previous pending review view
-        mPendingWorkRemoteInputView = clicked;
-    }
-
-    @Override
-    public void onWorkChallengeChanged() {
-        if (mPendingWorkRemoteInputView != null
-                && !mLockscreenUserManager.isAnyProfilePublicMode()) {
-            // Expand notification panel and the notification row, then click on remote input view
-            final Runnable clickPendingViewRunnable = () -> {
-                final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
-                if (pendingWorkRemoteInputView == null) {
-                    return;
-                }
-
-                // Climb up the hierarchy until we get to the container for this row.
-                ViewParent p = pendingWorkRemoteInputView.getParent();
-                while (!(p instanceof ExpandableNotificationRow)) {
-                    if (p == null) {
-                        return;
-                    }
-                    p = p.getParent();
-                }
-
-                final ExpandableNotificationRow row = (ExpandableNotificationRow) p;
-                ViewParent viewParent = row.getParent();
-                if (viewParent instanceof NotificationStackScrollLayout) {
-                    final NotificationStackScrollLayout scrollLayout =
-                            (NotificationStackScrollLayout) viewParent;
-                    row.makeActionsVisibile();
-                    row.post(() -> {
-                        final Runnable finishScrollingCallback = () -> {
-                            mPendingWorkRemoteInputView.callOnClick();
-                            mPendingWorkRemoteInputView = null;
-                            scrollLayout.setFinishScrollingCallback(null);
-                        };
-                        if (scrollLayout.scrollTo(row)) {
-                            // It scrolls! So call it when it's finished.
-                            scrollLayout.setFinishScrollingCallback(finishScrollingCallback);
-                        } else {
-                            // It does not scroll, so call it now!
-                            finishScrollingCallback.run();
-                        }
-                    });
-                }
-            };
-            mNotificationPanel.getViewTreeObserver().addOnGlobalLayoutListener(
-                    new ViewTreeObserver.OnGlobalLayoutListener() {
-                        @Override
-                        public void onGlobalLayout() {
-                            if (mNotificationPanel.mStatusBar.getStatusBarWindow()
-                                    .getHeight() != mNotificationPanel.mStatusBar
-                                            .getStatusBarHeight()) {
-                                mNotificationPanel.getViewTreeObserver()
-                                        .removeOnGlobalLayoutListener(this);
-                                mNotificationPanel.post(clickPendingViewRunnable);
-                            }
-                        }
-                    });
-            instantExpandNotificationsPanel();
-        }
-    }
-
-    @Override
-    public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
-        mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
-        if (mState == StatusBarState.KEYGUARD && nowExpanded) {
-            goToLockedShade(clickedEntry.row);
-        }
-    }
-
     /**
      * Goes back to the keyguard after hanging around in {@link StatusBarState#SHADE_LOCKED}.
      */
@@ -4102,7 +3574,7 @@
         mBouncerShowing = bouncerShowing;
         if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
         updateHideIconsForBouncer(true /* animate */);
-        recomputeDisableFlags(true /* animate */);
+        mCommandQueue.recomputeDisableFlags(true /* animate */);
         updateScrimController();
     }
 
@@ -4157,7 +3629,6 @@
             mAmbientPulseManager.releaseAllImmediately();
             mVisualStabilityManager.setScreenOn(true);
             mNotificationPanel.setTouchAndAnimationDisabled(false);
-            mDozeServiceHost.stopDozing();
             updateVisibleToUser();
             updateIsKeyguard();
             updateScrimController();
@@ -4227,25 +3698,6 @@
     }
 
     @Override
-    public void wakeUpIfDozing(long time, View where) {
-        if (mDozing) {
-            PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-            pm.wakeUp(time, "com.android.systemui:NODOZE");
-            mWakeUpComingFromTouch = true;
-            where.getLocationInWindow(mTmpInt2);
-            mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
-                    mTmpInt2[1] + where.getHeight() / 2);
-            mStatusBarKeyguardViewManager.notifyDeviceWakeUpRequested();
-            mFalsingManager.onScreenOnFromTouch();
-        }
-    }
-
-    @Override
-    public boolean isDeviceLocked(int userId) {
-        return mKeyguardManager.isDeviceLocked(userId);
-    }
-
-    @Override
     public void appTransitionCancelled() {
         getComponent(Divider.class).onAppTransitionFinished();
     }
@@ -4333,34 +3785,6 @@
         updateScrimController();
     }
 
-    private void updateDozing() {
-        Trace.beginSection("StatusBar#updateDozing");
-        // When in wake-and-unlock while pulsing, keep dozing state until fully unlocked.
-        boolean dozing = mDozingRequested && mState == StatusBarState.KEYGUARD
-                || mBiometricUnlockController.getMode()
-                        == BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
-        // When in wake-and-unlock we may not have received a change to mState
-        // but we still should not be dozing, manually set to false.
-        if (mBiometricUnlockController.getMode() ==
-                mBiometricUnlockController.MODE_WAKE_AND_UNLOCK) {
-            dozing = false;
-        }
-        if (mDozing != dozing) {
-            mDozing = dozing;
-            mKeyguardViewMediator.setAodShowing(mDozing);
-            mStatusBarWindowController.setDozing(mDozing);
-            mStatusBarKeyguardViewManager.setDozing(mDozing);
-            if (mAmbientIndicationContainer instanceof DozeReceiver) {
-                ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
-            }
-            mEntryManager.updateNotifications();
-            updateDozingState();
-            updateScrimController();
-            updateReportRejectedTouchVisibility();
-        }
-        Trace.endSection();
-    }
-
     @VisibleForTesting
     void updateScrimController() {
         Trace.beginSection("StatusBar#updateScrimController");
@@ -4383,6 +3807,9 @@
             // FLAG_DISMISS_KEYGUARD_ACTIVITY.
             ScrimState state = mStatusBarKeyguardViewManager.bouncerNeedsScrimming()
                     ? ScrimState.BOUNCER_SCRIMMED : ScrimState.BOUNCER;
+            if (mNotificationPanel.isSemiAwake()) {
+                state = ScrimState.DARK_KEYGUARD;
+            }
             mScrimController.transitionTo(state);
         } else if (isInLaunchTransition() || mLaunchCameraOnScreenTurningOn
                 || launchingAffordanceWithPreview) {
@@ -4394,7 +3821,8 @@
         } else if (mDozing) {
             mScrimController.transitionTo(ScrimState.AOD);
         } else if (mIsKeyguard && !wakeAndUnlocking) {
-            mScrimController.transitionTo(ScrimState.KEYGUARD);
+            mScrimController.transitionTo(mNotificationPanel.isSemiAwake()
+                    ? ScrimState.DARK_KEYGUARD : ScrimState.KEYGUARD);
         } else {
             mScrimController.transitionTo(ScrimState.UNLOCKED, mUnlockScrimCallback);
         }
@@ -4414,6 +3842,7 @@
         private boolean mAnimateWakeup;
         private boolean mAnimateScreenOff;
         private boolean mIgnoreTouchWhilePulsing;
+        private boolean mPassivelyInterrupted;
 
         @Override
         public String toString() {
@@ -4497,6 +3926,11 @@
         }
 
         @Override
+        public void setPassiveInterrupt(boolean passiveInterrupt) {
+            mPassivelyInterrupted = passiveInterrupt;
+        }
+
+        @Override
         public void onIgnoreTouchWhilePulsing(boolean ignore) {
             if (ignore != mIgnoreTouchWhilePulsing) {
                 DozeLog.tracePulseTouchDisabledByProx(mContext, ignore);
@@ -4615,6 +4049,10 @@
         public boolean shouldAnimateScreenOff() {
             return mAnimateScreenOff;
         }
+
+        public boolean wasPassivelyInterrupted() {
+            return mPassivelyInterrupted;
+        }
     }
 
     public boolean shouldIgnoreTouch() {
@@ -4637,8 +4075,6 @@
 
     protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
 
-    private AboveShelfObserver mAboveShelfObserver;
-
     // handling reordering
     protected VisualStabilityManager mVisualStabilityManager;
 
@@ -4656,7 +4092,6 @@
     protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     protected KeyguardManager mKeyguardManager;
-    private LockPatternUtils mLockPatternUtils;
     private DeviceProvisionedController mDeviceProvisionedController
             = Dependency.get(DeviceProvisionedController.class);
 
@@ -4675,28 +4110,10 @@
 
     protected AssistManager mAssistManager;
 
-    protected boolean mVrMode;
-
     public boolean isDeviceInteractive() {
         return mDeviceInteractive;
     }
 
-    @Override  // NotificationData.Environment
-    public boolean isDeviceProvisioned() {
-        return mDeviceProvisionedController.isDeviceProvisioned();
-    }
-
-    private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
-        @Override
-        public void onVrStateChanged(boolean enabled) {
-            mVrMode = enabled;
-        }
-    };
-
-    public boolean isDeviceInVrMode() {
-        return mVrMode;
-    }
-
     private final BroadcastReceiver mBannerActionBroadcastReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -4722,164 +4139,13 @@
     };
 
     @Override
-    public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) {
-        RemoteInputController controller = mRemoteInputManager.getController();
-        if (controller.isRemoteInputActive(row.getEntry())
-                && !TextUtils.isEmpty(row.getActiveRemoteInputText())) {
-            // We have an active remote input typed and the user clicked on the notification.
-            // this was probably unintentional, so we're closing the edit text instead.
-            controller.closeRemoteInputs();
-            return;
-        }
-        Notification notification = sbn.getNotification();
-        final PendingIntent intent = notification.contentIntent != null
-                ? notification.contentIntent
-                : notification.fullScreenIntent;
-        final String notificationKey = sbn.getKey();
-
-        boolean isActivityIntent = intent.isActivity();
-        final boolean afterKeyguardGone = isActivityIntent
-                && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
-                mLockscreenUserManager.getCurrentUserId());
-        final boolean wasOccluded = mIsOccluded;
-        dismissKeyguardThenExecute(() -> {
-            // TODO: Some of this code may be able to move to NotificationEntryManager.
-            if (mHeadsUpManager != null && mHeadsUpManager.isAlerting(notificationKey)) {
-                // Release the HUN notification to the shade.
-
-                if (isPresenterFullyCollapsed()) {
-                    HeadsUpUtil.setIsClickedHeadsUpNotification(row, true);
-                }
-                //
-                // In most cases, when FLAG_AUTO_CANCEL is set, the notification will
-                // become canceled shortly by NoMan, but we can't assume that.
-                mHeadsUpManager.removeNotification(sbn.getKey(),
-                        true /* releaseImmediately */);
-            }
-            StatusBarNotification parentToCancel = null;
-            if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) {
-                StatusBarNotification summarySbn =
-                        mGroupManager.getLogicalGroupSummary(sbn).getStatusBarNotification();
-                if (shouldAutoCancel(summarySbn)) {
-                    parentToCancel = summarySbn;
-                }
-            }
-            final StatusBarNotification parentToCancelFinal = parentToCancel;
-            final Runnable runnable = () -> {
-                try {
-                    // The intent we are sending is for the application, which
-                    // won't have permission to immediately start an activity after
-                    // the user switches to home.  We know it is safe to do at this
-                    // point, so make sure new activity switches are now allowed.
-                    ActivityManager.getService().resumeAppSwitches();
-                } catch (RemoteException e) {
-                }
-                int launchResult = ActivityManager.START_CANCELED;
-                if (intent != null) {
-                    // If we are launching a work activity and require to launch
-                    // separate work challenge, we defer the activity action and cancel
-                    // notification until work challenge is unlocked.
-                    if (isActivityIntent) {
-                        final int userId = intent.getCreatorUserHandle().getIdentifier();
-                        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
-                                && mKeyguardManager.isDeviceLocked(userId)) {
-                            // TODO(b/28935539): should allow certain activities to
-                            // bypass work challenge
-                            if (startWorkChallengeIfNecessary(userId, intent.getIntentSender(),
-                                    notificationKey)) {
-                                // Show work challenge, do not run PendingIntent and
-                                // remove notification
-                                collapseOnMainThread();
-                                return;
-                            }
-                        }
-                    }
-                    Intent fillInIntent = null;
-                    Entry entry = row.getEntry();
-                    CharSequence remoteInputText = null;
-                    if (!TextUtils.isEmpty(entry.remoteInputText)) {
-                        remoteInputText = entry.remoteInputText;
-                    }
-                    if (!TextUtils.isEmpty(remoteInputText)
-                            && !controller.isSpinning(entry.key)) {
-                        fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT,
-                                remoteInputText.toString());
-                    }
-                    RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(
-                            row, wasOccluded);
-                    try {
-                        if (adapter != null) {
-                            ActivityTaskManager.getService()
-                                    .registerRemoteAnimationForNextActivityStart(
-                                            intent.getCreatorPackage(), adapter);
-                        }
-                        launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
-                                null, null, getActivityOptions(adapter));
-                        mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
-                    } catch (RemoteException | PendingIntent.CanceledException e) {
-                        // the stack trace isn't very helpful here.
-                        // Just log the exception message.
-                        Log.w(TAG, "Sending contentIntent failed: " + e);
-
-                        // TODO: Dismiss Keyguard.
-                    }
-                    if (isActivityIntent) {
-                        mAssistManager.hideAssist();
-                    }
-                }
-                if (shouldCollapse()) {
-                    collapseOnMainThread();
-                }
-
-                final int count =
-                        mEntryManager.getNotificationData().getActiveNotifications().size();
-                final int rank = mEntryManager.getNotificationData().getRank(notificationKey);
-                final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey,
-                        rank, count, true);
-                try {
-                    mBarService.onNotificationClick(notificationKey, nv);
-                } catch (RemoteException ex) {
-                    // system process is dead if we're here.
-                }
-                if (parentToCancelFinal != null) {
-                    removeNotification(parentToCancelFinal);
-                }
-                if (shouldAutoCancel(sbn)
-                        || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
-                                notificationKey)) {
-                    // Automatically remove all notifications that we may have kept around longer
-                    removeNotification(sbn);
-                }
-            };
-
-            if (mStatusBarKeyguardViewManager.isShowing()
-                    && mStatusBarKeyguardViewManager.isOccluded()) {
-                mStatusBarKeyguardViewManager.addAfterKeyguardGoneRunnable(runnable);
-                collapsePanel(true /* animate */);
-            } else {
-                new Thread(runnable).start();
-            }
-
-            return !mNotificationPanel.isFullyCollapsed();
-        }, afterKeyguardGone);
-    }
-
-    private void collapseOnMainThread() {
-        if (Looper.getMainLooper().isCurrentThread()) {
-            collapsePanel();
-        } else {
-            Dependency.get(Dependency.MAIN_HANDLER).post(this::collapsePanel);
-        }
-    }
-
-    private boolean shouldCollapse() {
-        return mState != StatusBarState.SHADE || !mActivityLaunchAnimator.isAnimationPending();
-    }
-
     public void collapsePanel(boolean animate) {
         if (animate) {
-            collapsePanel();
-        } else if (!isPresenterFullyCollapsed()) {
+            boolean willCollapse = collapsePanel();
+            if (!willCollapse) {
+                runPostCollapseRunnables();
+            }
+        } else if (!mPresenter.isPresenterFullyCollapsed()) {
             instantCollapseNotificationPanel();
             visibilityChanged(false);
         } else {
@@ -4887,7 +4153,8 @@
         }
     }
 
-    private boolean collapsePanel() {
+    @Override
+    public boolean collapsePanel() {
         if (!mNotificationPanel.isFullyCollapsed()) {
             // close the shade if it was open
             animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */,
@@ -4900,59 +4167,8 @@
         }
     }
 
-    private void removeNotification(StatusBarNotification notification) {
-        // We have to post it to the UI thread for synchronization
-        mHandler.post(() -> {
-            Runnable removeRunnable =
-                    () -> mEntryManager.performRemoveNotification(notification);
-            if (isCollapsing()) {
-                // To avoid lags we're only performing the remove
-                // after the shade was collapsed
-                addPostCollapseAction(removeRunnable);
-            } else {
-                removeRunnable.run();
-            }
-        });
-    }
-
     protected NotificationListener mNotificationListener;
 
-    @Override  // NotificationData.Environment
-    public boolean isNotificationForCurrentProfiles(StatusBarNotification n) {
-        final int notificationUserId = n.getUserId();
-        if (DEBUG && MULTIUSER_DEBUG) {
-            Log.v(TAG, String.format("%s: current userid: %d, notification userid: %d", n,
-                    mLockscreenUserManager.getCurrentUserId(), notificationUserId));
-        }
-        return mLockscreenUserManager.isCurrentProfile(notificationUserId);
-    }
-
-    @Override
-    public NotificationGroupManager getGroupManager() {
-        return mGroupManager;
-    }
-
-    @Override
-    public void startNotificationGutsIntent(final Intent intent, final int appUid,
-            ExpandableNotificationRow row) {
-        dismissKeyguardThenExecute(() -> {
-            AsyncTask.execute(() -> {
-                int launchResult = TaskStackBuilder.create(mContext)
-                        .addNextIntentWithParentStack(intent)
-                        .startActivities(getActivityOptions(
-                                mActivityLaunchAnimator.getLaunchAnimation(row, mIsOccluded)),
-                                new UserHandle(UserHandle.getUserId(appUid)));
-                mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */);
-                if (shouldCollapse()) {
-                    // Putting it back on the main thread, since we're touching views
-                    mStatusBarWindow.post(() -> animateCollapsePanels(
-                            CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */));
-                }
-            });
-            return true;
-        }, false /* afterKeyguardGone */);
-    }
-
     public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
         if (snoozeOption.getSnoozeCriterion() != null) {
             mNotificationListener.snoozeNotification(sbn.getKey(),
@@ -5013,7 +4229,7 @@
             // Immediately update the icon hidden state, since that should only apply if we're
             // staying fullscreen.
             mWereIconsJustHidden = false;
-            recomputeDisableFlags(true);
+            mCommandQueue.recomputeDisableFlags(true);
         }
         updateHideIconsForBouncer(true /* animate */);
     }
@@ -5026,24 +4242,6 @@
         KeyboardShortcuts.dismiss();
     }
 
-    @Override  // NotificationData.Environment
-    public boolean shouldHideNotifications(int userId) {
-        return mLockscreenUserManager.shouldHideNotifications(userId);
-    }
-
-    @Override // NotificationDate.Environment
-    public boolean shouldHideNotifications(String key) {
-        return mLockscreenUserManager.shouldHideNotifications(key);
-    }
-
-    /**
-     * Returns true if we're on a secure lockscreen.
-     */
-    @Override  // NotificationData.Environment
-    public boolean isSecurelyLocked(int userId) {
-        return mLockscreenUserManager.isLockscreenPublicMode(userId);
-    }
-
     /**
      * Called when the notification panel layouts
      */
@@ -5055,8 +4253,8 @@
         if (mState == StatusBarState.KEYGUARD) {
             // Since the number of notifications is determined based on the height of the view, we
             // need to update them.
-            int maxBefore = getMaxNotificationsWhileLocked(false /* recompute */);
-            int maxNotifications = getMaxNotificationsWhileLocked(true /* recompute */);
+            int maxBefore = mPresenter.getMaxNotificationsWhileLocked(false /* recompute */);
+            int maxNotifications = mPresenter.getMaxNotificationsWhileLocked(true /* recompute */);
             if (maxBefore != maxNotifications) {
                 mViewHierarchyManager.updateRowStates();
             }
@@ -5064,7 +4262,7 @@
     }
 
     public void startPendingIntentDismissingKeyguard(final PendingIntent intent) {
-        if (!isDeviceProvisioned()) return;
+        if (!mDeviceProvisionedController.isDeviceProvisioned()) return;
 
         final boolean afterKeyguardGone = intent.isActivity()
                 && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
@@ -5098,18 +4296,7 @@
         }, afterKeyguardGone);
     }
 
-    private boolean shouldAutoCancel(StatusBarNotification sbn) {
-        int flags = sbn.getNotification().flags;
-        if ((flags & Notification.FLAG_AUTO_CANCEL) != Notification.FLAG_AUTO_CANCEL) {
-            return false;
-        }
-        if ((flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
-            return false;
-        }
-        return true;
-    }
-
-    protected Bundle getActivityOptions(@Nullable RemoteAnimationAdapter animationAdapter) {
+    public static Bundle getActivityOptions(@Nullable RemoteAnimationAdapter animationAdapter) {
         ActivityOptions options;
         if (animationAdapter != null) {
             options = ActivityOptions.makeRemoteAnimation(animationAdapter);
@@ -5226,29 +4413,4 @@
     public NotificationGutsManager getGutsManager() {
         return mGutsManager;
     }
-
-    @Override
-    public boolean isPresenterLocked() {
-        return mState == StatusBarState.KEYGUARD;
-    }
-
-    @Override
-    public Handler getHandler() {
-        return mHandler;
-    }
-
-    private final NotificationInfo.CheckSaveListener mCheckSaveListener =
-            (Runnable saveImportance, StatusBarNotification sbn) -> {
-                // If the user has security enabled, show challenge if the setting is changed.
-                if (mLockscreenUserManager.isLockscreenPublicMode(sbn.getUser().getIdentifier())
-                        && (mState == StatusBarState.KEYGUARD ||
-                                mState == StatusBarState.SHADE_LOCKED)) {
-                    onLockedNotificationImportanceChange(() -> {
-                        saveImportance.run();
-                        return true;
-                    });
-                } else {
-                    saveImportance.run();
-                }
-            };
 }
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 3db1456..c560301 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -16,7 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
-import static com.android.keyguard.KeyguardHostView.OnDismissAction;
+import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 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 +43,7 @@
 import com.android.systemui.SystemUIFactory;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.KeyguardBouncer.BouncerExpansionCallback;
@@ -84,6 +85,11 @@
         }
 
         @Override
+        public void onStartingToHide() {
+            updateStates();
+        }
+
+        @Override
         public void onFullyHidden() {
             updateStates();
         }
@@ -119,6 +125,8 @@
     // Dismiss action to be launched when we stop dozing or the keyguard is gone.
     private DismissWithActionRequest mPendingWakeupAction;
     private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
+    private final NotificationMediaManager mMediaManager =
+            Dependency.get(NotificationMediaManager.class);
 
     private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
             new KeyguardUpdateMonitorCallback() {
@@ -376,7 +384,7 @@
         boolean isOccluding = !mOccluded && occluded;
         mOccluded = occluded;
         if (mShowing) {
-            mStatusBar.updateMediaMetaData(false, animate && !occluded);
+            mMediaManager.updateMediaMetaData(false, animate && !occluded);
         }
         mStatusBarWindowController.setKeyguardOccluded(occluded);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
new file mode 100644
index 0000000..edfc049
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -0,0 +1,672 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static com.android.systemui.Dependency.MAIN_HANDLER;
+import static com.android.systemui.SysUiServiceProvider.getComponent;
+import static com.android.systemui.statusbar.phone.StatusBar.CLOSE_PANEL_WHEN_EMPTIED;
+import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
+import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG;
+import static com.android.systemui.statusbar.phone.StatusBar.SPEW;
+import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions;
+
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.KeyguardManager;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.app.TaskStackBuilder;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.AsyncTask;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.service.vr.IVrManager;
+import android.service.vr.IVrStateCallbacks;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Slog;
+import android.view.RemoteAnimationAdapter;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
+import android.widget.TextView;
+
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.NotificationVisibility;
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.Dependency;
+import com.android.systemui.InitController;
+import com.android.systemui.R;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager.Callback;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.RemoteInputController;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.AboveShelfObserver;
+import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.notification.NotificationData.Entry;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
+import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.policy.HeadsUpUtil;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
+import com.android.systemui.statusbar.policy.PreviewInflater;
+
+public class StatusBarNotificationPresenter implements NotificationPresenter {
+
+    private final LockscreenGestureLogger mLockscreenGestureLogger =
+            Dependency.get(LockscreenGestureLogger.class);
+
+    private static final String TAG = "StatusBarNotificationPresenter";
+
+    private final ShadeController mShadeController = Dependency.get(ShadeController.class);
+    private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
+    private final AssistManager mAssistManager = Dependency.get(AssistManager.class);
+    private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
+    private final NotificationViewHierarchyManager mViewHierarchyManager =
+            Dependency.get(NotificationViewHierarchyManager.class);
+    private final NotificationLockscreenUserManager mLockscreenUserManager =
+            Dependency.get(NotificationLockscreenUserManager.class);
+    private final StatusBarStateController mStatusBarStateController =
+            Dependency.get(StatusBarStateController.class);
+    private final NotificationEntryManager mEntryManager =
+            Dependency.get(NotificationEntryManager.class);
+    private final NotificationMediaManager mMediaManager =
+            Dependency.get(NotificationMediaManager.class);
+    private final NotificationRemoteInputManager mRemoteInputManager =
+            Dependency.get(NotificationRemoteInputManager.class);
+    private final NotificationGroupManager mGroupManager =
+            Dependency.get(NotificationGroupManager.class);
+    private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback =
+            (StatusBarRemoteInputCallback) Dependency.get(Callback.class);
+    protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
+
+    private final NotificationPanelView mNotificationPanel;
+    private final HeadsUpManagerPhone mHeadsUpManager;
+    private final AboveShelfObserver mAboveShelfObserver;
+    private final DozeScrimController mDozeScrimController;
+    private final ScrimController mScrimController;
+    private final Context mContext;
+    private final CommandQueue mCommandQueue;
+
+    private final AccessibilityManager mAccessibilityManager;
+    private final LockPatternUtils mLockPatternUtils;
+    private final KeyguardManager mKeyguardManager;
+    private final ActivityLaunchAnimator mActivityLaunchAnimator;
+    private final int mMaxAllowedKeyguardNotifications;
+    private final IStatusBarService mBarService;
+    private boolean mReinflateNotificationsOnUserSwitched;
+    private final UnlockMethodCache mUnlockMethodCache;
+    private TextView mNotificationPanelDebugText;
+
+    protected boolean mVrMode;
+    private int mMaxKeyguardNotifications;
+    private boolean mIsCollapsingToShowActivityOverLockscreen;
+
+    public StatusBarNotificationPresenter(Context context, NotificationPanelView panel,
+            HeadsUpManagerPhone headsUp, StatusBarWindowView statusBarWindow,
+            ViewGroup stackScroller, DozeScrimController dozeScrimController,
+            ScrimController scrimController,
+            ActivityLaunchAnimator.Callback launchAnimatorCallback) {
+        mContext = context;
+        mNotificationPanel = panel;
+        mHeadsUpManager = headsUp;
+        mCommandQueue = getComponent(context, CommandQueue.class);
+        mAboveShelfObserver = new AboveShelfObserver(stackScroller);
+        mAboveShelfObserver.setListener(statusBarWindow.findViewById(
+                R.id.notification_container_parent));
+        mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+        mDozeScrimController = dozeScrimController;
+        mScrimController = scrimController;
+        mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
+        mLockPatternUtils = new LockPatternUtils(context);
+        mKeyguardManager = context.getSystemService(KeyguardManager.class);
+        mMaxAllowedKeyguardNotifications = context.getResources().getInteger(
+                R.integer.keyguard_max_notification_count);
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+        mActivityLaunchAnimator = new ActivityLaunchAnimator(statusBarWindow,
+                launchAnimatorCallback,
+                mNotificationPanel,
+                (NotificationListContainer) stackScroller);
+
+        if (MULTIUSER_DEBUG) {
+            mNotificationPanelDebugText = mNotificationPanel.findViewById(R.id.header_debug_info);
+            mNotificationPanelDebugText.setVisibility(View.VISIBLE);
+        }
+
+        IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
+                Context.VR_SERVICE));
+        if (vrManager != null) {
+            try {
+                vrManager.registerListener(mVrStateCallbacks);
+            } catch (RemoteException e) {
+                Slog.e(TAG, "Failed to register VR mode state listener: " + e);
+            }
+        }
+        mRemoteInputManager.setUpWithPresenter(this,
+                Dependency.get(NotificationRemoteInputManager.Callback.class),
+                mNotificationPanel.createRemoteInputDelegate());
+        mRemoteInputManager.getController().addCallback(
+                Dependency.get(StatusBarWindowController.class));
+
+        NotificationListContainer notifListContainer = (NotificationListContainer) stackScroller;
+        Dependency.get(InitController.class).addPostInitTask(() -> {
+            mViewHierarchyManager.setUpWithPresenter(this, notifListContainer);
+            mEntryManager.setUpWithPresenter(this, notifListContainer, this, mHeadsUpManager);
+            mLockscreenUserManager.setUpWithPresenter(this);
+            mMediaManager.setUpWithPresenter(this);
+            Dependency.get(NotificationGutsManager.class).setUpWithPresenter(this,
+                    notifListContainer, mCheckSaveListener, mOnSettingsClickListener);
+
+            onUserSwitched(mLockscreenUserManager.getCurrentUserId());
+        });
+    }
+
+    public void onDensityOrFontScaleChanged() {
+        if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
+            mEntryManager.updateNotificationsOnDensityOrFontScaleChanged();
+        } else {
+            mReinflateNotificationsOnUserSwitched = true;
+        }
+    }
+
+    @Override
+    public ActivityLaunchAnimator getActivityLaunchAnimator() {
+        return mActivityLaunchAnimator;
+    }
+
+    @Override
+    public boolean isCollapsing() {
+        return mNotificationPanel.isCollapsing()
+                || mActivityLaunchAnimator.isAnimationPending()
+                || mActivityLaunchAnimator.isAnimationRunning();
+    }
+
+    @Override
+    public boolean isCollapsingToShowActivityOverLockscreen() {
+        return mIsCollapsingToShowActivityOverLockscreen;
+    }
+
+    @Override
+    public void onPerformRemoveNotification(StatusBarNotification n) {
+        if (mNotificationPanel.hasPulsingNotifications() &&
+                    !mAmbientPulseManager.hasNotifications()) {
+            // We were showing a pulse for a notification, but no notifications are pulsing anymore.
+            // Finish the pulse.
+            mDozeScrimController.pulseOutNow();
+        }
+    }
+
+    @Override
+    public void updateNotificationViews() {
+        // The function updateRowStates depends on both of these being non-null, so check them here.
+        // We may be called before they are set from DeviceProvisionedController's callback.
+        if (mScrimController == null) return;
+
+        // Do not modify the notifications during collapse.
+        if (isCollapsing()) {
+            mShadeController.addPostCollapseAction(this::updateNotificationViews);
+            return;
+        }
+
+        mViewHierarchyManager.updateNotificationViews();
+
+        mNotificationPanel.updateNotificationViews();
+    }
+
+    @Override
+    public void onNotificationAdded(Entry shadeEntry) {
+        // Recalculate the position of the sliding windows and the titles.
+        mShadeController.updateAreThereNotifications();
+    }
+
+    @Override
+    public void onNotificationUpdated(StatusBarNotification notification) {
+        mShadeController.updateAreThereNotifications();
+    }
+
+    @Override
+    public void onNotificationRemoved(String key, StatusBarNotification old) {
+        if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
+
+        if (old != null) {
+            if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
+                    && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
+                if (mStatusBarStateController.getState() == StatusBarState.SHADE) {
+                    mCommandQueue.animateCollapsePanels();
+                } else if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
+                        && !isCollapsing()) {
+                    mShadeController.goToKeyguard();
+                }
+            }
+        }
+        mShadeController.updateAreThereNotifications();
+    }
+
+    public boolean hasActiveNotifications() {
+        return !mEntryManager.getNotificationData().getActiveNotifications().isEmpty();
+    }
+
+    @Override
+    public boolean canHeadsUp(Entry entry, StatusBarNotification sbn) {
+        if (mShadeController.isDozing()) {
+            return false;
+        }
+
+        if (mShadeController.isOccluded()) {
+            boolean devicePublic = mLockscreenUserManager.
+                    isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
+            boolean userPublic = devicePublic
+                    || mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
+            boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
+            if (userPublic && needsRedaction) {
+                return false;
+            }
+        }
+
+        if (!mCommandQueue.panelsEnabled()) {
+            if (DEBUG) {
+                Log.d(TAG, "No heads up: disabled panel : " + sbn.getKey());
+            }
+            return false;
+        }
+
+        if (sbn.getNotification().fullScreenIntent != null) {
+            if (mAccessibilityManager.isTouchExplorationEnabled()) {
+                if (DEBUG) Log.d(TAG, "No heads up: accessible fullscreen: " + sbn.getKey());
+                return false;
+            } else {
+                // we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
+                return !mKeyguardMonitor.isShowing()
+                        || mShadeController.isOccluded();
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void onUserSwitched(int newUserId) {
+        // Begin old BaseStatusBar.userSwitched
+        mHeadsUpManager.setUser(newUserId);
+        // End old BaseStatusBar.userSwitched
+        if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
+        mCommandQueue.animateCollapsePanels();
+        if (mReinflateNotificationsOnUserSwitched) {
+            mEntryManager.updateNotificationsOnDensityOrFontScaleChanged();
+            mReinflateNotificationsOnUserSwitched = false;
+        }
+        updateNotificationViews();
+        mMediaManager.clearCurrentMediaNotification();
+        mShadeController.setLockscreenUser(newUserId);
+        updateMediaMetaData(true, false);
+    }
+
+    @Override
+    public void onBindRow(Entry entry, PackageManager pmUser,
+            StatusBarNotification sbn, ExpandableNotificationRow row) {
+        row.setAboveShelfChangedListener(mAboveShelfObserver);
+        row.setSecureStateProvider(mUnlockMethodCache::canSkipBouncer);
+    }
+
+    @Override
+    public boolean isPresenterFullyCollapsed() {
+        return mNotificationPanel.isFullyCollapsed();
+    }
+
+    @Override
+    public void onActivated(ActivatableNotificationView view) {
+        onActivated();
+        if (view != null) mNotificationPanel.setActivatedChild(view);
+    }
+
+    public void onActivated() {
+        mLockscreenGestureLogger.write(
+                MetricsEvent.ACTION_LS_NOTE,
+                0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
+        mNotificationPanel.showTransientIndication(R.string.notification_tap_again);
+        ActivatableNotificationView previousView = mNotificationPanel.getActivatedChild();
+        if (previousView != null) {
+            previousView.makeInactive(true /* animate */);
+        }
+    }
+
+    @Override
+    public void onActivationReset(ActivatableNotificationView view) {
+        if (view == mNotificationPanel.getActivatedChild()) {
+            mNotificationPanel.setActivatedChild(null);
+            mShadeController.onActivationReset();
+        }
+    }
+
+    @Override
+    public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
+        mMediaManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation);
+    }
+
+    @Override
+    public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) {
+        RemoteInputController controller = mRemoteInputManager.getController();
+        if (controller.isRemoteInputActive(row.getEntry())
+                && !TextUtils.isEmpty(row.getActiveRemoteInputText())) {
+            // We have an active remote input typed and the user clicked on the notification.
+            // this was probably unintentional, so we're closing the edit text instead.
+            controller.closeRemoteInputs();
+            return;
+        }
+        Notification notification = sbn.getNotification();
+        final PendingIntent intent = notification.contentIntent != null
+                ? notification.contentIntent
+                : notification.fullScreenIntent;
+        final String notificationKey = sbn.getKey();
+
+        boolean isActivityIntent = intent.isActivity();
+        final boolean afterKeyguardGone = isActivityIntent
+                && PreviewInflater.wouldLaunchResolverActivity(mContext, intent.getIntent(),
+                mLockscreenUserManager.getCurrentUserId());
+        final boolean wasOccluded = mShadeController.isOccluded();
+        boolean showOverLockscreen = mKeyguardMonitor.isShowing()
+                && PreviewInflater.wouldShowOverLockscreen(mContext,
+                intent.getIntent(),
+                mLockscreenUserManager.getCurrentUserId());
+        OnDismissAction postKeyguardAction = () -> {
+            // TODO: Some of this code may be able to move to NotificationEntryManager.
+            if (mHeadsUpManager != null && mHeadsUpManager.isAlerting(notificationKey)) {
+                // Release the HUN notification to the shade.
+
+                if (isPresenterFullyCollapsed()) {
+                    HeadsUpUtil.setIsClickedHeadsUpNotification(row, true);
+                }
+                //
+                // In most cases, when FLAG_AUTO_CANCEL is set, the notification will
+                // become canceled shortly by NoMan, but we can't assume that.
+                mHeadsUpManager.removeNotification(sbn.getKey(),
+                        true /* releaseImmediately */);
+            }
+            StatusBarNotification parentToCancel = null;
+            if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) {
+                StatusBarNotification summarySbn =
+                        mGroupManager.getLogicalGroupSummary(sbn).getStatusBarNotification();
+                if (shouldAutoCancel(summarySbn)) {
+                    parentToCancel = summarySbn;
+                }
+            }
+            final StatusBarNotification parentToCancelFinal = parentToCancel;
+            final Runnable runnable = () -> {
+                try {
+                    // The intent we are sending is for the application, which
+                    // won't have permission to immediately start an activity after
+                    // the user switches to home.  We know it is safe to do at this
+                    // point, so make sure new activity switches are now allowed.
+                    ActivityManager.getService().resumeAppSwitches();
+                } catch (RemoteException e) {
+                }
+                int launchResult = ActivityManager.START_CANCELED;
+                if (intent != null) {
+                    // If we are launching a work activity and require to launch
+                    // separate work challenge, we defer the activity action and cancel
+                    // notification until work challenge is unlocked.
+                    if (isActivityIntent) {
+                        final int userId = intent.getCreatorUserHandle().getIdentifier();
+                        if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
+                                && mKeyguardManager.isDeviceLocked(userId)) {
+                            // TODO(b/28935539): should allow certain activities to
+                            // bypass work challenge
+                            if (mStatusBarRemoteInputCallback.startWorkChallengeIfNecessary(userId,
+                                    intent.getIntentSender(), notificationKey)) {
+                                // Show work challenge, do not run PendingIntent and
+                                // remove notification
+                                collapseOnMainThread();
+                                return;
+                            }
+                        }
+                    }
+                    Intent fillInIntent = null;
+                    Entry entry = row.getEntry();
+                    CharSequence remoteInputText = null;
+                    if (!TextUtils.isEmpty(entry.remoteInputText)) {
+                        remoteInputText = entry.remoteInputText;
+                    }
+                    if (!TextUtils.isEmpty(remoteInputText)
+                            && !controller.isSpinning(entry.key)) {
+                        fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT,
+                                remoteInputText.toString());
+                    }
+                    RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(
+                            row, wasOccluded);
+                    try {
+                        if (adapter != null) {
+                            ActivityTaskManager.getService()
+                                    .registerRemoteAnimationForNextActivityStart(
+                                            intent.getCreatorPackage(), adapter);
+                        }
+                        launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
+                                null, null, getActivityOptions(adapter));
+                        mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
+                    } catch (RemoteException | PendingIntent.CanceledException e) {
+                        // the stack trace isn't very helpful here.
+                        // Just log the exception message.
+                        Log.w(TAG, "Sending contentIntent failed: " + e);
+
+                        // TODO: Dismiss Keyguard.
+                    }
+                    if (isActivityIntent) {
+                        mAssistManager.hideAssist();
+                    }
+                }
+                if (shouldCollapse()) {
+                    collapseOnMainThread();
+                }
+
+                final int count =
+                        mEntryManager.getNotificationData().getActiveNotifications().size();
+                final int rank = mEntryManager.getNotificationData().getRank(notificationKey);
+                final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey,
+                        rank, count, true);
+                try {
+                    mBarService.onNotificationClick(notificationKey, nv);
+                } catch (RemoteException ex) {
+                    // system process is dead if we're here.
+                }
+                if (parentToCancelFinal != null) {
+                    removeNotification(parentToCancelFinal);
+                }
+                if (shouldAutoCancel(sbn)
+                        || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
+                                notificationKey)) {
+                    // Automatically remove all notifications that we may have kept around longer
+                    removeNotification(sbn);
+                }
+                mIsCollapsingToShowActivityOverLockscreen = false;
+            };
+
+            if (showOverLockscreen) {
+                mShadeController.addPostCollapseAction(runnable);
+                mShadeController.collapsePanel(true /* animate */);
+            } else if (mKeyguardMonitor.isShowing()
+                    && mShadeController.isOccluded()) {
+                mShadeController.addAfterKeyguardGoneRunnable(runnable);
+                mShadeController.collapsePanel();
+            } else {
+                new Thread(runnable).start();
+            }
+
+            return !mNotificationPanel.isFullyCollapsed();
+        };
+        if (showOverLockscreen) {
+            mIsCollapsingToShowActivityOverLockscreen = true;
+            postKeyguardAction.onDismiss();
+        } else {
+            mActivityStarter.dismissKeyguardThenExecute(
+                    postKeyguardAction, null /* cancel */, afterKeyguardGone);
+        }
+    }
+
+    private void removeNotification(StatusBarNotification notification) {
+        // We have to post it to the UI thread for synchronization
+        Dependency.get(MAIN_HANDLER).post(() -> {
+            Runnable removeRunnable =
+                    () -> mEntryManager.performRemoveNotification(notification);
+            if (isCollapsing()) {
+                // To avoid lags we're only performing the remove
+                // after the shade was collapsed
+                mShadeController.addPostCollapseAction(removeRunnable);
+            } else {
+                removeRunnable.run();
+            }
+        });
+    }
+
+    @Override
+    public void startNotificationGutsIntent(final Intent intent, final int appUid,
+            ExpandableNotificationRow row) {
+        mActivityStarter.dismissKeyguardThenExecute(() -> {
+            AsyncTask.execute(() -> {
+                int launchResult = TaskStackBuilder.create(mContext)
+                        .addNextIntentWithParentStack(intent)
+                        .startActivities(getActivityOptions(
+                                mActivityLaunchAnimator.getLaunchAnimation(
+                                        row, mShadeController.isOccluded())),
+                                new UserHandle(UserHandle.getUserId(appUid)));
+                mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */);
+                if (shouldCollapse()) {
+                    // Putting it back on the main thread, since we're touching views
+                    Dependency.get(MAIN_HANDLER).post(() -> mCommandQueue.animateCollapsePanels(
+                            CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */));
+                }
+            });
+            return true;
+        }, null, false /* afterKeyguardGone */);
+    }
+
+    @Override
+    public int getMaxNotificationsWhileLocked(boolean recompute) {
+        if (recompute) {
+            mMaxKeyguardNotifications = Math.max(1,
+                    mNotificationPanel.computeMaxKeyguardNotifications(
+                            mMaxAllowedKeyguardNotifications));
+            return mMaxKeyguardNotifications;
+        }
+        return mMaxKeyguardNotifications;
+    }
+
+    @Override
+    public void onUpdateRowStates() {
+        mNotificationPanel.onUpdateRowStates();
+    }
+
+    @Override
+    public void onExpandClicked(Entry clickedEntry, boolean nowExpanded) {
+        mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
+        if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD && nowExpanded) {
+            mShadeController.goToLockedShade(clickedEntry.row);
+        }
+    }
+
+    @Override
+    public boolean isDeviceInVrMode() {
+        return mVrMode;
+    }
+
+    @Override
+    public boolean isPresenterLocked() {
+        return mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
+    }
+
+    private void collapseOnMainThread() {
+        if (Looper.getMainLooper().isCurrentThread()) {
+            mShadeController.collapsePanel();
+        } else {
+            Dependency.get(MAIN_HANDLER).post(mShadeController::collapsePanel);
+        }
+    }
+
+    private boolean shouldCollapse() {
+        return mStatusBarStateController.getState() != StatusBarState.SHADE
+                || !mActivityLaunchAnimator.isAnimationPending();
+    }
+
+    private void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {
+        mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+        mActivityStarter.dismissKeyguardThenExecute(dismissAction, null,
+                true /* afterKeyguardGone */);
+    }
+
+    private static boolean shouldAutoCancel(StatusBarNotification sbn) {
+        int flags = sbn.getNotification().flags;
+        if ((flags & Notification.FLAG_AUTO_CANCEL) != Notification.FLAG_AUTO_CANCEL) {
+            return false;
+        }
+        if ((flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+            return false;
+        }
+        return true;
+    }
+
+    private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
+        @Override
+        public void onVrStateChanged(boolean enabled) {
+            mVrMode = enabled;
+        }
+    };
+
+    private final CheckSaveListener mCheckSaveListener = new CheckSaveListener() {
+        @Override
+        public void checkSave(Runnable saveImportance, StatusBarNotification sbn) {
+            int state = mStatusBarStateController.getState();
+            // If the user has security enabled, show challenge if the setting is changed.
+            if (mLockscreenUserManager.isLockscreenPublicMode(sbn.getUser().getIdentifier())
+                    && mKeyguardManager.isKeyguardLocked()) {
+                onLockedNotificationImportanceChange(() -> {
+                    saveImportance.run();
+                    return true;
+                });
+            } else {
+                saveImportance.run();
+            }
+        }
+    };
+
+    private final OnSettingsClickListener mOnSettingsClickListener = new OnSettingsClickListener() {
+        @Override
+        public void onSettingsClick(String key) {
+            try {
+                mBarService.onNotificationSettingsViewed(key);
+            } catch (RemoteException e) {
+                // if we're here we're dead
+            }
+        }
+    };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
new file mode 100644
index 0000000..06f9658
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static android.content.Intent.ACTION_DEVICE_LOCKED_CHANGED;
+
+import static com.android.systemui.SysUiServiceProvider.getComponent;
+import static com.android.systemui.statusbar.NotificationLockscreenUserManager
+        .NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION;
+
+import android.app.ActivityManager;
+import android.app.KeyguardManager;
+import android.app.PendingIntent;
+import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.view.View;
+import android.view.ViewParent;
+import android.view.ViewTreeObserver;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.CommandQueue.Callbacks;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager.Callback;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+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.PreviewInflater;
+
+public class StatusBarRemoteInputCallback implements Callback, Callbacks {
+
+    private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
+    private final StatusBarStateController mStatusBarStateController
+            = Dependency.get(StatusBarStateController.class);
+    private final NotificationLockscreenUserManager mLockscreenUserManager
+            = Dependency.get(NotificationLockscreenUserManager.class);
+    private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
+    private final Context mContext;
+    private View mPendingWorkRemoteInputView;
+    private final StatusBarStateController.StateListener mStateListener = this::setStatusBarState;
+    private View mPendingRemoteInputView;
+    private final ShadeController mShadeController = Dependency.get(ShadeController.class);
+    private KeyguardManager mKeyguardManager;
+    private final CommandQueue mCommandQueue;
+    private int mDisabled2;
+    protected BroadcastReceiver mChallengeReceiver = new ChallengeReceiver();
+
+    public StatusBarRemoteInputCallback(Context context) {
+        mContext = context;
+        mContext.registerReceiverAsUser(mChallengeReceiver, UserHandle.ALL,
+                new IntentFilter(ACTION_DEVICE_LOCKED_CHANGED), null, null);
+        mStatusBarStateController.addListener(mStateListener);
+        mKeyguardManager = context.getSystemService(KeyguardManager.class);
+        mCommandQueue = getComponent(context, CommandQueue.class);
+        mCommandQueue.addCallbacks(this);
+    }
+
+    private void setStatusBarState(int state) {
+        if (state == StatusBarState.SHADE && mStatusBarStateController.leaveOpenOnKeyguardHide()) {
+            if (!mStatusBarStateController.isKeyguardRequested()) {
+                if (mPendingRemoteInputView != null
+                        && mPendingRemoteInputView.isAttachedToWindow()) {
+                    mPendingRemoteInputView.post(mPendingRemoteInputView::callOnClick);
+                }
+                mPendingRemoteInputView = null;
+            }
+        }
+    }
+
+    @Override
+    public void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
+        mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+        mShadeController.showBouncer(true /* scrimmed */);
+        mPendingRemoteInputView = clicked;
+    }
+
+    protected void onWorkChallengeChanged() {
+        if (mPendingWorkRemoteInputView != null
+                && !mLockscreenUserManager.isAnyProfilePublicMode()) {
+            // Expand notification panel and the notification row, then click on remote input view
+            final Runnable clickPendingViewRunnable = () -> {
+                final View pendingWorkRemoteInputView = mPendingWorkRemoteInputView;
+                if (pendingWorkRemoteInputView == null) {
+                    return;
+                }
+
+                // Climb up the hierarchy until we get to the container for this row.
+                ViewParent p = pendingWorkRemoteInputView.getParent();
+                while (!(p instanceof ExpandableNotificationRow)) {
+                    if (p == null) {
+                        return;
+                    }
+                    p = p.getParent();
+                }
+
+                final ExpandableNotificationRow row = (ExpandableNotificationRow) p;
+                ViewParent viewParent = row.getParent();
+                if (viewParent instanceof NotificationStackScrollLayout) {
+                    final NotificationStackScrollLayout scrollLayout =
+                            (NotificationStackScrollLayout) viewParent;
+                    row.makeActionsVisibile();
+                    row.post(() -> {
+                        final Runnable finishScrollingCallback = () -> {
+                            mPendingWorkRemoteInputView.callOnClick();
+                            mPendingWorkRemoteInputView = null;
+                            scrollLayout.setFinishScrollingCallback(null);
+                        };
+                        if (scrollLayout.scrollTo(row)) {
+                            // It scrolls! So call it when it's finished.
+                            scrollLayout.setFinishScrollingCallback(finishScrollingCallback);
+                        } else {
+                            // It does not scroll, so call it now!
+                            finishScrollingCallback.run();
+                        }
+                    });
+                }
+            };
+            mShadeController.postOnShadeExpanded(clickPendingViewRunnable);
+            mShadeController.instantExpandNotificationsPanel();
+        }
+    }
+
+    @Override
+    public void onMakeExpandedVisibleForRemoteInput(ExpandableNotificationRow row,
+            View clickedView) {
+        if (mKeyguardMonitor.isShowing()) {
+            onLockedRemoteInput(row, clickedView);
+        } else {
+            row.setUserExpanded(true);
+            row.getPrivateLayout().setOnExpandedVisibleListener(clickedView::performClick);
+        }
+    }
+
+    @Override
+    public void onLockedWorkRemoteInput(int userId, ExpandableNotificationRow row,
+            View clicked) {
+        // Collapse notification and show work challenge
+        mCommandQueue.animateCollapsePanels();
+        startWorkChallengeIfNecessary(userId, null, null);
+        // Add pending remote input view after starting work challenge, as starting work challenge
+        // will clear all previous pending review view
+        mPendingWorkRemoteInputView = clicked;
+    }
+
+    protected boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender,
+            String notificationKey) {
+        // Clear pending remote view, as we do not want to trigger pending remote input view when
+        // it's called by other code
+        mPendingWorkRemoteInputView = null;
+        // Begin old BaseStatusBar.startWorkChallengeIfNecessary.
+        final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null,
+                null, userId);
+        if (newIntent == null) {
+            return false;
+        }
+        final Intent callBackIntent = new Intent(NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION);
+        callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender);
+        callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey);
+        callBackIntent.setPackage(mContext.getPackageName());
+
+        PendingIntent callBackPendingIntent = PendingIntent.getBroadcast(
+                mContext,
+                0,
+                callBackIntent,
+                PendingIntent.FLAG_CANCEL_CURRENT |
+                        PendingIntent.FLAG_ONE_SHOT |
+                        PendingIntent.FLAG_IMMUTABLE);
+        newIntent.putExtra(
+                Intent.EXTRA_INTENT,
+                callBackPendingIntent.getIntentSender());
+        try {
+            ActivityManager.getService().startConfirmDeviceCredentialIntent(newIntent,
+                    null /*options*/);
+        } catch (RemoteException ex) {
+            // ignore
+        }
+        return true;
+        // End old BaseStatusBar.startWorkChallengeIfNecessary.
+    }
+
+    @Override
+    public boolean shouldHandleRemoteInput(View view, PendingIntent pendingIntent) {
+        // Skip remote input as doing so will expand the notification shade.
+        return (mDisabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) != 0;
+    }
+
+    @Override
+    public boolean handleRemoteViewClick(View view, PendingIntent pendingIntent,
+            Intent fillInIntent, NotificationRemoteInputManager.ClickHandler defaultHandler) {
+        final boolean isActivity = pendingIntent.isActivity();
+        if (isActivity) {
+            final boolean afterKeyguardGone = PreviewInflater.wouldLaunchResolverActivity(
+                    mContext, pendingIntent.getIntent(), mLockscreenUserManager.getCurrentUserId());
+            mActivityStarter.dismissKeyguardThenExecute(() -> {
+                try {
+                    ActivityManager.getService().resumeAppSwitches();
+                } catch (RemoteException e) {
+                }
+
+                boolean handled = defaultHandler.handleClick();
+
+                // close the shade if it was open and maybe wait for activity start.
+                return handled && mShadeController.closeShadeIfOpen();
+            }, null, afterKeyguardGone);
+            return true;
+        } else {
+            return defaultHandler.handleClick();
+        }
+    }
+
+    @Override
+    public void disable(int state1, int state2, boolean animate) {
+        mDisabled2 = state2;
+    }
+
+    protected class ChallengeReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
+            if (Intent.ACTION_DEVICE_LOCKED_CHANGED.equals(action)) {
+                if (userId != mLockscreenUserManager.getCurrentUserId()
+                        && mLockscreenUserManager.isCurrentProfile(userId)) {
+                    onWorkChallengeChanged();
+                }
+            }
+        }
+    };
+}
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 57c7e28..0d37b55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -173,9 +173,9 @@
         }
 
         if (state.dozing) {
-            mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+            mLpChanged.privateFlags |= LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
         } else {
-            mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+            mLpChanged.privateFlags &= ~LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
         }
     }
 
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 45b32c7..ad9b9b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -58,6 +58,7 @@
 import com.android.internal.view.FloatingActionMode;
 import com.android.internal.widget.FloatingToolbar;
 import com.android.systemui.Dependency;
+import com.android.systemui.ExpandHelper;
 import com.android.systemui.R;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.statusbar.DragDownHelper;
@@ -182,6 +183,11 @@
         }
     }
 
+    @VisibleForTesting
+    protected NotificationStackScrollLayout getStackScrollLayout() {
+        return mStackScrollLayout;
+    }
+
     @Override
     public FrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
         return new LayoutParams(getContext(), attrs);
@@ -215,8 +221,11 @@
 
     public void setService(StatusBar service) {
         mService = service;
-        setDragDownHelper(new DragDownHelper(getContext(), this, mStackScrollLayout,
-                mStackScrollLayout));
+        NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+        ExpandHelper.Callback expandHelperCallback = stackScrollLayout.getExpandHelperCallback();
+        DragDownHelper.DragDownCallback dragDownCallback = stackScrollLayout.getDragDownCallback();
+        setDragDownHelper(new DragDownHelper(getContext(), this, expandHelperCallback,
+                dragDownCallback));
     }
 
     @VisibleForTesting
@@ -309,7 +318,7 @@
             }
         }
         if (isDown) {
-            mStackScrollLayout.closeControlsIfOutsideTouch(ev);
+            getStackScrollLayout().closeControlsIfOutsideTouch(ev);
         }
         if (mService.isDozing()) {
             mService.mDozeScrimController.extendPulse();
@@ -331,13 +340,14 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
-        if (mService.isDozing() && !mStackScrollLayout.hasPulsingNotifications()) {
+        NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+        if (mService.isDozing() && !stackScrollLayout.hasPulsingNotifications()) {
             // Capture all touch events in always-on.
             return true;
         }
         boolean intercept = false;
         if (mNotificationPanel.isFullyExpanded()
-                && mStackScrollLayout.getVisibility() == View.VISIBLE
+                && stackScrollLayout.getVisibility() == View.VISIBLE
                 && mStatusBarStateController.getState() == StatusBarState.KEYGUARD
                 && !mService.isBouncerShowing()
                 && !mService.isDozing()) {
@@ -349,7 +359,7 @@
         if (intercept) {
             MotionEvent cancellation = MotionEvent.obtain(ev);
             cancellation.setAction(MotionEvent.ACTION_CANCEL);
-            mStackScrollLayout.onInterceptTouchEvent(cancellation);
+            stackScrollLayout.onInterceptTouchEvent(cancellation);
             mNotificationPanel.onInterceptTouchEvent(cancellation);
             cancellation.recycle();
         }
@@ -391,8 +401,9 @@
     }
 
     public void cancelExpandHelper() {
-        if (mStackScrollLayout != null) {
-            mStackScrollLayout.cancelExpandHelper();
+        NotificationStackScrollLayout stackScrollLayout = getStackScrollLayout();
+        if (stackScrollLayout != null) {
+            stackScrollLayout.cancelExpandHelper();
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
deleted file mode 100644
index aa60ec5..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/TrustDrawable.java
+++ /dev/null
@@ -1,290 +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.systemui.statusbar.phone;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ValueAnimator;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-import android.view.animation.Interpolator;
-
-import com.android.settingslib.Utils;
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
-
-public class TrustDrawable extends Drawable {
-
-    private static final long ENTERING_FROM_UNSET_START_DELAY = 200;
-    private static final long VISIBLE_DURATION = 1000;
-    private static final long EXIT_DURATION = 500;
-    private static final long ENTER_DURATION = 500;
-
-    private static final int ALPHA_VISIBLE_MIN = 0x26;
-    private static final int ALPHA_VISIBLE_MAX = 0x4c;
-
-    private static final int STATE_UNSET = -1;
-    private static final int STATE_GONE = 0;
-    private static final int STATE_ENTERING = 1;
-    private static final int STATE_VISIBLE = 2;
-    private static final int STATE_EXITING = 3;
-
-    private int mAlpha;
-    private boolean mAnimating;
-
-    private int mCurAlpha;
-    private float mCurInnerRadius;
-    private Animator mCurAnimator;
-    private int mState = STATE_UNSET;
-    private Paint mPaint;
-    private boolean mTrustManaged;
-
-    private final float mInnerRadiusVisibleMin;
-    private final float mInnerRadiusVisibleMax;
-    private final float mInnerRadiusExit;
-    private final float mInnerRadiusEnter;
-    private final float mThickness;
-
-    private final Animator mVisibleAnimator;
-
-    public TrustDrawable(Context context) {
-        Resources r = context.getResources();
-        mInnerRadiusVisibleMin = r.getDimension(R.dimen.trust_circle_inner_radius_visible_min);
-        mInnerRadiusVisibleMax = r.getDimension(R.dimen.trust_circle_inner_radius_visible_max);
-        mInnerRadiusExit = r.getDimension(R.dimen.trust_circle_inner_radius_exit);
-        mInnerRadiusEnter = r.getDimension(R.dimen.trust_circle_inner_radius_enter);
-        mThickness = r.getDimension(R.dimen.trust_circle_thickness);
-
-        mCurInnerRadius = mInnerRadiusEnter;
-
-        mVisibleAnimator = makeVisibleAnimator();
-
-        mPaint = new Paint();
-        mPaint.setStyle(Paint.Style.STROKE);
-        mPaint.setColor(Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor));
-        mPaint.setAntiAlias(true);
-        mPaint.setStrokeWidth(mThickness);
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        int newAlpha = (mCurAlpha * mAlpha) / 256;
-        if (newAlpha == 0) {
-            return;
-        }
-        final Rect r = getBounds();
-        mPaint.setAlpha(newAlpha);
-        canvas.drawCircle(r.exactCenterX(), r.exactCenterY(), mCurInnerRadius, mPaint);
-    }
-
-    @Override
-    public void setAlpha(int alpha) {
-        mAlpha = alpha;
-    }
-
-    @Override
-    public int getAlpha() {
-        return mAlpha;
-    }
-
-    @Override
-    public void setColorFilter(ColorFilter colorFilter) {
-        throw new UnsupportedOperationException("not implemented");
-    }
-
-    @Override
-    public int getOpacity() {
-        return PixelFormat.TRANSLUCENT;
-    }
-
-    public void start() {
-        if (!mAnimating) {
-            mAnimating = true;
-            updateState(true);
-            invalidateSelf();
-        }
-    }
-
-    public void stop() {
-        if (mAnimating) {
-            mAnimating = false;
-            if (mCurAnimator != null) {
-                mCurAnimator.cancel();
-                mCurAnimator = null;
-            }
-            mState = STATE_UNSET;
-            mCurAlpha = 0;
-            mCurInnerRadius = mInnerRadiusEnter;
-            invalidateSelf();
-        }
-    }
-
-    public void setTrustManaged(boolean trustManaged) {
-        if (trustManaged == mTrustManaged && mState != STATE_UNSET) return;
-        mTrustManaged = trustManaged;
-        updateState(true);
-    }
-
-    private void updateState(boolean allowTransientState) {
-        if (!mAnimating) {
-            return;
-        }
-
-        int nextState = mState;
-        if (mState == STATE_UNSET) {
-            nextState = mTrustManaged ? STATE_ENTERING : STATE_GONE;
-        } else if (mState == STATE_GONE) {
-            if (mTrustManaged) nextState = STATE_ENTERING;
-        } else if (mState == STATE_ENTERING) {
-            if (!mTrustManaged) nextState = STATE_EXITING;
-        } else if (mState == STATE_VISIBLE) {
-            if (!mTrustManaged) nextState = STATE_EXITING;
-        } else if (mState == STATE_EXITING) {
-            if (mTrustManaged) nextState = STATE_ENTERING;
-        }
-        if (!allowTransientState) {
-            if (nextState == STATE_ENTERING) nextState = STATE_VISIBLE;
-            if (nextState == STATE_EXITING) nextState = STATE_GONE;
-        }
-
-        if (nextState != mState) {
-            if (mCurAnimator != null) {
-                mCurAnimator.cancel();
-                mCurAnimator = null;
-            }
-
-            if (nextState == STATE_GONE) {
-                mCurAlpha = 0;
-                mCurInnerRadius = mInnerRadiusEnter;
-            } else if (nextState == STATE_ENTERING) {
-                mCurAnimator = makeEnterAnimator(mCurInnerRadius, mCurAlpha);
-                if (mState == STATE_UNSET) {
-                    mCurAnimator.setStartDelay(ENTERING_FROM_UNSET_START_DELAY);
-                }
-            } else if (nextState == STATE_VISIBLE) {
-                mCurAlpha = ALPHA_VISIBLE_MAX;
-                mCurInnerRadius = mInnerRadiusVisibleMax;
-                mCurAnimator = mVisibleAnimator;
-            } else if (nextState == STATE_EXITING) {
-                mCurAnimator = makeExitAnimator(mCurInnerRadius, mCurAlpha);
-            }
-
-            mState = nextState;
-            if (mCurAnimator != null) {
-                mCurAnimator.start();
-            }
-            invalidateSelf();
-        }
-    }
-
-    private Animator makeVisibleAnimator() {
-        return makeAnimators(mInnerRadiusVisibleMax, mInnerRadiusVisibleMin,
-                ALPHA_VISIBLE_MAX, ALPHA_VISIBLE_MIN, VISIBLE_DURATION,
-                Interpolators.ACCELERATE_DECELERATE,
-                true /* repeating */, false /* stateUpdateListener */);
-    }
-
-    private Animator makeEnterAnimator(float radius, int alpha) {
-        return makeAnimators(radius, mInnerRadiusVisibleMax,
-                alpha, ALPHA_VISIBLE_MAX, ENTER_DURATION, Interpolators.LINEAR_OUT_SLOW_IN,
-                false /* repeating */, true /* stateUpdateListener */);
-    }
-
-    private Animator makeExitAnimator(float radius, int alpha) {
-        return makeAnimators(radius, mInnerRadiusExit,
-                alpha, 0, EXIT_DURATION, Interpolators.FAST_OUT_SLOW_IN,
-                false /* repeating */, true /* stateUpdateListener */);
-    }
-
-    private Animator makeAnimators(float startRadius, float endRadius,
-            int startAlpha, int endAlpha, long duration, Interpolator interpolator,
-            boolean repeating, boolean stateUpdateListener) {
-        ValueAnimator alphaAnimator = configureAnimator(
-                ValueAnimator.ofInt(startAlpha, endAlpha),
-                duration, mAlphaUpdateListener, interpolator, repeating);
-        ValueAnimator sizeAnimator = configureAnimator(
-                ValueAnimator.ofFloat(startRadius, endRadius),
-                duration, mRadiusUpdateListener, interpolator, repeating);
-
-        AnimatorSet set = new AnimatorSet();
-        set.playTogether(alphaAnimator, sizeAnimator);
-        if (stateUpdateListener) {
-            set.addListener(new StateUpdateAnimatorListener());
-        }
-        return set;
-    }
-
-    private ValueAnimator configureAnimator(ValueAnimator animator, long duration,
-            ValueAnimator.AnimatorUpdateListener updateListener, Interpolator interpolator,
-            boolean repeating) {
-        animator.setDuration(duration);
-        animator.addUpdateListener(updateListener);
-        animator.setInterpolator(interpolator);
-        if (repeating) {
-            animator.setRepeatCount(ValueAnimator.INFINITE);
-            animator.setRepeatMode(ValueAnimator.REVERSE);
-        }
-        return animator;
-    }
-
-    private final ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener =
-            new ValueAnimator.AnimatorUpdateListener() {
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            mCurAlpha = (int) animation.getAnimatedValue();
-            invalidateSelf();
-        }
-    };
-
-    private final ValueAnimator.AnimatorUpdateListener mRadiusUpdateListener =
-            new ValueAnimator.AnimatorUpdateListener() {
-        @Override
-        public void onAnimationUpdate(ValueAnimator animation) {
-            mCurInnerRadius = (float) animation.getAnimatedValue();
-            invalidateSelf();
-        }
-    };
-
-    private class StateUpdateAnimatorListener extends AnimatorListenerAdapter {
-        boolean mCancelled;
-
-        @Override
-        public void onAnimationStart(Animator animation) {
-            mCancelled = false;
-        }
-
-        @Override
-        public void onAnimationCancel(Animator animation) {
-            mCancelled = true;
-        }
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (!mCancelled) {
-                updateState(false);
-            }
-        }
-    }
-}
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 d477587..b4d24d16 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar.policy;
 
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -151,6 +153,7 @@
         for (OnHeadsUpChangedListener listener : mListeners) {
             listener.onHeadsUpStateChanged(entry, false);
         }
+        entry.row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
     }
 
     protected void updatePinnedMode() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
index 8e32a0b..59bd85e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonRipple.java
@@ -27,8 +27,7 @@
 import android.graphics.PixelFormat;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
-import android.os.SystemProperties;
-import android.view.DisplayListCanvas;
+import android.graphics.RecordingCanvas;
 import android.view.RenderNodeAnimator;
 import android.view.View;
 import android.view.ViewConfiguration;
@@ -122,7 +121,7 @@
     public void draw(Canvas canvas) {
         mSupportHardware = canvas.isHardwareAccelerated();
         if (mSupportHardware) {
-            drawHardware((DisplayListCanvas) canvas);
+            drawHardware((RecordingCanvas) canvas);
         } else {
             drawSoftware(canvas);
         }
@@ -147,7 +146,7 @@
         return getBounds().width() > getBounds().height();
     }
 
-    private void drawHardware(DisplayListCanvas c) {
+    private void drawHardware(RecordingCanvas c) {
         if (mDrawingHardwareGlow) {
             c.drawRoundRect(mLeftProp, mTopProp, mRightProp, mBottomProp, mRxProp, mRyProp,
                     mPaintProp);
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 12b6f9d..298a93e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.policy;
 
+import static android.view.Display.INVALID_DISPLAY;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
 import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
 
@@ -33,6 +34,7 @@
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.TypedValue;
+import android.view.Display;
 import android.view.HapticFeedbackConstants;
 import android.view.InputDevice;
 import android.view.KeyCharacterMap;
@@ -307,6 +309,14 @@
                 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
                 flags | KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY,
                 InputDevice.SOURCE_KEYBOARD);
+        //Make KeyEvent work on multi-display environment
+        if (getDisplay() != null) {
+            final int displayId = getDisplay().getDisplayId();
+
+            if (displayId != INVALID_DISPLAY) {
+                ev.setDisplayId(displayId);
+            }
+        }
         InputManager.getInstance().injectInputEvent(ev,
                 InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
     }
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 7b42dd4..aba2377 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
@@ -24,6 +24,7 @@
     boolean isOccluded();
     boolean isKeyguardFadingAway();
     boolean isKeyguardGoingAway();
+    boolean isLaunchTransitionFadingAway();
     long getKeyguardFadingAwayDuration();
     long getKeyguardFadingAwayDelay();
     long calculateGoingToFullShadeDelay();
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 10cb09b..5eb0fb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
@@ -28,7 +28,7 @@
 public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback
         implements KeyguardMonitor {
 
-    private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
+    private final ArrayList<Callback> mCallbacks = new ArrayList<>();
 
     private final Context mContext;
     private final CurrentUserTracker mUserTracker;
@@ -45,6 +45,7 @@
     private long mKeyguardFadingAwayDelay;
     private long mKeyguardFadingAwayDuration;
     private boolean mKeyguardGoingAway;
+    private boolean mLaunchTransitionFadingAway;
 
     public KeyguardMonitorImpl(Context context) {
         mContext = context;
@@ -123,7 +124,7 @@
 
     private void notifyKeyguardChanged() {
         // Copy the list to allow removal during callback.
-        new ArrayList<Callback>(mCallbacks).forEach(Callback::onKeyguardShowingChanged);
+        new ArrayList<>(mCallbacks).forEach(Callback::onKeyguardShowingChanged);
     }
 
     public void notifyKeyguardFadingAway(long delay, long fadeoutDuration) {
@@ -165,4 +166,13 @@
     public void notifyKeyguardGoingAway(boolean keyguardGoingAway) {
         mKeyguardGoingAway = keyguardGoingAway;
     }
+
+    public void setLaunchTransitionFadingAway(boolean fadingAway) {
+        mLaunchTransitionFadingAway = fadingAway;
+    }
+
+    @Override
+    public boolean isLaunchTransitionFadingAway() {
+        return mLaunchTransitionFadingAway;
+    }
 }
\ No newline at end of file
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 24a28cb..70a3589 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -461,6 +461,8 @@
                     MobileSignalController controller = mMobileSignalControllers.valueAt(i);
                     controller.handleBroadcast(intent);
                 }
+                mConfig = Config.readConfig(mContext);
+                mReceiverHandler.post(this::handleConfigurationChanged);
                 break;
             case TelephonyIntents.ACTION_SIM_STATE_CHANGED:
                 // Avoid rebroadcast because SysUI is direct boot aware.
@@ -1042,18 +1044,23 @@
             config.showAtLeast3G = res.getBoolean(R.bool.config_showMin3G);
             config.alwaysShowCdmaRssi =
                     res.getBoolean(com.android.internal.R.bool.config_alwaysUseCdmaRssi);
-            config.show4gForLte = res.getBoolean(R.bool.config_show4GForLTE);
             config.hspaDataDistinguishable =
                     res.getBoolean(R.bool.config_hspa_data_distinguishable);
-            config.hideLtePlus = res.getBoolean(R.bool.config_hideLtePlus);
             config.inflateSignalStrengths = res.getBoolean(R.bool.config_inflateSignalStrength);
 
             CarrierConfigManager configMgr = (CarrierConfigManager)
                     context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-            PersistableBundle b = configMgr.getConfig();
+            // Handle specific carrier config values for the default data SIM
+            int defaultDataSubId = SubscriptionManager.from(context)
+                    .getDefaultDataSubscriptionId();
+            PersistableBundle b = configMgr.getConfigForSubId(defaultDataSubId);
             if (b != null) {
                 config.alwaysShowDataRatIcon = b.getBoolean(
                         CarrierConfigManager.KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL);
+                config.show4gForLte = b.getBoolean(
+                        CarrierConfigManager.KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL);
+                config.hideLtePlus = b.getBoolean(
+                        CarrierConfigManager.KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL);
             }
             return config;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
index 687b83a..92034b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PreviewInflater.java
@@ -146,6 +146,14 @@
                 == null;
     }
 
+    public static boolean wouldShowOverLockscreen(Context ctx, Intent intent, int currentUserId) {
+        ActivityInfo targetActivityInfo = getTargetActivityInfo(ctx, intent, currentUserId,
+                false /* onlyDirectBootAware */);
+        return targetActivityInfo != null
+                && (targetActivityInfo.flags & (ActivityInfo.FLAG_SHOW_WHEN_LOCKED
+                | ActivityInfo.FLAG_SHOW_FOR_ALL_USERS)) > 0;
+    }
+
     /**
      * @param onlyDirectBootAware a boolean indicating whether the matched activity packages must
      *                            be direct boot aware when in direct boot mode if false, all
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 dd03162..aa4782f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -28,7 +28,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ContrastColorUtil;
-import com.android.keyguard.KeyguardHostView.OnDismissAction;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.NotificationData;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
index 71414a2..0826054 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/PluginFragment.java
@@ -25,15 +25,13 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.provider.Settings;
-import androidx.preference.PreferenceFragment;
-import androidx.preference.SwitchPreference;
-import androidx.preference.PreferenceScreen;
-import androidx.preference.PreferenceViewHolder;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.view.View;
 
 import com.android.systemui.R;
+import com.android.systemui.plugins.PluginEnablerImpl;
+import com.android.systemui.shared.plugins.PluginEnabler;
 import com.android.systemui.shared.plugins.PluginInstanceManager;
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.plugins.PluginPrefs;
@@ -41,12 +39,18 @@
 import java.util.List;
 import java.util.Set;
 
+import androidx.preference.PreferenceFragment;
+import androidx.preference.PreferenceScreen;
+import androidx.preference.PreferenceViewHolder;
+import androidx.preference.SwitchPreference;
+
 public class PluginFragment extends PreferenceFragment {
 
     public static final String ACTION_PLUGIN_SETTINGS
             = "com.android.systemui.action.PLUGIN_SETTINGS";
 
     private PluginPrefs mPluginPrefs;
+    private PluginEnabler mPluginEnabler;
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -68,6 +72,7 @@
 
     @Override
     public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
+        mPluginEnabler = new PluginEnablerImpl(getContext());
         loadPrefs();
     }
 
@@ -98,7 +103,7 @@
                 PackageManager.MATCH_DISABLED_COMPONENTS | PackageManager.GET_SERVICES);
         apps.forEach(app -> {
             if (!plugins.containsKey(app.packageName)) return;
-            SwitchPreference pref = new PluginPreference(prefContext, app);
+            SwitchPreference pref = new PluginPreference(prefContext, app, mPluginEnabler);
             pref.setSummary("Plugins: " + toString(plugins.get(app.packageName)));
             screen.addPreference(pref);
         });
@@ -139,15 +144,16 @@
     private static class PluginPreference extends SwitchPreference {
         private final boolean mHasSettings;
         private final PackageInfo mInfo;
-        private final PackageManager mPm;
+        private final PluginEnabler mPluginEnabler;
 
-        public PluginPreference(Context prefContext, PackageInfo info) {
+        public PluginPreference(Context prefContext, PackageInfo info, PluginEnabler pluginEnabler) {
             super(prefContext);
-            mPm = prefContext.getPackageManager();
-            mHasSettings = mPm.resolveActivity(new Intent(ACTION_PLUGIN_SETTINGS)
+            PackageManager pm = prefContext.getPackageManager();
+            mHasSettings = pm.resolveActivity(new Intent(ACTION_PLUGIN_SETTINGS)
                     .setPackage(info.packageName), 0) != null;
             mInfo = info;
-            setTitle(info.applicationInfo.loadLabel(mPm));
+            mPluginEnabler = pluginEnabler;
+            setTitle(info.applicationInfo.loadLabel(pm));
             setChecked(isPluginEnabled());
             setWidgetLayoutResource(R.layout.tuner_widget_settings_switch);
         }
@@ -156,8 +162,7 @@
             for (int i = 0; i < mInfo.services.length; i++) {
                 ComponentName componentName = new ComponentName(mInfo.packageName,
                         mInfo.services[i].name);
-                if (mPm.getComponentEnabledSetting(componentName)
-                        == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+                if (!mPluginEnabler.isEnabled(componentName)) {
                     return false;
                 }
             }
@@ -165,17 +170,14 @@
         }
 
         @Override
-        protected boolean persistBoolean(boolean value) {
-            final int desiredState = value ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-                    : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+        protected boolean persistBoolean(boolean isEnabled) {
             boolean shouldSendBroadcast = false;
             for (int i = 0; i < mInfo.services.length; i++) {
                 ComponentName componentName = new ComponentName(mInfo.packageName,
                         mInfo.services[i].name);
 
-                if (mPm.getComponentEnabledSetting(componentName) != desiredState) {
-                    mPm.setComponentEnabledSetting(componentName, desiredState,
-                            PackageManager.DONT_KILL_APP);
+                if (mPluginEnabler.isEnabled(componentName) != isEnabled) {
+                    mPluginEnabler.setEnabled(componentName, isEnabled);
                     shouldSendBroadcast = true;
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
index af99236..e85dee8 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunablePadding.java
@@ -51,7 +51,9 @@
     public void onTuningChanged(String key, String newValue) {
         int dimen = mDefaultSize;
         if (newValue != null) {
-            dimen = (int) (Integer.parseInt(newValue) * mDensity);
+            try {
+                dimen = (int) (Integer.parseInt(newValue) * mDensity);
+            } catch (NumberFormatException ex) {}
         }
         int left = mView.isLayoutRtl() ? FLAG_END : FLAG_START;
         int right = mView.isLayoutRtl() ? FLAG_START : FLAG_END;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
index 66d5ee1..4102e63 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbDebuggingActivity.java
@@ -54,7 +54,7 @@
     @Override
     public void onCreate(Bundle icicle) {
         Window window = getWindow();
-        window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+        window.addSystemFlags(WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
         window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
 
         super.onCreate(icicle);
diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
index 5790ba3..0dd8937 100644
--- a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
+++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.util;
 
+import android.content.Context;
 import android.hardware.HardwareBuffer;
 import android.hardware.Sensor;
 import android.hardware.SensorAdditionalInfo;
@@ -30,7 +31,11 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.Preconditions;
+import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.SensorManagerPlugin;
+import com.android.systemui.shared.plugins.PluginManager;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -40,7 +45,8 @@
  * without blocking. Note that this means registering listeners now always appears successful even
  * if it is not.
  */
-public class AsyncSensorManager extends SensorManager {
+public class AsyncSensorManager extends SensorManager
+        implements PluginListener<SensorManagerPlugin> {
 
     private static final String TAG = "AsyncSensorManager";
 
@@ -48,12 +54,15 @@
     private final List<Sensor> mSensorCache;
     private final HandlerThread mHandlerThread = new HandlerThread("async_sensor");
     @VisibleForTesting final Handler mHandler;
+    private final List<SensorManagerPlugin> mPlugins;
 
-    public AsyncSensorManager(SensorManager inner) {
+    public AsyncSensorManager(SensorManager inner, PluginManager pluginManager) {
         mInner = inner;
         mHandlerThread.start();
         mHandler = new Handler(mHandlerThread.getLooper());
         mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL);
+        mPlugins = new ArrayList<>();
+        pluginManager.addPluginListener(this, SensorManagerPlugin.class, true /* allowMultiple */);
     }
 
     @Override
@@ -63,7 +72,7 @@
 
     @Override
     protected List<Sensor> getFullDynamicSensorList() {
-        return mInner.getDynamicSensorList(Sensor.TYPE_ALL);
+        return mInner.getSensorList(Sensor.TYPE_ALL);
     }
 
     @Override
@@ -132,6 +141,32 @@
         return true;
     }
 
+    /**
+     * Requests for all sensors that match the given type from all plugins.
+     * @param sensor
+     * @param listener
+     */
+    public void requestPluginTriggerSensor(SensorManagerPlugin.Sensor sensor,
+            SensorManagerPlugin.TriggerEventListener listener) {
+        if (mPlugins.isEmpty()) {
+            Log.w(TAG, "No plugins registered");
+        }
+        mHandler.post(() -> {
+            for (int i = 0; i < mPlugins.size(); i++) {
+                mPlugins.get(i).registerTriggerEvent(sensor, listener);
+            }
+        });
+    }
+
+    public void cancelPluginTriggerSensor(SensorManagerPlugin.Sensor sensor,
+            SensorManagerPlugin.TriggerEventListener listener) {
+        mHandler.post(() -> {
+            for (int i = 0; i < mPlugins.size(); i++) {
+                mPlugins.get(i).unregisterTriggerEvent(sensor, listener);
+            }
+        });
+    }
+
     @Override
     protected boolean initDataInjectionImpl(boolean enable) {
         throw new UnsupportedOperationException("not implemented");
@@ -159,4 +194,14 @@
             }
         });
     }
+
+    @Override
+    public void onPluginConnected(SensorManagerPlugin plugin, Context pluginContext) {
+        mPlugins.add(plugin);
+    }
+
+    @Override
+    public void onPluginDisconnected(SensorManagerPlugin plugin) {
+        mPlugins.remove(plugin);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index a97effd..e20e267 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -956,11 +956,13 @@
                 changed |= onVolumeChangedW(stream, 0);
             } else if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) {
                 final int rm = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1);
+                if (isInitialStickyBroadcast()) mState.ringerModeExternal = rm;
                 if (D.BUG) Log.d(TAG, "onReceive RINGER_MODE_CHANGED_ACTION rm="
                         + Util.ringerModeToString(rm));
                 changed = updateRingerModeExternalW(rm);
             } else if (action.equals(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION)) {
                 final int rm = intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1);
+                if (isInitialStickyBroadcast()) mState.ringerModeInternal = rm;
                 if (D.BUG) Log.d(TAG, "onReceive INTERNAL_RINGER_MODE_CHANGED_ACTION rm="
                         + Util.ringerModeToString(rm));
                 changed = updateRingerModeInternalW(rm);
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 4810b0b..798f8bc 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -135,10 +135,6 @@
     private final AccessibilityManagerWrapper mAccessibilityMgr;
     private final Object mSafetyWarningLock = new Object();
     private final Accessibility mAccessibility = new Accessibility();
-    private ColorStateList mActiveTint;
-    private int mActiveAlpha;
-    private ColorStateList mInactiveTint;
-    private int mInactiveAlpha;
 
     private boolean mShowing;
     private boolean mShowA11yStream;
@@ -238,11 +234,6 @@
         lp.gravity = ((FrameLayout.LayoutParams) mDialogView.getLayoutParams()).gravity;
         mWindow.setAttributes(lp);
 
-        mActiveTint = Utils.getColorAccent(mContext);
-        mActiveAlpha = Color.alpha(mActiveTint.getDefaultColor());
-        mInactiveTint = Utils.getColorAttr(mContext, android.R.attr.colorForeground);
-        mInactiveAlpha = getAlphaAttr(android.R.attr.secondaryContentAlpha);
-
         mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows);
         mRinger = mDialog.findViewById(R.id.ringer);
         if (mRinger != null) {
@@ -556,14 +547,15 @@
         mHandler.removeMessages(H.SHOW);
         mHandler.removeMessages(H.DISMISS);
         rescheduleTimeoutH();
-        mShowing = true;
 
         if (mConfigChanged) {
-            initDialog();
+            initDialog(); // resets mShowing to false
             mConfigurableTexts.update();
             mConfigChanged = false;
         }
+
         initSettingsH();
+        mShowing = true;
         mDialog.show();
         Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
         mController.notifyVisible(true);
@@ -941,8 +933,12 @@
             row.slider.requestFocus();
         }
         boolean useActiveColoring = isActive && row.slider.isEnabled();
-        final ColorStateList tint = useActiveColoring ? mActiveTint : mInactiveTint;
-        final int alpha = useActiveColoring ? mActiveAlpha : mInactiveAlpha;
+        final ColorStateList tint = useActiveColoring
+                ? Utils.getColorAccent(mContext)
+                : Utils.getColorAttr(mContext, android.R.attr.colorForeground);
+        final int alpha = useActiveColoring
+                ? Color.alpha(tint.getDefaultColor())
+                : getAlphaAttr(android.R.attr.secondaryContentAlpha);
         if (tint == row.cachedTint) return;
         row.slider.setProgressTintList(tint);
         row.slider.setThumbTintList(tint);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java
index 3f85c9d..a69fd56 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardHostViewTest.java
@@ -23,6 +23,7 @@
 import android.testing.TestableLooper;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -44,7 +45,7 @@
     @Test
     public void testHasDismissActions() {
         Assert.assertFalse("Action not set yet", mKeyguardHostView.hasDismissActions());
-        mKeyguardHostView.setOnDismissAction(mock(KeyguardHostView.OnDismissAction.class),
+        mKeyguardHostView.setOnDismissAction(mock(OnDismissAction.class),
                 null /* cancelAction */);
         Assert.assertTrue("Action should exist", mKeyguardHostView.hasDismissActions());
     }
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt
index cfe9818..ab3a3e1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewTest.kt
@@ -46,9 +46,9 @@
     }
 
     @Test
-    fun onResume_clearsTextField() {
+    fun onPause_clearsTextField() {
         mSecurityMessage.setMessage("an old message")
-        mKeyguardPatternView.onResume(KeyguardSecurityView.SCREEN_ON)
+        mKeyguardPatternView.onPause()
         assertThat(mSecurityMessage.text).isEqualTo("")
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index cc96917..b84f85b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -16,6 +16,7 @@
 
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
 
+import  static com.android.systemui.ScreenDecorations.rectsToRegion;
 import static com.android.systemui.tuner.TunablePadding.FLAG_END;
 import static com.android.systemui.tuner.TunablePadding.FLAG_START;
 
@@ -35,6 +36,7 @@
 
 import android.app.Fragment;
 import android.content.res.Configuration;
+import android.graphics.Rect;
 import android.os.Handler;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
@@ -58,6 +60,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Collections;
+
 @RunWithLooper
 @RunWith(AndroidTestingRunner.class)
 @SmallTest
@@ -240,4 +244,11 @@
         mScreenDecorations.onConfigurationChanged(null);
         assertEquals(mScreenDecorations.mRoundedDefault, 5);
     }
+
+    @Test
+    public void testBoundingRectsToRegion() throws Exception {
+        Rect rect = new Rect(1, 2, 3, 4);
+        assertThat(rectsToRegion(Collections.singletonList(rect)).getBounds(), is(rect));
+    }
+
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
index a35ca46..a58bc85 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java
@@ -58,7 +58,6 @@
 
     @Before
     public void SysuiSetup() throws Exception {
-        mContext.setTheme(R.style.Theme_SystemUI);
         SystemUIFactory.createFromConfig(mContext);
 
         mRealInstrumentation = InstrumentationRegistry.getInstrumentation();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
index 9d3124e..e811270 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestableContext.java
@@ -25,10 +25,12 @@
 
     public SysuiTestableContext(Context base) {
         super(base);
+        setTheme(R.style.Theme_SystemUI);
     }
 
     public SysuiTestableContext(Context base, LeakCheck check) {
         super(base, check);
+        setTheme(R.style.Theme_SystemUI);
     }
 
     public ArrayMap<Class<?>, Object> getComponents() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java
index 5c83d99..0c8d137 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/TestableDependency.java
@@ -25,6 +25,9 @@
     private final ArraySet<Object> mInstantiatedObjects = new ArraySet<>();
 
     public TestableDependency(Context context) {
+        if (context instanceof SysuiTestableContext) {
+            mComponents = ((SysuiTestableContext) context).getComponents();
+        }
         mContext = context;
         if (SystemUIFactory.getInstance() == null) {
             SystemUIFactory.createFromConfig(context);
@@ -43,6 +46,9 @@
     }
 
     public <T> void injectTestDependency(Class<T> key, T obj) {
+        if (mInstantiatedObjects.contains(key)) {
+            throw new IllegalStateException(key + " was already initialized");
+        }
         mObjs.put(key, obj);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
index bb67d6e..45342d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationTest.java
@@ -47,10 +47,10 @@
             return;
         }
 
-        Settings.Secure.putString(mContext.getContentResolver(), Settings.Secure.DOZE_ALWAYS_ON,
-                null);
+        Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                Settings.Secure.DOZE_ALWAYS_ON, null, UserHandle.USER_CURRENT);
         boolean defaultValue = mContext.getResources()
                 .getBoolean(com.android.internal.R.bool.config_dozeAlwaysOnEnabled);
-        assertEquals(mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT), defaultValue);
+        assertEquals(defaultValue, mDozeConfig.alwaysOnEnabled(UserHandle.USER_CURRENT));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
index 2398fd3..6abd407 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeHostFake.java
@@ -115,6 +115,11 @@
     }
 
     @Override
+    public void setPassiveInterrupt(boolean lightInterrupt) {
+
+    }
+
+    @Override
     public void setDozeScreenBrightness(int value) {
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
new file mode 100644
index 0000000..d9412ec
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CastTileTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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.qs.tiles;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.service.quicksettings.Tile;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.statusbar.policy.CastController;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
+import com.android.systemui.statusbar.policy.NetworkController;
+
+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.util.HashSet;
+import java.util.Set;
+
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+@SmallTest
+public class CastTileTest extends SysuiTestCase {
+
+    @Mock
+    private CastController mController;
+    @Mock
+    private ActivityStarter mActivityStarter;
+    @Mock
+    private KeyguardMonitor mKeyguard;
+    @Mock
+    private NetworkController mNetworkController;
+    @Mock
+    private QSTileHost mHost;
+    @Mock
+    NetworkController.SignalCallback mCallback;
+
+    private TestableLooper mTestableLooper;
+    private CastTile mCastTile;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mTestableLooper = TestableLooper.get(this);
+
+        mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
+        mController = mDependency.injectMockDependency(CastController.class);
+        mActivityStarter = mDependency.injectMockDependency(ActivityStarter.class);
+        mKeyguard = mDependency.injectMockDependency(KeyguardMonitor.class);
+        mNetworkController = mDependency.injectMockDependency(NetworkController.class);
+
+        when(mHost.getContext()).thenReturn(mContext);
+
+        mCastTile = new CastTile(mHost);
+
+        // We are not setting the mocks to listening, so we trigger a first refresh state to
+        // set the initial state
+        mCastTile.refreshState();
+
+        mCastTile.handleSetListening(true);
+        ArgumentCaptor<NetworkController.SignalCallback> signalCallbackArgumentCaptor =
+                ArgumentCaptor.forClass(NetworkController.SignalCallback.class);
+        verify(mNetworkController).addCallback(signalCallbackArgumentCaptor.capture());
+        mCallback = signalCallbackArgumentCaptor.getValue();
+
+    }
+
+    @Test
+    public void testStateUnavailable_wifiDisabled() {
+        NetworkController.IconState qsIcon =
+                new NetworkController.IconState(false, 0, "");
+        mCallback.setWifiIndicators(false, mock(NetworkController.IconState.class),
+                qsIcon, false,false, "",
+                false, "");
+        mTestableLooper.processAllMessages();
+
+        assertEquals(Tile.STATE_UNAVAILABLE, mCastTile.getState().state);
+    }
+
+    @Test
+    public void testStateUnavailable_wifiNotConnected() {
+        NetworkController.IconState qsIcon =
+                new NetworkController.IconState(false, 0, "");
+        mCallback.setWifiIndicators(true, mock(NetworkController.IconState.class),
+                qsIcon, false,false, "",
+                false, "");
+        mTestableLooper.processAllMessages();
+
+        assertEquals(Tile.STATE_UNAVAILABLE, mCastTile.getState().state);
+    }
+
+    @Test
+    public void testStateActive_wifiEnabledAndCasting() {
+        CastController.CastDevice device = mock(CastController.CastDevice.class);
+        device.state = CastController.CastDevice.STATE_CONNECTED;
+        Set<CastController.CastDevice> devices = new HashSet<>();
+        devices.add(device);
+        when(mController.getCastDevices()).thenReturn(devices);
+
+        NetworkController.IconState qsIcon =
+                new NetworkController.IconState(true, 0, "");
+        mCallback.setWifiIndicators(true, mock(NetworkController.IconState.class),
+                qsIcon, false,false, "",
+                false, "");
+        mTestableLooper.processAllMessages();
+
+        assertEquals(Tile.STATE_ACTIVE, mCastTile.getState().state);
+    }
+
+    @Test
+    public void testStateInactive_wifiEnabledNotCasting() {
+        NetworkController.IconState qsIcon =
+                new NetworkController.IconState(true, 0, "");
+        mCallback.setWifiIndicators(true, mock(NetworkController.IconState.class),
+                qsIcon, false,false, "",
+                false, "");
+        mTestableLooper.processAllMessages();
+
+        assertEquals(Tile.STATE_INACTIVE, mCastTile.getState().state);
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceManagerTest.java
index 6d1ff8c..5bf6040 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceManagerTest.java
@@ -28,6 +28,7 @@
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginEnablerImpl;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.shared.plugins.PluginInstanceManager.PluginInfo;
 import com.android.systemui.shared.plugins.VersionInfo.InvalidVersionException;
@@ -88,6 +89,7 @@
         mMockManager = mock(PluginManagerImpl.class);
         when(mMockManager.getClassLoader(any(), any()))
                 .thenReturn(getClass().getClassLoader());
+        when(mMockManager.getPluginEnabler()).thenReturn(new PluginEnablerImpl(mMockPm));
         mMockVersionInfo = mock(VersionInfo.class);
         mPluginInstanceManager = new PluginInstanceManager(mContextWrapper, mMockPm, "myAction",
                 mMockListener, true, mHandlerThread.getLooper(), mMockVersionInfo,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
index 3c70205..ff1bc8ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginManagerTest.java
@@ -37,6 +37,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginEnablerImpl;
 import com.android.systemui.plugins.PluginInitializerImpl;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -62,6 +63,7 @@
     private PluginInstanceManager mMockPluginInstance;
     private PluginManagerImpl mPluginManager;
     private PluginListener mMockListener;
+    private PackageManager mMockPackageManager;
 
     private UncaughtExceptionHandler mRealExceptionHandler;
     private UncaughtExceptionHandler mMockExceptionHandler;
@@ -79,12 +81,18 @@
                 Mockito.anyBoolean(), Mockito.any(), Mockito.any(), Mockito.any()))
                 .thenReturn(mMockPluginInstance);
 
+        mMockPackageManager = mock(PackageManager.class);
         mPluginManager = new PluginManagerImpl(getContext(), mMockFactory, true,
                 mMockExceptionHandler, new PluginInitializerImpl() {
             @Override
             public String[] getWhitelistedPlugins(Context context) {
                 return new String[0];
             }
+
+            @Override
+            public PluginEnabler getPluginEnabler(Context context) {
+                return new PluginEnablerImpl(mMockPackageManager);
+            }
         });
         resetExceptionHandler();
         mMockListener = mock(PluginListener.class);
@@ -182,9 +190,8 @@
     @Test
     public void testDisableIntent() {
         NotificationManager nm = mock(NotificationManager.class);
-        PackageManager pm = mock(PackageManager.class);
         mContext.addMockSystemService(Context.NOTIFICATION_SERVICE, nm);
-        mContext.setMockPackageManager(pm);
+        mContext.setMockPackageManager(mMockPackageManager);
 
         ComponentName testComponent = new ComponentName(getContext().getPackageName(),
                 PluginManagerTest.class.getName());
@@ -192,7 +199,7 @@
         intent.setData(Uri.parse("package://" + testComponent.flattenToString()));
         mPluginManager.onReceive(mContext, intent);
         verify(nm).cancel(eq(testComponent.getClassName()), eq(SystemMessage.NOTE_PLUGIN));
-        verify(pm).setComponentEnabledSetting(eq(testComponent),
+        verify(mMockPackageManager).setComponentEnabledSetting(eq(testComponent),
                 eq(PackageManager.COMPONENT_ENABLED_STATE_DISABLED),
                 eq(PackageManager.DONT_KILL_APP));
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
index a02ef98..8ae3cd8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/CommandQueueTest.java
@@ -84,7 +84,7 @@
     public void testCollapsePanels() {
         mCommandQueue.animateCollapsePanels();
         waitForIdleSync();
-        verify(mCallbacks).animateCollapsePanels(eq(0));
+        verify(mCallbacks).animateCollapsePanels(eq(0), eq(false));
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index bdd05c7..aae6d93 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
@@ -28,6 +30,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.app.trust.TrustManager;
 import android.content.Context;
+import android.graphics.Color;
 import android.hardware.fingerprint.FingerprintManager;
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
@@ -45,6 +48,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -54,9 +59,13 @@
 
     private String mDisclosureWithOrganization;
 
-    private DevicePolicyManager mDevicePolicyManager = mock(DevicePolicyManager.class);
-    private ViewGroup mIndicationArea = mock(ViewGroup.class);
-    private KeyguardIndicationTextView mDisclosure = mock(KeyguardIndicationTextView.class);
+    @Mock
+    private DevicePolicyManager mDevicePolicyManager;
+    @Mock
+    private ViewGroup mIndicationArea;
+    @Mock
+    private KeyguardIndicationTextView mDisclosure;
+    private KeyguardIndicationTextView mTextView;
 
     private KeyguardIndicationController mController;
     private WakeLockFake mWakeLock;
@@ -64,7 +73,9 @@
 
     @Before
     public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
         mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        mTextView = new KeyguardIndicationTextView(mContext);
 
         mContext.addMockSystemService(Context.DEVICE_POLICY_SERVICE, mDevicePolicyManager);
         mContext.addMockSystemService(Context.TRUST_SERVICE, mock(TrustManager.class));
@@ -74,6 +85,7 @@
 
         when(mIndicationArea.findViewById(R.id.keyguard_indication_enterprise_disclosure))
                 .thenReturn(mDisclosure);
+        when(mIndicationArea.findViewById(R.id.keyguard_indication_text)).thenReturn(mTextView);
 
         mWakeLock = new WakeLockFake();
     }
@@ -189,4 +201,17 @@
         });
         assertFalse("WakeLock expected: RELEASED, was: HELD", held[0]);
     }
+
+    @Test
+    public void transientIndication_visibleWhenDozing() {
+        createController();
+
+        mController.setVisible(true);
+        mController.showTransientIndication("Test");
+        mController.setDozing(true);
+
+        assertThat(mTextView.getText()).isEqualTo("Test");
+        assertThat(mTextView.getCurrentTextColor()).isEqualTo(Color.WHITE);
+        assertThat(mTextView.getAlpha()).isEqualTo(1f);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
index da59450..2e280d3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NonPhoneDependencyTest.java
@@ -17,26 +17,27 @@
 package com.android.systemui.statusbar;
 
 import static org.junit.Assert.assertFalse;
-import static org.mockito.Mockito.when;
 
 import android.os.Handler;
-import android.os.Looper;
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
 import com.android.systemui.Dependency;
+import com.android.systemui.InitController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
-import com.android.systemui.statusbar.notification.row.NotificationInfo;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
+import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.phone.StatusBarWindowController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -49,25 +50,29 @@
  */
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@Ignore("b/118400112")
 public class NonPhoneDependencyTest extends SysuiTestCase {
     @Mock private NotificationPresenter mPresenter;
     @Mock private NotificationListContainer mListContainer;
     @Mock private NotificationEntryManager.Callback mEntryManagerCallback;
     @Mock private HeadsUpManager mHeadsUpManager;
     @Mock private RemoteInputController.Delegate mDelegate;
-    @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener;
-    @Mock private NotificationGutsManager.OnSettingsClickListener mOnClickListener;
     @Mock private NotificationRemoteInputManager.Callback mRemoteInputManagerCallback;
+    @Mock private CheckSaveListener mCheckSaveListener;
+    @Mock private OnSettingsClickListener mOnSettingsClickListener;
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
+        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
+               new Handler(TestableLooper.get(this).getLooper()));
     }
 
     @Test
+    @Ignore("b/118400112")
     public void testNotificationManagementCodeHasNoDependencyOnStatusBarWindowManager() {
+        mDependency.injectMockDependency(ShadeController.class);
         NotificationEntryManager entryManager = Dependency.get(NotificationEntryManager.class);
         NotificationGutsManager gutsManager = Dependency.get(NotificationGutsManager.class);
         NotificationListener notificationListener = Dependency.get(NotificationListener.class);
@@ -79,24 +84,20 @@
                 Dependency.get(NotificationLockscreenUserManager.class);
         NotificationViewHierarchyManager viewHierarchyManager =
                 Dependency.get(NotificationViewHierarchyManager.class);
-        NotificationGroupManager groupManager = Dependency.get(NotificationGroupManager.class);
-
-        when(mPresenter.getNotificationLockscreenUserManager()).thenReturn(lockscreenUserManager);
-        when(mPresenter.getGroupManager()).thenReturn(groupManager);
-
+        Dependency.get(InitController.class).executePostInitTasks();
         entryManager.setUpWithPresenter(mPresenter, mListContainer, mEntryManagerCallback,
                 mHeadsUpManager);
-        groupManager.setHeadsUpManager(mHeadsUpManager);
-        gutsManager.setUpWithPresenter(mPresenter, mListContainer, mCheckSaveListener,
-                mOnClickListener);
-        notificationLogger.setUpWithEntryManager(entryManager, mListContainer);
-        mediaManager.setUpWithPresenter(mPresenter, entryManager);
-        remoteInputManager.setUpWithPresenter(mPresenter, entryManager, mRemoteInputManagerCallback,
+        gutsManager.setUpWithPresenter(mPresenter, mListContainer,
+                mCheckSaveListener, mOnSettingsClickListener);
+        notificationLogger.setUpWithContainer(mListContainer);
+        mediaManager.setUpWithPresenter(mPresenter);
+        remoteInputManager.setUpWithPresenter(mPresenter, mRemoteInputManagerCallback,
                 mDelegate);
-        lockscreenUserManager.setUpWithPresenter(mPresenter, entryManager);
-        viewHierarchyManager.setUpWithPresenter(mPresenter, entryManager, mListContainer);
-        notificationListener.setUpWithPresenter(mPresenter, entryManager);
+        lockscreenUserManager.setUpWithPresenter(mPresenter);
+        viewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
+        notificationListener.setUpWithPresenter(mPresenter);
 
+        TestableLooper.get(this).processAllMessages();
         assertFalse(mDependency.hasInstantiatedDependency(StatusBarWindowController.class));
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
index 7b0c0a0..63ececb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java
@@ -32,6 +32,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -44,7 +45,7 @@
 
 @SmallTest
 @RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
 public class NotificationListenerTest extends SysuiTestCase {
     private static final String TEST_PACKAGE_NAME = "test";
     private static final int TEST_UID = 0;
@@ -66,15 +67,16 @@
         mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
         mDependency.injectTestDependency(NotificationRemoteInputManager.class,
                 mRemoteInputManager);
+        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
+                new Handler(TestableLooper.get(this).getLooper()));
 
-        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
         when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
 
         mListener = new NotificationListener(mContext);
         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID, 0,
                 new Notification(), UserHandle.CURRENT, null, 0);
 
-        mListener.setUpWithPresenter(mPresenter, mEntryManager);
+        mListener.setUpWithPresenter(mPresenter);
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 515c109..f168a49 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -40,7 +40,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
-import android.util.Log;
+import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -83,12 +83,12 @@
 
         when(mUserManager.getProfiles(mCurrentUserId)).thenReturn(Lists.newArrayList(
                 new UserInfo(mCurrentUserId, "", 0), new UserInfo(mCurrentUserId + 1, "", 0)));
-        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
         when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
+        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
+                Handler.createAsync(Looper.myLooper()));
 
         mLockscreenUserManager = new TestNotificationLockscreenUserManager(mContext);
-        mLockscreenUserManager.setUpWithPresenter(mPresenter, mEntryManager);
-        mLockscreenUserManager.setKeyguardViewManager(mKeyguardViewManager);
+        mLockscreenUserManager.setUpWithPresenter(mPresenter);
     }
 
     @Test
@@ -137,15 +137,6 @@
     }
 
     @Test
-    public void testActionDeviceLockedChangedWithDifferentUserIdCallsOnWorkChallengeChanged() {
-        Intent intent = new Intent()
-                .setAction(ACTION_DEVICE_LOCKED_CHANGED)
-                .putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId + 1);
-        mLockscreenUserManager.getAllUsersReceiverForTest().onReceive(mContext, intent);
-        verify(mPresenter, times(1)).onWorkChallengeChanged();
-    }
-
-    @Test
     public void testActionUserSwitchedCallsOnUserSwitched() {
         Intent intent = new Intent()
                 .setAction(ACTION_USER_SWITCHED)
@@ -161,15 +152,11 @@
         assertTrue(mLockscreenUserManager.isLockscreenPublicMode(mCurrentUserId));
     }
 
-    private class TestNotificationLockscreenUserManager extends NotificationLockscreenUserManager {
+    private class TestNotificationLockscreenUserManager extends NotificationLockscreenUserManagerImpl {
         public TestNotificationLockscreenUserManager(Context context) {
             super(context);
         }
 
-        public BroadcastReceiver getAllUsersReceiverForTest() {
-            return mAllUsersReceiver;
-        }
-
         public BroadcastReceiver getBaseBroadcastReceiverForTest() {
             return mBaseBroadcastReceiver;
         }
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 8a59e96..d409e2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -20,6 +20,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.SysuiTestCase;
 
 import com.android.systemui.statusbar.notification.NotificationData;
@@ -70,8 +71,8 @@
         mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
                 mLockscreenUserManager);
         mDependency.injectTestDependency(SmartReplyController.class, mSmartReplyController);
-
-        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
+        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
+                Handler.createAsync(Looper.myLooper()));
 
         mRemoteInputManager = new TestableNotificationRemoteInputManager(mContext);
         mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
@@ -79,7 +80,7 @@
         mEntry = new NotificationData.Entry(mSbn);
         mEntry.row = mRow;
 
-        mRemoteInputManager.setUpWithPresenterForTest(mPresenter, mEntryManager, mCallback,
+        mRemoteInputManager.setUpWithPresenterForTest(mPresenter, mCallback,
                 mDelegate, mController);
         for (NotificationLifetimeExtender extender : mRemoteInputManager.getLifetimeExtenders()) {
             extender.setCallback(
@@ -201,11 +202,10 @@
         }
 
         public void setUpWithPresenterForTest(NotificationPresenter presenter,
-                NotificationEntryManager entryManager,
                 Callback callback,
                 RemoteInputController.Delegate delegate,
                 RemoteInputController controller) {
-            super.setUpWithPresenter(presenter, entryManager, callback, delegate);
+            super.setUpWithPresenter(presenter, callback, delegate);
             mRemoteInputController = controller;
         }
 
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 edf29ac..aca1f90 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -31,9 +31,9 @@
 import android.view.LayoutInflater;
 import android.widget.RemoteViews;
 
-import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.row.NotificationInflater.InflationFlag;
 import com.android.systemui.statusbar.notification.row.NotificationInflaterTest;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
@@ -67,16 +67,50 @@
         mGroupManager.setHeadsUpManager(mHeadsUpManager);
     }
 
+    /**
+     * Creates a generic row.
+     *
+     * @return a generic row with no special properties.
+     * @throws Exception
+     */
     public ExpandableNotificationRow createRow() throws Exception {
         return createRow(PKG, UID);
     }
 
+    /**
+     * Create a row with the package and user id specified.
+     *
+     * @param pkg package
+     * @param uid user id
+     * @return a row with a notification using the package and user id
+     * @throws Exception
+     */
     public ExpandableNotificationRow createRow(String pkg, int uid) throws Exception {
         return createRow(pkg, uid, false /* isGroupSummary */, null /* groupKey */);
     }
 
+    /**
+     * Creates a row based off the notification given.
+     *
+     * @param notification the notification
+     * @return a row built off the notification
+     * @throws Exception
+     */
     public ExpandableNotificationRow createRow(Notification notification) throws Exception {
-        return generateRow(notification, PKG, UID, false /* isGroupRow */);
+        return generateRow(notification, PKG, UID, 0 /* extraInflationFlags */);
+    }
+
+    /**
+     * Create a row with the specified content views inflated in addition to the default.
+     *
+     * @param extraInflationFlags the flags corresponding to the additional content views that
+     *                            should be inflated
+     * @return a row with the specified content views inflated in addition to the default
+     * @throws Exception
+     */
+    public ExpandableNotificationRow createRow(@InflationFlag int extraInflationFlags)
+            throws Exception {
+        return generateRow(createNotification(), PKG, UID, extraInflationFlags);
     }
 
     /**
@@ -122,34 +156,53 @@
             boolean isGroupSummary,
             @Nullable String groupKey)
             throws Exception {
+        Notification notif = createNotification(isGroupSummary, groupKey);
+        return generateRow(notif, pkg, uid, 0 /* inflationFlags */);
+    }
+
+    /**
+     * Creates a generic notification.
+     *
+     * @return a notification with no special properties
+     */
+    private Notification createNotification() {
+        return createNotification(false /* isGroupSummary */, null /* groupKey */);
+    }
+
+    /**
+     * Creates a notification with the given parameters.
+     *
+     * @param isGroupSummary whether the notification is a group summary
+     * @param groupKey the group key for the notification group used across notifications
+     * @return a notification that is in the group specified or standalone if unspecified
+     */
+    private Notification createNotification(boolean isGroupSummary,
+            @Nullable String groupKey) {
         Notification publicVersion = new Notification.Builder(mContext).setSmallIcon(
                 R.drawable.ic_person)
                 .setCustomContentView(new RemoteViews(mContext.getPackageName(),
                         R.layout.custom_view_dark))
                 .build();
-        Notification.Builder notificationBuilder =
-                new Notification.Builder(mContext, "channelId")
-                        .setSmallIcon(R.drawable.ic_person)
-                        .setContentTitle("Title")
-                        .setContentText("Text")
-                        .setPublicVersion(publicVersion);
-
-        // Group notification setup
+        Notification.Builder notificationBuilder = new Notification.Builder(mContext, "channelId")
+                .setSmallIcon(R.drawable.ic_person)
+                .setContentTitle("Title")
+                .setContentText("Text")
+                .setPublicVersion(publicVersion)
+                .setStyle(new Notification.BigTextStyle().bigText("Big Text"));
         if (isGroupSummary) {
             notificationBuilder.setGroupSummary(true);
         }
         if (!TextUtils.isEmpty(groupKey)) {
             notificationBuilder.setGroup(groupKey);
         }
-
-        return generateRow(notificationBuilder.build(), pkg, uid, !TextUtils.isEmpty(groupKey));
+        return notificationBuilder.build();
     }
 
     private ExpandableNotificationRow generateRow(
             Notification notification,
             String pkg,
             int uid,
-            boolean isGroupRow)
+            @InflationFlag int extraInflationFlags)
             throws Exception {
         LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
                 mContext.LAYOUT_INFLATER_SERVICE);
@@ -179,8 +232,10 @@
         entry.channel = new NotificationChannel(
                 notification.getChannelId(), notification.getChannelId(), IMPORTANCE_DEFAULT);
         entry.channel.setBlockableSystem(true);
+        row.setEntry(entry);
+        row.getNotificationInflater().addInflationFlags(extraInflationFlags);
         NotificationInflaterTest.runThenWaitForInflation(
-                () -> row.updateNotification(entry),
+                () -> row.inflateViews(),
                 row.getNotificationInflater());
 
         // This would be done as part of onAsyncInflationFinished, but we skip large amounts of
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 15c18e9..602e613 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -32,6 +32,8 @@
 import android.view.ViewGroup;
 import android.widget.LinearLayout;
 
+import com.android.systemui.Dependency;
+import com.android.systemui.InitController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.notification.NotificationData;
@@ -42,6 +44,7 @@
 import com.android.systemui.statusbar.notification.row.ExpandableView;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ShadeController;
 
 import com.google.android.collect.Lists;
 
@@ -67,6 +70,7 @@
     @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
     @Mock private NotificationGroupManager mGroupManager;
     @Mock private VisualStabilityManager mVisualStabilityManager;
+    @Mock private ShadeController mShadeController;
 
     private NotificationViewHierarchyManager mViewHierarchyManager;
     private NotificationTestHelper mHelper = new NotificationTestHelper(mContext);;
@@ -79,11 +83,13 @@
                 mLockscreenUserManager);
         mDependency.injectTestDependency(NotificationGroupManager.class, mGroupManager);
         mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
+        mDependency.injectTestDependency(ShadeController.class, mShadeController);
 
         when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);
 
         mViewHierarchyManager = new NotificationViewHierarchyManager(mContext);
-        mViewHierarchyManager.setUpWithPresenter(mPresenter, mEntryManager, mListContainer);
+        Dependency.get(InitController.class).executePostInitTasks();
+        mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
     }
 
     private NotificationData.Entry createEntry() throws Exception {
@@ -218,6 +224,9 @@
         public void generateChildOrderChangedEvent() {}
 
         @Override
+        public void onReset(ExpandableView view) {}
+
+        @Override
         public int getContainerChildCount() {
             return mRows.size();
         }
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 17daaac..1d977d8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -80,8 +80,7 @@
                 mSmartReplyController);
 
         mRemoteInputManager = new NotificationRemoteInputManager(mContext);
-        mRemoteInputManager.setUpWithPresenter(mPresenter, mNotificationEntryManager, mCallback,
-                mDelegate);
+        mRemoteInputManager.setUpWithPresenter(mPresenter, mCallback, mDelegate);
         mNotification = new Notification.Builder(mContext, "")
                 .setSmallIcon(R.drawable.ic_person)
                 .setContentTitle("Title")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AppOpsListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AppOpsListenerTest.java
index 78be783..b405a5c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AppOpsListenerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/AppOpsListenerTest.java
@@ -18,7 +18,6 @@
 
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.app.AppOpsManager;
 import android.os.Handler;
@@ -27,6 +26,7 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.ForegroundServiceController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationPresenter;
@@ -59,14 +59,15 @@
         mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
         mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
         getContext().addMockSystemService(AppOpsManager.class, mAppOpsManager);
-        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
+        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
+                Handler.createAsync(Looper.myLooper()));
 
         mListener = new AppOpsListener(mContext);
     }
 
     @Test
     public void testOnlyListenForFewOps() {
-        mListener.setUpWithPresenter(mPresenter, mEntryManager);
+        mListener.setUpWithPresenter(mPresenter);
 
         verify(mAppOpsManager, times(1)).startWatchingActive(AppOpsListener.OPS, mListener);
     }
@@ -79,7 +80,7 @@
 
     @Test
     public void testInformEntryMgrOnAppOpsChange() {
-        mListener.setUpWithPresenter(mPresenter, mEntryManager);
+        mListener.setUpWithPresenter(mPresenter);
         mListener.onOpActiveChanged(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
         TestableLooper.get(this).processAllMessages();
@@ -89,7 +90,7 @@
 
     @Test
     public void testInformFscOnAppOpsChange() {
-        mListener.setUpWithPresenter(mPresenter, mEntryManager);
+        mListener.setUpWithPresenter(mPresenter);
         mListener.onOpActiveChanged(
                 AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true);
         TestableLooper.get(this).processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
index de5a8a0..459dc5d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationDataTest.java
@@ -55,13 +55,16 @@
 import android.testing.TestableLooper.RunWithLooper;
 import android.util.ArraySet;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.ForegroundServiceController;
+import com.android.systemui.InitController;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ShadeController;
 
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -87,7 +90,7 @@
     @Mock
     ForegroundServiceController mFsc;
     @Mock
-    NotificationData.Environment mEnvironment;
+    NotificationData.KeyguardEnvironment mEnvironment;
 
     private final IPackageManager mMockPackageManager = mock(IPackageManager.class);
     private NotificationData mNotificationData;
@@ -108,10 +111,14 @@
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
 
         mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
-        when(mEnvironment.getGroupManager()).thenReturn(new NotificationGroupManager());
+        mDependency.injectTestDependency(NotificationGroupManager.class,
+                new NotificationGroupManager());
+        mDependency.injectMockDependency(ShadeController.class);
+        mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
         when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
         when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
-        mNotificationData = new TestableNotificationData(mEnvironment);
+        mNotificationData = new TestableNotificationData();
+        Dependency.get(InitController.class).executePostInitTasks();
         mNotificationData.updateRanking(mock(NotificationListenerService.RankingMap.class));
         mRow = new NotificationTestHelper(getContext()).createRow();
     }
@@ -298,11 +305,11 @@
                 mRow.getEntry().notification)).thenReturn(false);
         when(mEnvironment.isNotificationForCurrentProfiles(
                 row2.getEntry().notification)).thenReturn(true);
-        ArrayList<NotificationData.Entry> reuslt =
+        ArrayList<NotificationData.Entry> result =
                 mNotificationData.getNotificationsForCurrentUser();
 
-        assertEquals(reuslt.size(), 1);
-        junit.framework.Assert.assertEquals(reuslt.get(0), row2.getEntry());
+        assertEquals(result.size(), 1);
+        junit.framework.Assert.assertEquals(result.get(0), row2.getEntry());
     }
 
     @Test
@@ -416,8 +423,8 @@
     }
 
     private class TestableNotificationData extends NotificationData {
-        public TestableNotificationData(Environment environment) {
-            super(environment);
+        public TestableNotificationData() {
+            super();
         }
 
         @Override
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 4e16b7f..fb4ecd1 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
@@ -54,7 +54,9 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.systemui.Dependency;
 import com.android.systemui.ForegroundServiceController;
+import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.NotificationLifetimeExtender;
@@ -66,11 +68,14 @@
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.notification.NotificationData.KeyguardEnvironment;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.row.NotificationInflater;
 import com.android.systemui.statusbar.notification.row.RowInflaterTask;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ShadeController;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
 
@@ -96,6 +101,7 @@
     private static final int TEST_UID = 0;
 
     @Mock private NotificationPresenter mPresenter;
+    @Mock private KeyguardEnvironment mEnvironment;
     @Mock private ExpandableNotificationRow mRow;
     @Mock private NotificationListContainer mListContainer;
     @Mock private NotificationEntryManager.Callback mCallback;
@@ -134,8 +140,9 @@
         }
 
         @Override
-        public void onAsyncInflationFinished(NotificationData.Entry entry) {
-            super.onAsyncInflationFinished(entry);
+        public void onAsyncInflationFinished(NotificationData.Entry entry,
+                @NotificationInflater.InflationFlag int inflatedFlags) {
+            super.onAsyncInflationFinished(entry, inflatedFlags);
 
             mCountDownLatch.countDown();
         }
@@ -188,6 +195,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
+        mDependency.injectMockDependency(ShadeController.class);
         mDependency.injectTestDependency(ForegroundServiceController.class,
                 mForegroundServiceController);
         mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
@@ -202,12 +210,12 @@
         mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
         mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
         mDependency.injectTestDependency(SmartReplyController.class, mSmartReplyController);
+        mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
 
         mCountDownLatch = new CountDownLatch(1);
 
-        when(mPresenter.getHandler()).thenReturn(Handler.createAsync(Looper.myLooper()));
-        when(mPresenter.getNotificationLockscreenUserManager()).thenReturn(mLockscreenUserManager);
-        when(mPresenter.getGroupManager()).thenReturn(mGroupManager);
+        mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
+                Handler.createAsync(Looper.myLooper()));
         when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
         when(mListContainer.getViewParentForNotification(any())).thenReturn(
                 new FrameLayout(mContext));
@@ -222,6 +230,7 @@
         mEntry.expandedIcon = mock(StatusBarIconView.class);
 
         mEntryManager = new TestableNotificationEntryManager(mContext, mBarService);
+        Dependency.get(InitController.class).executePostInitTasks();
         mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mCallback, mHeadsUpManager);
 
         setUserSentiment(mEntry.key, NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL);
@@ -419,8 +428,9 @@
 
     @Test
     public void testUpdateNotificationRanking() {
-        when(mPresenter.isDeviceProvisioned()).thenReturn(true);
-        when(mPresenter.isNotificationForCurrentProfiles(any())).thenReturn(true);
+        when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
+        when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
+        when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
 
         mEntry.row = mRow;
         mEntry.setInflationTask(mAsyncInflationTask);
@@ -428,51 +438,51 @@
         setSmartActions(mEntry.key, new ArrayList<>(Arrays.asList(createAction())));
 
         mEntryManager.updateNotificationRanking(mRankingMap);
-        verify(mRow).updateNotification(eq(mEntry));
+        verify(mRow).setEntry(eq(mEntry));
         assertEquals(1, mEntry.smartActions.size());
         assertEquals("action", mEntry.smartActions.get(0).title);
     }
 
     @Test
     public void testUpdateNotificationRanking_noChange() {
-        when(mPresenter.isDeviceProvisioned()).thenReturn(true);
-        when(mPresenter.isNotificationForCurrentProfiles(any())).thenReturn(true);
+        when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
+        when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
 
         mEntry.row = mRow;
         mEntryManager.getNotificationData().add(mEntry);
         setSmartActions(mEntry.key, null);
 
         mEntryManager.updateNotificationRanking(mRankingMap);
-        verify(mRow, never()).updateNotification(eq(mEntry));
+        verify(mRow, never()).setEntry(eq(mEntry));
         assertEquals(0, mEntry.smartActions.size());
     }
 
     @Test
     public void testUpdateNotificationRanking_rowNotInflatedYet() {
-        when(mPresenter.isDeviceProvisioned()).thenReturn(true);
-        when(mPresenter.isNotificationForCurrentProfiles(any())).thenReturn(true);
+        when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
+        when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
 
         mEntry.row = null;
         mEntryManager.getNotificationData().add(mEntry);
         setSmartActions(mEntry.key, new ArrayList<>(Arrays.asList(createAction())));
 
         mEntryManager.updateNotificationRanking(mRankingMap);
-        verify(mRow, never()).updateNotification(eq(mEntry));
+        verify(mRow, never()).setEntry(eq(mEntry));
         assertEquals(1, mEntry.smartActions.size());
         assertEquals("action", mEntry.smartActions.get(0).title);
     }
 
     @Test
     public void testUpdateNotificationRanking_pendingNotification() {
-        when(mPresenter.isDeviceProvisioned()).thenReturn(true);
-        when(mPresenter.isNotificationForCurrentProfiles(any())).thenReturn(true);
+        when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
+        when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
 
         mEntry.row = null;
         mEntryManager.mPendingNotifications.put(mEntry.key, mEntry);
         setSmartActions(mEntry.key, new ArrayList<>(Arrays.asList(createAction())));
 
         mEntryManager.updateNotificationRanking(mRankingMap);
-        verify(mRow, never()).updateNotification(eq(mEntry));
+        verify(mRow, never()).setEntry(eq(mEntry));
         assertEquals(1, mEntry.smartActions.size());
         assertEquals("action", mEntry.smartActions.get(0).title);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
index ca62c3b..1c7a8e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/logging/NotificationLoggerTest.java
@@ -92,7 +92,7 @@
         mEntry.row = mRow;
 
         mLogger = new TestableNotificationLogger(mBarService);
-        mLogger.setUpWithEntryManager(mEntryManager, mListContainer);
+        mLogger.setUpWithContainer(mListContainer);
     }
 
     @Test
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 743b307..bf8eb62 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
@@ -18,8 +18,13 @@
 
 import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
 
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_ALL;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_PUBLIC;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -48,6 +53,7 @@
 
 import org.junit.Assert;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -120,7 +126,8 @@
 
     @Test
     public void testIconColorShouldBeUpdatedWhenSensitive() throws Exception {
-        ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow());
+        ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow(
+                FLAG_CONTENT_VIEW_ALL));
         row.setSensitive(true, true);
         row.setHideSensitive(true, false, 0, 0);
         verify(row).updateShelfIconColor();
@@ -133,6 +140,38 @@
         verify(row).updateShelfIconColor();
     }
 
+    // TODO: Ignoring as a temporary workaround until heads up views can be safely freed.
+    // See http://b/117933032
+    @Test
+    @Ignore
+    public void testFreeContentViewWhenSafe() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
+
+        row.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
+
+        assertNull(row.getPrivateLayout().getHeadsUpChild());
+    }
+
+    @Test
+    public void setNeedsRedactionSetsInflationFlag() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow();
+
+        row.setNeedsRedaction(true);
+
+        assertTrue(row.getNotificationInflater().isInflationFlagSet(FLAG_CONTENT_VIEW_PUBLIC));
+    }
+
+    @Test
+    public void setNeedsRedactionFreesViewWhenFalse() throws Exception {
+        ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
+        row.setNeedsRedaction(true);
+        row.getPublicLayout().setVisibility(View.GONE);
+
+        row.setNeedsRedaction(false);
+
+        assertNull(row.getPublicLayout().getContractedChild());
+    }
+
     @Test
     public void testAboveShelfChangedListenerCalled() throws Exception {
         ExpandableNotificationRow row = mNotificationTestHelper.createRow();
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 8edbf17..ee35449 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
@@ -61,7 +61,9 @@
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -93,11 +95,14 @@
     @Mock private NotificationEntryManager mEntryManager;
     @Mock private NotificationStackScrollLayout mStackScroller;
     @Mock private NotificationInfo.CheckSaveListener mCheckSaveListener;
-    @Mock private NotificationGutsManager.OnSettingsClickListener mOnSettingsClickListener;
+    @Mock private OnSettingsClickListener mOnSettingsClickListener;
+    @Mock private DeviceProvisionedController mDeviceProvisionedController;
 
     @Before
     public void setUp() {
         mTestableLooper = TestableLooper.get(this);
+        mDependency.injectTestDependency(DeviceProvisionedController.class,
+                mDeviceProvisionedController);
         mHandler = Handler.createAsync(mTestableLooper.getLooper());
 
         mHelper = new NotificationTestHelper(mContext);
@@ -330,7 +335,7 @@
         row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
         when(row.getIsNonblockable()).thenReturn(false);
         StatusBarNotification statusBarNotification = row.getStatusBarNotification();
-        when(mPresenter.isDeviceProvisioned()).thenReturn(true);
+        when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
 
         mGutsManager.initializeNotificationInfo(row, notificationInfoView);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInflaterTest.java
index 81e79d1..fdb66cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInflaterTest.java
@@ -16,10 +16,15 @@
 
 package com.android.systemui.statusbar.notification.row;
 
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_ALL;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_AMBIENT;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_EXPANDED;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_HEADS_UP;
+import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_CONTENT_VIEW_PUBLIC;
 
-import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_REINFLATE_ALL;
-
-import static com.android.systemui.statusbar.notification.row.NotificationInflater.FLAG_REINFLATE_EXPANDED_VIEW;
+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.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -34,6 +39,7 @@
 import android.support.test.filters.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper.RunWithLooper;
+import android.util.ArrayMap;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.RemoteViews;
@@ -41,8 +47,8 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.InflationTask;
-import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.NotificationData;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -82,7 +88,8 @@
             }
 
             @Override
-            public void onAsyncInflationFinished(NotificationData.Entry entry) {
+            public void onAsyncInflationFinished(NotificationData.Entry entry,
+                    @NotificationInflater.InflationFlag int inflatedFlags) {
             }
         });
     }
@@ -91,7 +98,7 @@
     public void testIncreasedHeadsUpBeingUsed() {
         mNotificationInflater.setUsesIncreasedHeadsUpHeight(true);
         Notification.Builder builder = spy(mBuilder);
-        mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext);
+        mNotificationInflater.inflateNotificationViews(FLAG_CONTENT_VIEW_ALL, builder, mContext);
         verify(builder).createHeadsUpContentView(true);
     }
 
@@ -99,7 +106,7 @@
     public void testIncreasedHeightBeingUsed() {
         mNotificationInflater.setUsesIncreasedHeight(true);
         Notification.Builder builder = spy(mBuilder);
-        mNotificationInflater.inflateNotificationViews(FLAG_REINFLATE_ALL, builder, mContext);
+        mNotificationInflater.inflateNotificationViews(FLAG_CONTENT_VIEW_ALL, builder, mContext);
         verify(builder).createContentView(true);
     }
 
@@ -110,15 +117,18 @@
         verify(mRow).onNotificationUpdated();
     }
 
+    // TODO: Ignoring as a temporary workaround until ambient views can be safely freed.
+    // See http://b/117894786
     @Test
-    public void testInflationCallsOnlyRightMethod() throws Exception {
-        mRow.getPrivateLayout().removeAllViews();
-        mRow.getEntry().cachedBigContentView = null;
-        runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(
-                FLAG_REINFLATE_EXPANDED_VIEW), mNotificationInflater);
-        assertTrue(mRow.getPrivateLayout().getChildCount() == 1);
-        assertTrue(mRow.getPrivateLayout().getChildAt(0)
-                == mRow.getPrivateLayout().getExpandedChild());
+    @Ignore
+    public void testInflationOnlyInflatesSetFlags() throws Exception {
+        mNotificationInflater.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP,
+                true /* shouldInflate */);
+        runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(),
+                mNotificationInflater);
+
+        assertNotNull(mRow.getPrivateLayout().getHeadsUpChild());
+        assertNull(mRow.getShowingLayout().getAmbientChild());
         verify(mRow).onNotificationUpdated();
     }
 
@@ -155,8 +165,9 @@
                 new NotificationInflater.InflationProgress();
         result.packageContext = mContext;
         CountDownLatch countDownLatch = new CountDownLatch(1);
-        NotificationInflater.applyRemoteView(result, FLAG_REINFLATE_EXPANDED_VIEW, 0, mRow,
-                false /* redactAmbient */, true /* isNewView */, new RemoteViews.OnClickHandler(),
+        NotificationInflater.applyRemoteView(result, FLAG_CONTENT_VIEW_EXPANDED, 0,
+                new ArrayMap() /* cachedContentViews */, mRow, false /* redactAmbient */,
+                true /* isNewView */, new RemoteViews.OnClickHandler(),
                 new NotificationInflater.InflationCallback() {
                     @Override
                     public void handleInflationException(StatusBarNotification notification,
@@ -166,10 +177,11 @@
                     }
 
                     @Override
-                    public void onAsyncInflationFinished(NotificationData.Entry entry) {
+                    public void onAsyncInflationFinished(NotificationData.Entry entry,
+                            @NotificationInflater.InflationFlag int inflatedFlags) {
                         countDownLatch.countDown();
                     }
-                }, mRow.getEntry(), mRow.getPrivateLayout(), null, null, new HashMap<>(),
+                }, mRow.getPrivateLayout(), null, null, new HashMap<>(),
                 new NotificationInflater.ApplyCallback() {
                     @Override
                     public void setResultView(View v) {
@@ -184,18 +196,34 @@
         assertTrue(countDownLatch.await(500, TimeUnit.MILLISECONDS));
     }
 
+    @Test
+    public void testUpdateNeedsRedactionReinflatesChangedContentViews() {
+        mNotificationInflater.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, true);
+        mNotificationInflater.updateInflationFlag(FLAG_CONTENT_VIEW_PUBLIC, true);
+        mNotificationInflater.updateNeedsRedaction(true);
+
+        NotificationInflater.AsyncInflationTask asyncInflationTask =
+                (NotificationInflater.AsyncInflationTask) mRow.getEntry().getRunningTask();
+        assertEquals(FLAG_CONTENT_VIEW_AMBIENT | FLAG_CONTENT_VIEW_PUBLIC,
+                asyncInflationTask.getReInflateFlags());
+        asyncInflationTask.abort();
+    }
+
     /* Cancelling requires us to be on the UI thread otherwise we might have a race */
     @Test
-    public void testSupersedesExistingTask() throws Exception {
+    public void testSupersedesExistingTask() {
+        mNotificationInflater.addInflationFlags(FLAG_CONTENT_VIEW_ALL);
         mNotificationInflater.inflateNotificationViews();
+
+        // Trigger inflation of content and expanded only.
         mNotificationInflater.setIsLowPriority(true);
         mNotificationInflater.setIsChildInGroup(true);
+
         InflationTask runningTask = mRow.getEntry().getRunningTask();
         NotificationInflater.AsyncInflationTask asyncInflationTask =
                 (NotificationInflater.AsyncInflationTask) runningTask;
-        Assert.assertSame("Successive inflations don't inherit the previous flags!",
-                asyncInflationTask.getReInflateFlags(),
-                NotificationInflater.FLAG_REINFLATE_ALL);
+        assertEquals("Successive inflations don't inherit the previous flags!",
+                FLAG_CONTENT_VIEW_ALL, asyncInflationTask.getReInflateFlags());
         runningTask.abort();
     }
 
@@ -231,7 +259,8 @@
             }
 
             @Override
-            public void onAsyncInflationFinished(NotificationData.Entry entry) {
+            public void onAsyncInflationFinished(NotificationData.Entry entry,
+                    @NotificationInflater.InflationFlag int inflatedFlags) {
                 if (expectingException) {
                     exceptionHolder.setException(new RuntimeException(
                             "Inflation finished even though there should be an error"));
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 b545e61..d2fe82f 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
@@ -15,6 +15,10 @@
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+
+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;
@@ -36,31 +40,33 @@
 import android.support.test.annotation.UiThreadTest;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
 
+import com.android.systemui.Dependency;
 import com.android.systemui.ExpandHelper;
+import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.EmptyShadeView;
-import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationShelf;
+import com.android.systemui.statusbar.RemoteInputController;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.notification.NotificationData;
 import com.android.systemui.statusbar.notification.NotificationData.Entry;
 import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.row.FooterView;
 import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
-import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShelf;
-import com.android.systemui.statusbar.RemoteInputController;
-import com.android.systemui.statusbar.StatusBarStateController;
 import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 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 java.util.ArrayList;
-
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
@@ -71,6 +77,8 @@
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
+import java.util.ArrayList;
+
 /**
  * Tests for {@link NotificationStackScrollLayout}.
  */
@@ -105,6 +113,7 @@
         mDependency.injectTestDependency(StatusBarStateController.class, mBarState);
         mDependency.injectTestDependency(NotificationRemoteInputManager.class,
                 mRemoteInputManager);
+        mDependency.injectMockDependency(ShadeController.class);
         when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
 
         IPowerManager powerManagerService = mock(IPowerManager.class);
@@ -113,11 +122,13 @@
 
         mEntryManager = new TestableNotificationEntryManager(mDreamManager, mPowerManager,
                 mContext);
+        mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
+        Dependency.get(InitController.class).executePostInitTasks();
         mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, null, mHeadsUpManager,
                 mNotificationData);
-        mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
 
-        NotificationShelf notificationShelf = spy(new NotificationShelf(getContext(), null));
+
+        NotificationShelf notificationShelf = mock(NotificationShelf.class);
         mStackScroller = spy(new NotificationStackScrollLayout(getContext()));
         mStackScroller.setShelf(notificationShelf);
         mStackScroller.setStatusBar(mBar);
@@ -144,7 +155,7 @@
         when(mBarState.getState()).thenReturn(StatusBarState.SHADE);
         mStackScroller.setDimmed(true /* dimmed */, false /* animate */);
         mStackScroller.setDimmed(true /* dimmed */, true /* animate */);
-        Assert.assertFalse(mStackScroller.isDimmed());
+        assertFalse(mStackScroller.isDimmed());
     }
 
     @Test
@@ -243,7 +254,7 @@
         assertEquals(0, mNotificationData.getActiveNotifications().size());
 
         mStackScroller.updateFooter();
-        verify(mStackScroller).updateFooterView(false, false);
+        verify(mStackScroller, atLeastOnce()).updateFooterView(false, false);
     }
 
     @Test
@@ -284,7 +295,8 @@
         setBarStateForTest(StatusBarState.SHADE);
         ArrayList<Entry> entries = new ArrayList<>();
         entries.add(mock(Entry.class));
-        when(mNotificationData.getActiveNotifications()).thenReturn(entries);
+        when(mEntryManager.getNotificationData().getActiveNotifications()).thenReturn(entries);
+        assertTrue(mEntryManager.getNotificationData().getActiveNotifications().size() != 0);
 
         mStackScroller.updateFooter();
         verify(mStackScroller).updateFooterView(true, false);
@@ -314,10 +326,39 @@
         verify(mStackScroller).setEmptyShadeView(any());
     }
 
+    @Test
+    @UiThreadTest
+    public void testSetIsBeingDraggedResetsExposedMenu() {
+        NotificationSwipeHelper swipeActionHelper =
+                (NotificationSwipeHelper) mStackScroller.getSwipeActionHelper();
+        swipeActionHelper.setExposedMenuView(new View(mContext));
+        mStackScroller.setIsBeingDragged(true);
+        assertNull(swipeActionHelper.getExposedMenuView());
+    }
+
+    @Test
+    @UiThreadTest
+    public void testPanelTrackingStartResetsExposedMenu() {
+        NotificationSwipeHelper swipeActionHelper =
+                (NotificationSwipeHelper) mStackScroller.getSwipeActionHelper();
+        swipeActionHelper.setExposedMenuView(new View(mContext));
+        mStackScroller.onPanelTrackingStarted();
+        assertNull(swipeActionHelper.getExposedMenuView());
+    }
+
+    @Test
+    @UiThreadTest
+    public void testDarkModeResetsExposedMenu() {
+        NotificationSwipeHelper swipeActionHelper =
+                (NotificationSwipeHelper) mStackScroller.getSwipeActionHelper();
+        swipeActionHelper.setExposedMenuView(new View(mContext));
+        mStackScroller.setDarkAmount(0.1f, 0.1f);
+        assertNull(swipeActionHelper.getExposedMenuView());
+    }
+
     private void setBarStateForTest(int state) {
-        ArgumentCaptor<StatusBarStateController.StateListener> captor =
-                ArgumentCaptor.forClass(StatusBarStateController.StateListener.class);
-        verify(mBarState, atLeastOnce()).addListener(captor.capture());
-        captor.getValue().onStateChanged(state);
+        // Can't inject this through the listener or we end up on the actual implementation
+        // rather than the mock because the spy just coppied the anonymous inner /shruggie.
+        mStackScroller.setStatusBarState(state);
     }
 }
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 a4004ae..10b0d83 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
@@ -54,6 +54,7 @@
     private ExpandableNotificationRow mFirst;
     private HeadsUpStatusBarView mHeadsUpStatusBarView;
     private HeadsUpManagerPhone mHeadsUpManager;
+    private View mOperatorNameView;
 
     @Before
     public void setUp() throws Exception {
@@ -63,13 +64,15 @@
         mHeadsUpStatusBarView = new HeadsUpStatusBarView(mContext, mock(View.class),
                 mock(TextView.class));
         mHeadsUpManager = mock(HeadsUpManagerPhone.class);
+        mOperatorNameView = new View(mContext);
         mHeadsUpAppearanceController = new HeadsUpAppearanceController(
                 mock(NotificationIconAreaController.class),
                 mHeadsUpManager,
                 mHeadsUpStatusBarView,
                 mStackScroller,
                 mPanelView,
-                new View(mContext));
+                new View(mContext),
+                mOperatorNameView);
         mHeadsUpAppearanceController.setExpandedHeight(0.0f, 0.0f);
     }
 
@@ -116,6 +119,22 @@
     }
 
     @Test
+    public void testOperatorNameViewUpdated() {
+        mHeadsUpAppearanceController.setAnimationsEnabled(false);
+
+        mFirst.setPinned(true);
+        when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
+        when(mHeadsUpManager.getTopEntry()).thenReturn(mFirst.getEntry());
+        mHeadsUpAppearanceController.onHeadsUpPinned(mFirst);
+        Assert.assertEquals(View.INVISIBLE, mOperatorNameView.getVisibility());
+
+        mFirst.setPinned(false);
+        when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
+        mHeadsUpAppearanceController.onHeadsUpUnPinned(mFirst);
+        Assert.assertEquals(View.VISIBLE, mOperatorNameView.getVisibility());
+    }
+
+    @Test
     public void testHeaderReadFromOldController() {
         mHeadsUpAppearanceController.setExpandedHeight(1.0f, 1.0f);
 
@@ -125,6 +144,7 @@
                 mHeadsUpStatusBarView,
                 mStackScroller,
                 mPanelView,
+                new View(mContext),
                 new View(mContext));
         newController.readFrom(mHeadsUpAppearanceController);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
new file mode 100644
index 0000000..96f1976
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
@@ -0,0 +1,47 @@
+package com.android.systemui.statusbar.phone
+
+import android.support.test.filters.SmallTest
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.KeyguardIndicationController
+
+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
+class KeyguardBottomAreaTest : SysuiTestCase() {
+
+    @Mock
+    private lateinit var mStatusBar: StatusBar
+    @Mock
+    private lateinit var mKeyguardIndicationController: KeyguardIndicationController
+    private lateinit var mKeyguardBottomArea: KeyguardBottomAreaView
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        mKeyguardBottomArea = LayoutInflater.from(mContext).inflate(
+                R.layout.keyguard_bottom_area, null, false) as KeyguardBottomAreaView
+        mKeyguardBottomArea.setStatusBar(mStatusBar)
+        mKeyguardBottomArea.setKeyguardIndicationController(mKeyguardIndicationController)
+    }
+
+    @Test
+    fun initFrom_doesntCrash() {
+        val other = LayoutInflater.from(mContext).inflate(
+                R.layout.keyguard_bottom_area, null, false) as KeyguardBottomAreaView
+
+        other.initFrom(mKeyguardBottomArea)
+        other.launchVoiceAssist()
+        other.onLongClick(null)
+    }
+}
\ No newline at end of file
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 a7954f2..7f8668f 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
@@ -45,6 +45,7 @@
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -170,13 +171,17 @@
         mBouncer.ensureView();
         mBouncer.setExpansion(0.5f);
 
-        mBouncer.setExpansion(1);
+        mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
         verify(mFalsingManager).onBouncerHidden();
         verify(mExpansionCallback).onFullyHidden();
 
-        mBouncer.setExpansion(0);
+        mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
         verify(mFalsingManager).onBouncerShown();
         verify(mExpansionCallback).onFullyShown();
+
+        verify(mExpansionCallback, never()).onStartingToHide();
+        mBouncer.setExpansion(0.9f);
+        verify(mExpansionCallback).onStartingToHide();
     }
 
     @Test
@@ -234,7 +239,7 @@
 
     @Test
     public void testShowOnDismissAction_showsBouncer() {
-        final KeyguardHostView.OnDismissAction dismissAction = () -> false;
+        final OnDismissAction dismissAction = () -> false;
         final Runnable cancelAction = () -> {};
         mBouncer.showWithDismissAction(dismissAction, cancelAction);
         verify(mKeyguardHostView).setOnDismissAction(dismissAction, cancelAction);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
new file mode 100644
index 0000000..be26d91
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NavigationBarRotationContextTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static 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;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+
+import com.android.systemui.SysuiTestableContext;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.TestableDependency;
+import com.android.systemui.statusbar.policy.KeyButtonDrawable;
+import com.android.systemui.statusbar.policy.RotationLockController;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.MockitoAnnotations;
+
+/** atest NavigationBarRotationContextTest */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class NavigationBarRotationContextTest extends SysuiTestCase {
+    static final int RES_UNDEF = 0;
+    static final int DEFAULT_ROTATE = 0;
+
+    @Rule
+    public final SysuiTestableContext mContext = new SysuiTestableContext(
+            InstrumentationRegistry.getContext(), getLeakCheck());
+    private final TestableDependency mDependency = new TestableDependency(mContext);
+    private RotationContextButton mButton;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mDependency.injectMockDependency(RotationLockController.class);
+
+        final View view = new View(mContext);
+        mButton = spy(new RotationContextButton(RES_UNDEF, RES_UNDEF, mContext, RES_UNDEF));
+        final KeyButtonDrawable kbd = mock(KeyButtonDrawable.class);
+        doReturn(view).when(mButton).getCurrentView();
+        doReturn(kbd).when(mButton).getNewDrawable();
+    }
+
+    @Test
+    public void testOnInvalidRotationProposal() {
+        mButton.onRotationProposal(DEFAULT_ROTATE, DEFAULT_ROTATE + 1, false /* isValid */);
+        verify(mButton, times(1)).setRotateSuggestionButtonState(false /* visible */);
+    }
+
+    @Test
+    public void testOnSameRotationProposal() {
+        mButton.onRotationProposal(DEFAULT_ROTATE, DEFAULT_ROTATE, true /* isValid */);
+        verify(mButton, times(1)).setRotateSuggestionButtonState(false /* visible */);
+    }
+
+    @Test
+    public void testOnRotationProposalShowButtonShowNav() {
+        // No navigation bar should not call to set visibility state
+        mButton.onNavigationBarWindowVisibilityChange(false /* showing */);
+        verify(mButton, times(0)).setRotateSuggestionButtonState(false /* visible */);
+        verify(mButton, times(0)).setRotateSuggestionButtonState(true /* visible */);
+
+        // No navigation bar with rotation change should not call to set visibility state
+        mButton.onRotationProposal(DEFAULT_ROTATE, DEFAULT_ROTATE + 1, true /* isValid */);
+        verify(mButton, times(0)).setRotateSuggestionButtonState(false /* visible */);
+        verify(mButton, times(0)).setRotateSuggestionButtonState(true /* visible */);
+
+        // Since rotation has changed rotation should be pending, show mButton when showing nav bar
+        mButton.onNavigationBarWindowVisibilityChange(true /* showing */);
+        verify(mButton, times(1)).setRotateSuggestionButtonState(true /* visible */);
+    }
+
+    @Test
+    public void testOnRotationProposalShowButton() {
+        // Navigation bar being visible should not call to set visibility state
+        mButton.onNavigationBarWindowVisibilityChange(true /* showing */);
+        verify(mButton, times(0)).setRotateSuggestionButtonState(false /* visible */);
+        verify(mButton, times(0)).setRotateSuggestionButtonState(true /* visible */);
+
+        // Navigation bar is visible and rotation requested
+        mButton.onRotationProposal(DEFAULT_ROTATE, DEFAULT_ROTATE + 1, true /* isValid */);
+        verify(mButton, times(1)).setRotateSuggestionButtonState(true /* visible */);
+    }
+}
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 be4560b..93dedfb 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
@@ -31,10 +31,10 @@
 import android.view.ViewGroup;
 
 import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardHostView;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -78,7 +78,7 @@
 
     @Test
     public void dismissWithAction_AfterKeyguardGoneSetToFalse() {
-        KeyguardHostView.OnDismissAction action = () -> false;
+        OnDismissAction action = () -> false;
         Runnable cancelAction = () -> {};
         mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction,
                 false /* afterKeyguardGone */);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
new file mode 100644
index 0000000..24baa7d
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenterTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static org.junit.Assert.assertFalse;
+import static org.mockito.Mockito.mock;
+
+import android.app.Notification;
+import android.app.StatusBarManager;
+import android.content.Context;
+import android.metrics.LogMaker;
+import android.os.UserHandle;
+import android.service.notification.StatusBarNotification;
+import android.support.test.filters.SmallTest;
+import android.support.test.metricshelper.MetricsAsserts;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.ViewGroup;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.logging.testing.FakeMetricsLogger;
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@RunWithLooper(setAsMainLooper = true)
+public class StatusBarNotificationPresenterTest extends SysuiTestCase {
+
+
+    private StatusBarNotificationPresenter mStatusBar;
+    private CommandQueue mCommandQueue;
+    private FakeMetricsLogger mMetricsLogger;
+    private ShadeController mShadeController = mock(ShadeController.class);
+
+    @Before
+    public void setup() {
+        mMetricsLogger = new FakeMetricsLogger();
+        mDependency.injectTestDependency(MetricsLogger.class, mMetricsLogger);
+        mCommandQueue = new CommandQueue();
+        mContext.putComponent(CommandQueue.class, mCommandQueue);
+        mDependency.injectTestDependency(ShadeController.class, mShadeController);
+
+        mStatusBar = new StatusBarNotificationPresenter(mContext,
+                mock(NotificationPanelView.class), mock(HeadsUpManagerPhone.class),
+                mock(StatusBarWindowView.class), mock(NotificationListContainerViewGroup.class),
+                mock(DozeScrimController.class), mock(ScrimController.class),
+                mock(ActivityLaunchAnimator.Callback.class));
+    }
+
+    @Test
+    public void testHeadsUp_disabledStatusBar() {
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+        mCommandQueue.disable(StatusBarManager.DISABLE_EXPAND, 0, false /* animate */);
+        TestableLooper.get(this).processAllMessages();
+
+        assertFalse("The panel shouldn't allow heads up while disabled",
+                mStatusBar.canHeadsUp(entry, sbn));
+    }
+
+    @Test
+    public void testHeadsUp_disabledNotificationShade() {
+        Notification n = new Notification.Builder(getContext(), "a").build();
+        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
+                UserHandle.of(0), null, 0);
+        NotificationData.Entry entry = new NotificationData.Entry(sbn);
+        mCommandQueue.disable(0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false /* animate */);
+        TestableLooper.get(this).processAllMessages();
+
+        assertFalse("The panel shouldn't allow heads up while notitifcation shade disabled",
+                mStatusBar.canHeadsUp(entry, sbn));
+    }
+
+    @Test
+    public void onActivatedMetrics() {
+        ActivatableNotificationView view =  mock(ActivatableNotificationView.class);
+        mStatusBar.onActivated(view);
+
+        MetricsAsserts.assertHasLog("missing lockscreen note tap log",
+                mMetricsLogger.getLogs(),
+                new LogMaker(MetricsEvent.ACTION_LS_NOTE)
+                        .setType(MetricsEvent.TYPE_ACTION));
+    }
+
+    // We need this because mockito doesn't know how to construct a mock that extends ViewGroup
+    // and implements NotificationListContainer without it because of classloader issues.
+    private abstract static class NotificationListContainerViewGroup extends ViewGroup
+            implements NotificationListContainer {
+
+        public NotificationListContainerViewGroup(Context context) {
+            super(context);
+        }
+    }
+}
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
new file mode 100644
index 0000000..f28757f
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.phone;
+
+import static android.content.Intent.ACTION_DEVICE_LOCKED_CHANGED;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+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 static org.mockito.internal.verification.VerificationModeFactory.times;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.UserManager;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+
+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 StatusBarRemoteInputCallbackTest extends SysuiTestCase {
+    @Mock private NotificationPresenter mPresenter;
+    @Mock private UserManager mUserManager;
+
+    // Dependency mocks:
+    @Mock private NotificationEntryManager mEntryManager;
+    @Mock private DeviceProvisionedController mDeviceProvisionedController;
+    @Mock private ShadeController mShadeController;
+    @Mock private NotificationLockscreenUserManager mNotificationLockscreenUserManager;
+
+    private int mCurrentUserId = 0;
+    private StatusBarRemoteInputCallback mRemoteInputCallback;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
+        mDependency.injectTestDependency(DeviceProvisionedController.class,
+                mDeviceProvisionedController);
+        mDependency.injectTestDependency(ShadeController.class, mShadeController);
+        mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
+                mNotificationLockscreenUserManager);
+        mDependency.putComponent(CommandQueue.class, mock(CommandQueue.class));
+
+        mRemoteInputCallback = spy(new StatusBarRemoteInputCallback(mContext));
+        mRemoteInputCallback.mChallengeReceiver = mRemoteInputCallback.new ChallengeReceiver();
+    }
+
+    @Test
+    public void testActionDeviceLockedChangedWithDifferentUserIdCallsOnWorkChallengeChanged() {
+        when(mNotificationLockscreenUserManager.getCurrentUserId()).thenReturn(mCurrentUserId);
+        when(mNotificationLockscreenUserManager.isCurrentProfile(anyInt())).thenReturn(true);
+        Intent intent = new Intent()
+                .setAction(ACTION_DEVICE_LOCKED_CHANGED)
+                .putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId + 1);
+        mRemoteInputCallback.mChallengeReceiver.onReceive(mContext, intent);
+        verify(mRemoteInputCallback, times(1)).onWorkChallengeChanged();
+    }
+
+}
\ 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 da93327..939245f 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
@@ -18,9 +18,7 @@
 
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
 
-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 junit.framework.TestCase.fail;
 
@@ -64,42 +62,41 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.logging.testing.FakeMetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
-import com.android.keyguard.KeyguardHostView.OnDismissAction;
+import com.android.systemui.Dependency;
 import com.android.systemui.ForegroundServiceController;
+import com.android.systemui.InitController;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.assist.AssistManager;
-import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.classifier.FalsingManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.recents.misc.SystemServicesProxy;
-import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
-import com.android.systemui.statusbar.notification.AppOpsListener;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.notification.NotificationData;
-import com.android.systemui.statusbar.notification.NotificationData.Entry;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
 import com.android.systemui.statusbar.NotificationListener;
 import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.logging.NotificationLogger;
 import com.android.systemui.statusbar.NotificationMediaManager;
 import com.android.systemui.statusbar.NotificationPresenter;
 import com.android.systemui.statusbar.NotificationRemoteInputManager;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.NotificationViewHierarchyManager;
 import com.android.systemui.statusbar.RemoteInputController;
-import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.AppOpsListener;
+import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.NotificationData.Entry;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -137,18 +134,21 @@
     @Mock private NotificationRemoteInputManager mRemoteInputManager;
     @Mock private RemoteInputController mRemoteInputController;
     @Mock private StatusBarStateController mStatusBarStateController;
+    @Mock private DeviceProvisionedController mDeviceProvisionedController;
+    @Mock private NotificationPresenter mNotificationPresenter;
+    @Mock private NotificationEntryManager.Callback mCallback;
 
     private TestableStatusBar mStatusBar;
     private FakeMetricsLogger mMetricsLogger;
     private PowerManager mPowerManager;
     private TestableNotificationEntryManager mEntryManager;
     private NotificationLogger mNotificationLogger;
+    private CommandQueue mCommandQueue;
 
     @Before
     public void setup() throws Exception {
         MockitoAnnotations.initMocks(this);
         mDependency.injectMockDependency(AssistManager.class);
-        mDependency.injectMockDependency(DeviceProvisionedController.class);
         mDependency.injectMockDependency(NotificationGutsManager.class);
         mDependency.injectMockDependency(NotificationMediaManager.class);
         mDependency.injectMockDependency(ForegroundServiceController.class);
@@ -159,6 +159,8 @@
         mDependency.injectTestDependency(KeyguardMonitor.class, mock(KeyguardMonitorImpl.class));
         mDependency.injectTestDependency(AppOpsListener.class, mock(AppOpsListener.class));
         mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController);
+        mDependency.injectTestDependency(DeviceProvisionedController.class,
+                mDeviceProvisionedController);
 
         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
         mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
@@ -172,9 +174,9 @@
         mPowerManager = new PowerManager(mContext, powerManagerService,
                 Handler.createAsync(Looper.myLooper()));
 
-        CommandQueue commandQueue = mock(CommandQueue.class);
-        when(commandQueue.asBinder()).thenReturn(new Binder());
-        mContext.putComponent(CommandQueue.class, commandQueue);
+        mCommandQueue = mock(CommandQueue.class);
+        when(mCommandQueue.asBinder()).thenReturn(new Binder());
+        mContext.putComponent(CommandQueue.class, mCommandQueue);
 
         mContext.setTheme(R.style.Theme_SystemUI_Light);
 
@@ -202,17 +204,19 @@
                 mPowerManager, mNotificationPanelView, mBarService, mNotificationListener,
                 mNotificationLogger, mVisualStabilityManager, mViewHierarchyManager,
                 mEntryManager, mScrimController, mBiometricUnlockController,
-                mock(ActivityLaunchAnimator.class), mKeyguardViewMediator,
-                mRemoteInputManager, mock(NotificationGroupManager.class),
+                mKeyguardViewMediator, mRemoteInputManager, mock(NotificationGroupManager.class),
                 mock(FalsingManager.class), mock(StatusBarWindowController.class),
                 mock(NotificationIconAreaController.class), mock(DozeScrimController.class),
                 mock(NotificationShelf.class), mLockscreenUserManager,
-                mock(CommandQueue.class));
+                mCommandQueue,
+                mNotificationPresenter);
         mStatusBar.mContext = mContext;
         mStatusBar.mComponents = mContext.getComponents();
-        mEntryManager.setUpForTest(mStatusBar, mStackScroller, mStatusBar, mHeadsUpManager,
-                mNotificationData);
-        mNotificationLogger.setUpWithEntryManager(mEntryManager, mStackScroller);
+        mStatusBar.putComponent(StatusBar.class, mStatusBar);
+        Dependency.get(InitController.class).executePostInitTasks();
+        mEntryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller,
+                mCallback, mHeadsUpManager, mNotificationData);
+        mNotificationLogger.setUpWithContainer(mStackScroller);
 
         TestableLooper.get(this).setMessageHandler(m -> {
             if (m.getCallback() == mStatusBar.mNotificationLogger.getVisibilityReporter()) {
@@ -347,17 +351,6 @@
     }
 
     @Test
-    public void onActivatedMetrics() {
-        ActivatableNotificationView view =  mock(ActivatableNotificationView.class);
-        mStatusBar.onActivated(view);
-
-        MetricsAsserts.assertHasLog("missing lockscreen note tap log",
-                mMetricsLogger.getLogs(),
-                new LogMaker(MetricsEvent.ACTION_LS_NOTE)
-                        .setType(MetricsEvent.TYPE_ACTION));
-    }
-
-    @Test
     public void testShouldHeadsUp_nonSuppressedGroupSummary() throws Exception {
         when(mPowerManager.isScreenOn()).thenReturn(true);
         when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
@@ -365,6 +358,7 @@
         when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
         when(mDreamManager.isDreaming()).thenReturn(false);
         when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+        when(mCallback.canHeadsUp(any(), any())).thenReturn(true);
 
         Notification n = new Notification.Builder(getContext(), "a")
                 .setGroup("a")
@@ -386,6 +380,7 @@
         when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
         when(mDreamManager.isDreaming()).thenReturn(false);
         when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+        when(mCallback.canHeadsUp(any(), any())).thenReturn(true);
 
         Notification n = new Notification.Builder(getContext(), "a")
                 .setGroup("a")
@@ -406,6 +401,7 @@
         when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
         when(mDreamManager.isDreaming()).thenReturn(false);
         when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+        when(mCallback.canHeadsUp(any(), any())).thenReturn(true);
 
         when(mNotificationData.shouldSuppressPeek(any())).thenReturn(true);
 
@@ -424,6 +420,7 @@
         when(mNotificationData.shouldFilterOut(any())).thenReturn(false);
         when(mDreamManager.isDreaming()).thenReturn(false);
         when(mNotificationData.getImportance(any())).thenReturn(IMPORTANCE_HIGH);
+        when(mCallback.canHeadsUp(any(), any())).thenReturn(true);
 
         when(mNotificationData.shouldSuppressPeek(any())).thenReturn(false);
 
@@ -436,30 +433,6 @@
     }
 
     @Test
-    public void testHeadsUp_disabledStatusBar() {
-        Notification n = new Notification.Builder(getContext(), "a").build();
-        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
-                UserHandle.of(0), null, 0);
-        NotificationData.Entry entry = new NotificationData.Entry(sbn);
-        mStatusBar.disable(StatusBarManager.DISABLE_EXPAND, 0, false /* animate */);
-
-        assertFalse("The panel shouldn't allow heads up while disabled",
-                mStatusBar.canHeadsUp(entry, sbn));
-    }
-
-    @Test
-    public void testHeadsUp_disabledNotificationShade() {
-        Notification n = new Notification.Builder(getContext(), "a").build();
-        StatusBarNotification sbn = new StatusBarNotification("a", "a", 0, "a", 0, 0, n,
-                UserHandle.of(0), null, 0);
-        NotificationData.Entry entry = new NotificationData.Entry(sbn);
-        mStatusBar.disable(0, StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false /* animate */);
-
-        assertFalse("The panel shouldn't allow heads up while notification shade disabled",
-                mStatusBar.canHeadsUp(entry, sbn));
-    }
-
-    @Test
     public void testLogHidden() {
         try {
             mStatusBar.handleVisibleToUserChanged(false);
@@ -473,10 +446,11 @@
 
     @Test
     public void testPanelOpenForHeadsUp() {
+        when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(true);
         when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList);
         when(mNotificationList.size()).thenReturn(5);
-        when(mNotificationPanelView.isFullyCollapsed()).thenReturn(true);
+        when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(true);
         mStatusBar.setBarStateForTest(StatusBarState.SHADE);
 
         try {
@@ -495,7 +469,7 @@
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
         when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList);
         when(mNotificationList.size()).thenReturn(5);
-        when(mNotificationPanelView.isFullyCollapsed()).thenReturn(false);
+        when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(false);
         mStatusBar.setBarStateForTest(StatusBarState.SHADE);
 
         try {
@@ -514,7 +488,7 @@
         when(mHeadsUpManager.hasPinnedHeadsUp()).thenReturn(false);
         when(mNotificationData.getActiveNotifications()).thenReturn(mNotificationList);
         when(mNotificationList.size()).thenReturn(5);
-        when(mNotificationPanelView.isFullyCollapsed()).thenReturn(false);
+        when(mNotificationPresenter.isPresenterFullyCollapsed()).thenReturn(false);
         mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
 
         try {
@@ -532,8 +506,9 @@
     public void testDisableExpandStatusBar() {
         mStatusBar.setBarStateForTest(StatusBarState.SHADE);
         mStatusBar.setUserSetupForTest(true);
-        when(mStatusBar.isDeviceProvisioned()).thenReturn(true);
+        when(mDeviceProvisionedController.isDeviceProvisioned()).thenReturn(true);
 
+        when(mCommandQueue.panelsEnabled()).thenReturn(false);
         mStatusBar.disable(StatusBarManager.DISABLE_NONE,
                 StatusBarManager.DISABLE2_NOTIFICATION_SHADE, false);
         verify(mNotificationPanelView).setQsExpansionEnabled(false);
@@ -542,6 +517,7 @@
         mStatusBar.animateExpandSettingsPanel(null);
         verify(mNotificationPanelView, never()).expand(anyBoolean());
 
+        when(mCommandQueue.panelsEnabled()).thenReturn(true);
         mStatusBar.disable(StatusBarManager.DISABLE_NONE, StatusBarManager.DISABLE2_NONE, false);
         verify(mNotificationPanelView).setQsExpansionEnabled(true);
         mStatusBar.animateExpandNotificationsPanel();
@@ -627,7 +603,7 @@
                 NotificationViewHierarchyManager viewHierarchyManager,
                 TestableNotificationEntryManager entryManager, ScrimController scrimController,
                 BiometricUnlockController biometricUnlockController,
-                ActivityLaunchAnimator launchAnimator, KeyguardViewMediator keyguardViewMediator,
+                KeyguardViewMediator keyguardViewMediator,
                 NotificationRemoteInputManager notificationRemoteInputManager,
                 NotificationGroupManager notificationGroupManager,
                 FalsingManager falsingManager,
@@ -636,7 +612,8 @@
                 DozeScrimController dozeScrimController,
                 NotificationShelf notificationShelf,
                 NotificationLockscreenUserManager notificationLockscreenUserManager,
-                CommandQueue commandQueue) {
+                CommandQueue commandQueue,
+                NotificationPresenter notificationPresenter) {
             mStatusBarKeyguardViewManager = man;
             mUnlockMethodCache = unlock;
             mKeyguardIndicationController = key;
@@ -653,7 +630,6 @@
             mEntryManager = entryManager;
             mScrimController = scrimController;
             mBiometricUnlockController = biometricUnlockController;
-            mActivityLaunchAnimator = launchAnimator;
             mKeyguardViewMediator = keyguardViewMediator;
             mRemoteInputManager = notificationRemoteInputManager;
             mGroupManager = notificationGroupManager;
@@ -664,6 +640,7 @@
             mNotificationShelf = notificationShelf;
             mLockscreenUserManager = notificationLockscreenUserManager;
             mCommandQueue = commandQueue;
+            mPresenter = notificationPresenter;
         }
 
         private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowControllerTest.java
index f7a7e04..de26c70 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowControllerTest.java
@@ -74,14 +74,14 @@
                 ArgumentCaptor.forClass(WindowManager.LayoutParams.class);
         verify(mWindowManager).updateViewLayout(any(), captor.capture());
         int flag = captor.getValue().privateFlags
-                & WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+                & WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
         assertThat(flag).isNotEqualTo(0);
 
         reset(mWindowManager);
         mStatusBarWindowController.setDozing(false);
         verify(mWindowManager).updateViewLayout(any(), captor.capture());
         flag = captor.getValue().privateFlags
-                & WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+                & WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
         assertThat(flag).isEqualTo(0);
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
index 445a194..46335dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarWindowViewTest.java
@@ -17,11 +17,11 @@
 package com.android.systemui.statusbar.phone;
 
 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.os.SystemClock;
-import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 import android.view.MotionEvent;
@@ -31,6 +31,7 @@
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -43,11 +44,14 @@
     private StatusBarWindowView mView;
     private StatusBar mStatusBar;
     private DragDownHelper mDragDownHelper;
+    private NotificationStackScrollLayout mStackScrollLayout;
 
     @Before
     public void setUp() {
         mDependency.injectMockDependency(StatusBarStateController.class);
-        mView = new StatusBarWindowView(getContext(), null);
+        mView = spy(new StatusBarWindowView(getContext(), null));
+        mStackScrollLayout = mock(NotificationStackScrollLayout.class);
+        when(mView.getStackScrollLayout()).thenReturn(mStackScrollLayout);
         mStatusBar = mock(StatusBar.class);
         mView.setService(mStatusBar);
         mDragDownHelper = mock(DragDownHelper.class);
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 01e6307..4534ebe 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
@@ -41,7 +41,7 @@
 import android.widget.Button;
 import android.widget.LinearLayout;
 
-import com.android.keyguard.KeyguardHostView.OnDismissAction;
+import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.notification.NotificationData;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
index 469bdc0..77df791 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/AsyncSensorManagerTest.java
@@ -18,6 +18,7 @@
 
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -28,6 +29,8 @@
 import android.testing.AndroidTestingRunner;
 
 import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.SensorManagerPlugin;
+import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.utils.hardware.FakeSensorManager;
 
 import org.junit.Before;
@@ -42,9 +45,11 @@
     private FakeSensorManager mFakeSensorManager;
     private SensorEventListener mListener;
     private FakeSensorManager.MockProximitySensor mSensor;
+    private PluginManager mPluginManager;
 
     @Before
     public void setUp() throws Exception {
+        mPluginManager = mock(PluginManager.class);
         mFakeSensorManager = new FakeSensorManager(mContext);
         mAsyncSensorManager = new TestableAsyncSensorManager(mFakeSensorManager);
         mSensor = mFakeSensorManager.getMockProximitySensor();
@@ -86,9 +91,15 @@
         verifyNoMoreInteractions(mListener);
     }
 
+    @Test
+    public void registersPlugin_whenLoaded() {
+        verify(mPluginManager).addPluginListener(eq(mAsyncSensorManager),
+                eq(SensorManagerPlugin.class), eq(true) /* allowMultiple */);
+    }
+
     private class TestableAsyncSensorManager extends AsyncSensorManager {
         public TestableAsyncSensorManager(SensorManager sensorManager) {
-            super(sensorManager);
+            super(sensorManager, mPluginManager);
         }
 
         public void waitUntilRequestsCompleted() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
index 51b86c2..95c7a4d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeKeyguardMonitor.java
@@ -62,6 +62,11 @@
     }
 
     @Override
+    public boolean isLaunchTransitionFadingAway() {
+        return false;
+    }
+
+    @Override
     public long getKeyguardFadingAwayDuration() {
         return 0;
     }
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-km/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-km/strings.xml
index feb66be..fb0d88e 100644
--- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-km/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-km/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"ស្នាមចោះ​នៅជ្រុង"</string>
+    <string name="display_cutout_emulation_overlay" msgid="1677693377327336341">"សក់សេះនៅជ្រុង"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-km/strings.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-km/strings.xml
index 8a7fcec..1553594 100644
--- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-km/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-km/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"ស្នាមចោះ​ភ្លោះ"</string>
+    <string name="display_cutout_emulation_overlay" msgid="5323179900047630217">"សក់សេះ​ភ្លោះ"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-km/strings.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-km/strings.xml
index 959c9986..97e867f 100644
--- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-km/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-km/strings.xml
@@ -19,5 +19,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="3947428012427075896">"ស្នាមចោះ​តូច"</string>
+    <string name="display_cutout_emulation_overlay" msgid="3947428012427075896">"សក់សេះ​តូច"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-km/strings.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-km/strings.xml
index eba93ef..5a01a62 100644
--- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-km/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-km/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"ស្នាមចោះ​ជ្រៅ"</string>
+    <string name="display_cutout_emulation_overlay" msgid="6424539415439220018">"សក់សេះវែង"</string>
 </resources>
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-km/strings.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-km/strings.xml
index a2493a0..7325a73 100644
--- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-km/strings.xml
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-km/strings.xml
@@ -17,5 +17,5 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="display_cutout_emulation_overlay" msgid="4043478945358357737">"ស្នាមចោះ​ធំ"</string>
+    <string name="display_cutout_emulation_overlay" msgid="4043478945358357737">"សក់សេះ​ធំ"</string>
 </resources>
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 5e87707..da1fee3 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -6549,6 +6549,26 @@
     // Subtype: The importance of a notification has been changed
     ADJUSTMENT_KEY_IMPORTANCE = 1580;
 
+    // OPEN: Settings > Network & internet > Mobile network > Choose network
+    // CATEGORY: SETTINGS
+    // OS: Q
+    MOBILE_NETWORK_SELECT = 1581;
+
+    // OPEN: Settings > Network & internet > Mobile network > Mobile Data > Dialog
+    // CATEGORY: SETTINGS
+    // OS: Q
+    MOBILE_DATA_DIALOG = 1582;
+
+    // OPEN: Settings > Network & internet > Mobile network > Data roaming > Dialog
+    // CATEGORY: SETTINGS
+    // OS: Q
+    MOBILE_ROAMING_DIALOG = 1583;
+
+    // OPEN: Settings > Display > Lock screen display > On lock screen
+    // CATEGORY: SETTINGS
+    // OS: Q
+    LOCK_SCREEN_NOTIFICATION_CONTENT = 1584;
+
     // ---- End Q Constants, all Q constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 46c515f..ebd9e77 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -216,7 +216,7 @@
          * Called back to notify system that the client has changed
          * @param serviceInfoChanged True if the service's AccessibilityServiceInfo changed.
          */
-        void onClientChange(boolean serviceInfoChanged);
+        void onClientChangeLocked(boolean serviceInfoChanged);
 
         int getCurrentUserIdLocked();
 
@@ -363,7 +363,7 @@
                 } else {
                     setDynamicallyConfigurableProperties(info);
                 }
-                mSystemSupport.onClientChange(true);
+                mSystemSupport.onClientChangeLocked(true);
             }
         } finally {
             Binder.restoreCallingIdentity(identity);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 9bee8db..fbceade 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -254,7 +254,7 @@
 
     private final UserManager mUserManager;
 
-    private final UiAutomationManager mUiAutomationManager = new UiAutomationManager();
+    private final UiAutomationManager mUiAutomationManager = new UiAutomationManager(mLock);
 
     private int mCurrentUserId = UserHandle.USER_SYSTEM;
 
@@ -379,25 +379,20 @@
 
             @Override
             public void onPackageUpdateFinished(String packageName, int uid) {
-                // Unbind all services from this package, and then update the user state to
-                // re-bind new versions of them.
+                // The package should already be removed from mBoundServices, and added into
+                // mBindingServices in binderDied() during updating. Remove services from  this
+                // package from mBindingServices, and then update the user state to re-bind new
+                // versions of them.
                 synchronized (mLock) {
                     final int userId = getChangingUserId();
                     if (userId != mCurrentUserId) {
                         return;
                     }
                     UserState userState = getUserStateLocked(userId);
-                    boolean unboundAService = false;
-                    for (int i = userState.mBoundServices.size() - 1; i >= 0; i--) {
-                        AccessibilityServiceConnection boundService =
-                                userState.mBoundServices.get(i);
-                        String servicePkg = boundService.mComponentName.getPackageName();
-                        if (servicePkg.equals(packageName)) {
-                            boundService.unbindLocked();
-                            unboundAService = true;
-                        }
-                    }
-                    if (unboundAService) {
+                    boolean reboundAService = userState.mBindingServices.removeIf(
+                            component -> component != null
+                                    && component.getPackageName().equals(packageName));
+                    if (reboundAService) {
                         onUserStateChangedLocked(userState);
                     }
                 }
@@ -419,6 +414,7 @@
                         String compPkg = comp.getPackageName();
                         if (compPkg.equals(packageName)) {
                             it.remove();
+                            userState.mBindingServices.remove(comp);
                             // Update the enabled services setting.
                             persistComponentNamesToSettingLocked(
                                     Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
@@ -457,6 +453,7 @@
                                     return true;
                                 }
                                 it.remove();
+                                userState.mBindingServices.remove(comp);
                                 persistComponentNamesToSettingLocked(
                                         Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
                                         userState.mEnabledServices, userId);
@@ -833,7 +830,7 @@
 
         synchronized (mLock) {
             mUiAutomationManager.registerUiTestAutomationServiceLocked(owner, serviceClient,
-                    mContext, accessibilityServiceInfo, sIdCounter++, mMainHandler, mLock,
+                    mContext, accessibilityServiceInfo, sIdCounter++, mMainHandler,
                     mSecurityPolicy, this, mWindowManagerService, mGlobalActionPerformer, flags);
             onUserStateChangedLocked(getCurrentUserStateLocked());
         }
@@ -2633,7 +2630,7 @@
         final List<Integer> outsideWindowsIds;
         final List<RemoteAccessibilityConnection> connectionList = new ArrayList<>();
         synchronized (mLock) {
-            outsideWindowsIds = mSecurityPolicy.getWatchOutsideTouchWindowId(targetWindowId);
+            outsideWindowsIds = mSecurityPolicy.getWatchOutsideTouchWindowIdLocked(targetWindowId);
             for (int i = 0; i < outsideWindowsIds.size(); i++) {
                 connectionList.add(getConnectionLocked(outsideWindowsIds.get(i)));
             }
@@ -2790,7 +2787,7 @@
     }
 
     @Override
-    public void onClientChange(boolean serviceInfoChanged) {
+    public void onClientChangeLocked(boolean serviceInfoChanged) {
         AccessibilityManagerService.UserState userState = getUserStateLocked(mCurrentUserId);
         onUserStateChangedLocked(userState);
         if (serviceInfoChanged) {
@@ -3687,13 +3684,13 @@
             return mWindowInfoById.get(windowId);
         }
 
-        private List<Integer> getWatchOutsideTouchWindowId(int targetWindowId) {
-            if (mWindowInfoById != null && mHasWatchOutsideTouchWindow) {
+        private List<Integer> getWatchOutsideTouchWindowIdLocked(int targetWindowId) {
+            final WindowInfo targetWindow = mWindowInfoById.get(targetWindowId);
+            if (targetWindow != null && mWindowInfoById != null && mHasWatchOutsideTouchWindow) {
                 final List<Integer> outsideWindowsId = new ArrayList<>();
-                final WindowInfo targetWindow = mWindowInfoById.get(targetWindowId);
                 for (int i = 0; i < mWindowInfoById.size(); i++) {
                     WindowInfo window = mWindowInfoById.valueAt(i);
-                    if (window.layer < targetWindow.layer
+                    if (window != null && window.layer < targetWindow.layer
                             && window.hasFlagWatchOutsideTouch) {
                         outsideWindowsId.add(mWindowInfoById.keyAt(i));
                     }
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index e0eb269..2396ded 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -16,8 +16,6 @@
 
 package com.android.server.accessibility;
 
-import static android.provider.Settings.Secure.SHOW_MODE_AUTO;
-
 import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -133,7 +131,7 @@
                 } finally {
                     Binder.restoreCallingIdentity(identity);
                 }
-                mSystemSupport.onClientChange(false);
+                mSystemSupport.onClientChangeLocked(false);
             }
         }
     }
@@ -158,7 +156,7 @@
             UserState userState = mUserStateWeakReference.get();
             if (userState == null) return;
             userState.addServiceLocked(this);
-            mSystemSupport.onClientChange(false);
+            mSystemSupport.onClientChangeLocked(false);
             // Initialize the service on the main handler after we're done setting up for
             // the new configuration (for example, initializing the input filter).
             mMainHandler.sendMessage(obtainMessage(
@@ -253,13 +251,13 @@
                 return;
             }
             mWasConnectedAndDied = true;
-            mSystemSupport.getKeyEventDispatcher().flush(this);
             UserState userState = mUserStateWeakReference.get();
             if (userState != null) {
                 userState.serviceDisconnectedLocked(this);
             }
+            resetLocked();
             mSystemSupport.getMagnificationController().resetIfNeeded(mId);
-            mSystemSupport.onClientChange(false);
+            mSystemSupport.onClientChangeLocked(false);
         }
     }
 
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index b938f3b..17bf570 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -32,6 +32,8 @@
 import android.text.TextUtils;
 import android.util.MathUtils;
 import android.util.Slog;
+import android.util.SparseArray;
+import android.view.Display;
 import android.view.MagnificationSpec;
 import android.view.View;
 import android.view.animation.DecelerateInterpolator;
@@ -40,6 +42,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.os.SomeArgs;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.LocalServices;
 import com.android.server.wm.WindowManagerInternal;
 
@@ -55,7 +58,7 @@
  * magnification region. If a value is out of bounds, it will be adjusted to guarantee these
  * constraints.
  */
-public class MagnificationController implements Handler.Callback {
+public class MagnificationController {
     private static final boolean DEBUG = false;
     private static final String LOG_TAG = "MagnificationController";
 
@@ -64,90 +67,553 @@
 
     private static final boolean DEBUG_SET_MAGNIFICATION_SPEC = false;
 
-    private static final int INVALID_ID = -1;
-
     private static final float DEFAULT_MAGNIFICATION_SCALE = 2.0f;
 
-    // Messages
-    private static final int MSG_SEND_SPEC_TO_ANIMATION = 1;
-    private static final int MSG_SCREEN_TURNED_OFF = 2;
-    private static final int MSG_ON_MAGNIFIED_BOUNDS_CHANGED = 3;
-    private static final int MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED = 4;
-    private static final int MSG_ON_USER_CONTEXT_CHANGED = 5;
-
     private final Object mLock;
 
-    /**
-     * The current magnification spec. If an animation is running, this
-     * reflects the end state.
-     */
-    private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain();
-
-    private final Region mMagnificationRegion = Region.obtain();
-    private final Rect mMagnificationBounds = new Rect();
-
-    private final Rect mTempRect = new Rect();
-    private final Rect mTempRect1 = new Rect();
-
     private final AccessibilityManagerService mAms;
 
     private final SettingsBridge mSettingsBridge;
 
     private final ScreenStateObserver mScreenStateObserver;
 
-    private final SpecAnimationBridge mSpecAnimationBridge;
-
-    private final WindowManagerInternal.MagnificationCallbacks mWMCallbacks =
-            new WindowManagerInternal.MagnificationCallbacks () {
-                @Override
-                public void onMagnificationRegionChanged(Region region) {
-                    final SomeArgs args = SomeArgs.obtain();
-                    args.arg1 = Region.obtain(region);
-                    mHandler.obtainMessage(MSG_ON_MAGNIFIED_BOUNDS_CHANGED, args).sendToTarget();
-                }
-
-                @Override
-                public void onRectangleOnScreenRequested(int left, int top, int right, int bottom) {
-                    final SomeArgs args = SomeArgs.obtain();
-                    args.argi1 = left;
-                    args.argi2 = top;
-                    args.argi3 = right;
-                    args.argi4 = bottom;
-                    mHandler.obtainMessage(MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED, args)
-                            .sendToTarget();
-                }
-
-                @Override
-                public void onRotationChanged(int rotation) {
-                    // Treat as context change and reset
-                    mHandler.sendEmptyMessage(MSG_ON_USER_CONTEXT_CHANGED);
-                }
-
-                @Override
-                public void onUserContextChanged() {
-                    mHandler.sendEmptyMessage(MSG_ON_USER_CONTEXT_CHANGED);
-                }
-            };
-
     private int mUserId;
 
     private final long mMainThreadId;
 
     private Handler mHandler;
 
-    private int mIdOfLastServiceToMagnify = INVALID_ID;
-
     private final WindowManagerInternal mWindowManager;
 
-    // Flag indicating that we are registered with window manager.
-    @VisibleForTesting boolean mRegistered;
+    private final DisplayMagnification mDisplay;
 
-    private boolean mUnregisterPending;
+    /**
+     * This class implements {@link WindowManagerInternal.MagnificationCallbacks} and holds
+     * magnification information per display.
+     */
+    private final class DisplayMagnification implements
+            WindowManagerInternal.MagnificationCallbacks {
+        /**
+         * The current magnification spec. If an animation is running, this
+         * reflects the end state.
+         */
+        private final MagnificationSpec mCurrentMagnificationSpec = MagnificationSpec.obtain();
+
+        private final Region mMagnificationRegion = Region.obtain();
+        private final Rect mMagnificationBounds = new Rect();
+
+        private final Rect mTempRect = new Rect();
+        private final Rect mTempRect1 = new Rect();
+
+        private final SpecAnimationBridge mSpecAnimationBridge;
+
+        // Flag indicating that we are registered with window manager.
+        private boolean mRegistered;
+        private boolean mUnregisterPending;
+
+        private final int mDisplayId;
+
+        private static final int INVALID_ID = -1;
+        private int mIdOfLastServiceToMagnify = INVALID_ID;
+
+
+        DisplayMagnification(int displayId, SpecAnimationBridge specAnimation) {
+            mDisplayId = displayId;
+            mSpecAnimationBridge = specAnimation;
+        }
+
+        void register() {
+            synchronized (mLock) {
+                if (!mRegistered) {
+                    mWindowManager.setMagnificationCallbacks(this);
+                    mSpecAnimationBridge.setEnabled(true);
+                    // Obtain initial state.
+                    mWindowManager.getMagnificationRegion(mMagnificationRegion);
+                    mMagnificationRegion.getBounds(mMagnificationBounds);
+                    mRegistered = true;
+                }
+            }
+        }
+
+        void unregister() {
+            synchronized (mLock) {
+                if (!isMagnifying()) {
+                    unregisterInternalLocked();
+                } else {
+                    mUnregisterPending = true;
+                    reset(true);
+                }
+            }
+        }
+
+        boolean isRegisteredLocked() {
+            return mRegistered;
+        }
+
+
+        float getScale() {
+            return mCurrentMagnificationSpec.scale;
+        }
+
+        float getOffsetX() {
+            return mCurrentMagnificationSpec.offsetX;
+        }
+
+        float getCenterX() {
+            synchronized (mLock) {
+                return (mMagnificationBounds.width() / 2.0f
+                        + mMagnificationBounds.left - getOffsetX()) / getScale();
+            }
+        }
+
+        float getCenterY() {
+            synchronized (mLock) {
+                return (mMagnificationBounds.height() / 2.0f
+                        + mMagnificationBounds.top - getOffsetY()) / getScale();
+            }
+        }
+
+        /**
+         * Returns the scale currently used by the window manager. If an
+         * animation is in progress, this reflects the current state of the
+         * animation.
+         *
+         * @return the scale currently used by the window manager
+         */
+        float getSentScale() {
+            return mSpecAnimationBridge.mSentMagnificationSpec.scale;
+        }
+
+        /**
+         * Returns the X offset currently used by the window manager. If an
+         * animation is in progress, this reflects the current state of the
+         * animation.
+         *
+         * @return the X offset currently used by the window manager
+         */
+        float getSentOffsetX() {
+            return mSpecAnimationBridge.mSentMagnificationSpec.offsetX;
+        }
+
+        /**
+         * Returns the Y offset currently used by the window manager. If an
+         * animation is in progress, this reflects the current state of the
+         * animation.
+         *
+         * @return the Y offset currently used by the window manager
+         */
+        float getSentOffsetY() {
+            return mSpecAnimationBridge.mSentMagnificationSpec.offsetY;
+        }
+
+        boolean resetIfNeeded(boolean animate) {
+            synchronized (mLock) {
+                if (isMagnifying()) {
+                    reset(animate);
+                    return true;
+                }
+                return false;
+            }
+        }
+
+        float getOffsetY() {
+            return mCurrentMagnificationSpec.offsetY;
+        }
+
+        boolean isMagnifying() {
+            return mCurrentMagnificationSpec.scale > 1.0f;
+        }
+
+        void unregisterInternalLocked() {
+            if (mRegistered) {
+                mSpecAnimationBridge.setEnabled(false);
+                mWindowManager.setMagnificationCallbacks(null);
+                mMagnificationRegion.setEmpty();
+
+                mRegistered = false;
+            }
+            mUnregisterPending = false;
+        }
+
+
+        @Override
+        public void onMagnificationRegionChanged(Region magnificationRegion) {
+            final Message m = PooledLambda.obtainMessage(
+                    DisplayMagnification.this::updateMagnificationRegion,
+                    Region.obtain(magnificationRegion));
+            mHandler.sendMessage(m);
+        }
+
+        @Override
+        public void onRectangleOnScreenRequested(int left, int top, int right, int bottom) {
+            final Message m = PooledLambda.obtainMessage(
+                    DisplayMagnification.this::requestRectangleOnScreen, left, top, right, bottom);
+            mHandler.sendMessage(m);
+        }
+
+        @Override
+        public void onRotationChanged(int rotation) {
+            // Treat as context change and reset
+            final Message m = PooledLambda.obtainMessage(DisplayMagnification.this::resetIfNeeded,
+                    true);
+            mHandler.sendMessage(m);
+        }
+
+        @Override
+        public void onUserContextChanged() {
+            final Message m = PooledLambda.obtainMessage(DisplayMagnification.this::resetIfNeeded,
+                    true);
+            mHandler.sendMessage(m);
+        }
+
+        /**
+         * Update our copy of the current magnification region
+         *
+         * @param magnified the magnified region
+         */
+        void updateMagnificationRegion(Region magnified) {
+            synchronized (mLock) {
+                if (!mRegistered) {
+                    // Don't update if we've unregistered
+                    return;
+                }
+                if (!mMagnificationRegion.equals(magnified)) {
+                    mMagnificationRegion.set(magnified);
+                    mMagnificationRegion.getBounds(mMagnificationBounds);
+                    // It's possible that our magnification spec is invalid with the new bounds.
+                    // Adjust the current spec's offsets if necessary.
+                    if (updateCurrentSpecWithOffsetsLocked(
+                            mCurrentMagnificationSpec.offsetX, mCurrentMagnificationSpec.offsetY)) {
+                        sendSpecToAnimation(mCurrentMagnificationSpec, false);
+                    }
+                    onMagnificationChangedLocked();
+                }
+                magnified.recycle();
+            }
+        }
+
+        void sendSpecToAnimation(MagnificationSpec spec, boolean animate) {
+            if (DEBUG) {
+                Slog.i(LOG_TAG,
+                        "sendSpecToAnimation(spec = " + spec + ", animate = " + animate + ")");
+            }
+            if (Thread.currentThread().getId() == mMainThreadId) {
+                mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
+            } else {
+                final Message m = PooledLambda.obtainMessage(
+                        this.mSpecAnimationBridge::updateSentSpecMainThread, spec, animate);
+                mHandler.sendMessage(m);
+            }
+        }
+
+        /**
+         * Get the ID of the last service that changed the magnification spec.
+         *
+         * @return The id
+         */
+        int getIdOfLastServiceToMagnify() {
+            return mIdOfLastServiceToMagnify;
+        }
+
+        void onMagnificationChangedLocked() {
+            mAms.notifyMagnificationChanged(mMagnificationRegion,
+                    getScale(), getCenterX(), getCenterY());
+            if (mUnregisterPending && !isMagnifying()) {
+                unregisterInternalLocked();
+            }
+        }
+
+        boolean magnificationRegionContains(float x, float y) {
+            synchronized (mLock) {
+                return mMagnificationRegion.contains((int) x, (int) y);
+
+            }
+        }
+
+        void getMagnificationBounds(@NonNull Rect outBounds) {
+            synchronized (mLock) {
+                outBounds.set(mMagnificationBounds);
+            }
+        }
+
+        void getMagnificationRegion(@NonNull Region outRegion) {
+            synchronized (mLock) {
+                outRegion.set(mMagnificationRegion);
+            }
+        }
+
+        void requestRectangleOnScreen(int left, int top, int right, int bottom) {
+            synchronized (mLock) {
+                final Rect magnifiedFrame = mTempRect;
+                getMagnificationBounds(magnifiedFrame);
+                if (!magnifiedFrame.intersects(left, top, right, bottom)) {
+                    return;
+                }
+
+                final Rect magnifFrameInScreenCoords = mTempRect1;
+                getMagnifiedFrameInContentCoordsLocked(magnifFrameInScreenCoords);
+
+                final float scrollX;
+                final float scrollY;
+                if (right - left > magnifFrameInScreenCoords.width()) {
+                    final int direction = TextUtils
+                            .getLayoutDirectionFromLocale(Locale.getDefault());
+                    if (direction == View.LAYOUT_DIRECTION_LTR) {
+                        scrollX = left - magnifFrameInScreenCoords.left;
+                    } else {
+                        scrollX = right - magnifFrameInScreenCoords.right;
+                    }
+                } else if (left < magnifFrameInScreenCoords.left) {
+                    scrollX = left - magnifFrameInScreenCoords.left;
+                } else if (right > magnifFrameInScreenCoords.right) {
+                    scrollX = right - magnifFrameInScreenCoords.right;
+                } else {
+                    scrollX = 0;
+                }
+
+                if (bottom - top > magnifFrameInScreenCoords.height()) {
+                    scrollY = top - magnifFrameInScreenCoords.top;
+                } else if (top < magnifFrameInScreenCoords.top) {
+                    scrollY = top - magnifFrameInScreenCoords.top;
+                } else if (bottom > magnifFrameInScreenCoords.bottom) {
+                    scrollY = bottom - magnifFrameInScreenCoords.bottom;
+                } else {
+                    scrollY = 0;
+                }
+
+                final float scale = getScale();
+                offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_ID);
+            }
+        }
+
+        void getMagnifiedFrameInContentCoordsLocked(Rect outFrame) {
+            final float scale = getSentScale();
+            final float offsetX = getSentOffsetX();
+            final float offsetY = getSentOffsetY();
+            getMagnificationBounds(outFrame);
+            outFrame.offset((int) -offsetX, (int) -offsetY);
+            outFrame.scale(1.0f / scale);
+        }
+
+        /**
+         * Resets magnification if last magnifying service is disabled.
+         *
+         * @param connectionId the connection ID be disabled.
+         * @return {@code true} on success, {@code false} on failure
+         */
+        boolean resetIfNeeded(int connectionId) {
+            if (mIdOfLastServiceToMagnify == connectionId) {
+                return resetIfNeeded(true /*animate*/);
+            }
+            return false;
+        }
+
+        void setForceShowMagnifiableBounds(boolean show) {
+            if (mRegistered) {
+                mWindowManager.setForceShowMagnifiableBounds(show);
+            }
+        }
+
+        boolean reset(boolean animate) {
+            synchronized (mLock) {
+                if (!mRegistered) {
+                    return false;
+                }
+                final MagnificationSpec spec = mCurrentMagnificationSpec;
+                final boolean changed = !spec.isNop();
+                if (changed) {
+                    spec.clear();
+                    onMagnificationChangedLocked();
+                }
+                mIdOfLastServiceToMagnify = INVALID_ID;
+                sendSpecToAnimation(spec, animate);
+                return changed;
+            }
+        }
+
+
+        boolean setScale(float scale, float pivotX, float pivotY,
+                boolean animate, int id) {
+
+            synchronized (mLock) {
+                if (!mRegistered) {
+                    return false;
+                }
+                // Constrain scale immediately for use in the pivot calculations.
+                scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+
+                final Rect viewport = mTempRect;
+                mMagnificationRegion.getBounds(viewport);
+                final MagnificationSpec spec = mCurrentMagnificationSpec;
+                final float oldScale = spec.scale;
+                final float oldCenterX
+                        = (viewport.width() / 2.0f - spec.offsetX + viewport.left) / oldScale;
+                final float oldCenterY
+                        = (viewport.height() / 2.0f - spec.offsetY + viewport.top) / oldScale;
+                final float normPivotX = (pivotX - spec.offsetX) / oldScale;
+                final float normPivotY = (pivotY - spec.offsetY) / oldScale;
+                final float offsetX = (oldCenterX - normPivotX) * (oldScale / scale);
+                final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale);
+                final float centerX = normPivotX + offsetX;
+                final float centerY = normPivotY + offsetY;
+                mIdOfLastServiceToMagnify = id;
+
+                return setScaleAndCenter(scale, centerX, centerY, animate, id);
+            }
+        }
+
+        boolean setScaleAndCenter(float scale, float centerX, float centerY,
+                boolean animate, int id) {
+
+            synchronized (mLock) {
+                if (!mRegistered) {
+                    return false;
+                }
+                if (DEBUG) {
+                    Slog.i(LOG_TAG,
+                            "setScaleAndCenterLocked(scale = " + scale + ", centerX = " + centerX
+                                    + ", centerY = " + centerY + ", animate = " + animate
+                                    + ", id = " + id
+                                    + ")");
+                }
+                final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
+                sendSpecToAnimation(mCurrentMagnificationSpec, animate);
+                if (isMagnifying() && (id != INVALID_ID)) {
+                    mIdOfLastServiceToMagnify = id;
+                }
+                return changed;
+            }
+        }
+
+        /**
+         * Updates the current magnification spec.
+         *
+         * @param scale the magnification scale
+         * @param centerX the unscaled, screen-relative X coordinate of the center
+         *                of the viewport, or {@link Float#NaN} to leave unchanged
+         * @param centerY the unscaled, screen-relative Y coordinate of the center
+         *                of the viewport, or {@link Float#NaN} to leave unchanged
+         * @return {@code true} if the magnification spec changed or {@code false}
+         *         otherwise
+         */
+        boolean updateMagnificationSpecLocked(float scale, float centerX, float centerY) {
+            // Handle defaults.
+            if (Float.isNaN(centerX)) {
+                centerX = getCenterX();
+            }
+            if (Float.isNaN(centerY)) {
+                centerY = getCenterY();
+            }
+            if (Float.isNaN(scale)) {
+                scale = getScale();
+            }
+
+            // Compute changes.
+            boolean changed = false;
+
+            final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
+            if (Float.compare(mCurrentMagnificationSpec.scale, normScale) != 0) {
+                mCurrentMagnificationSpec.scale = normScale;
+                changed = true;
+            }
+
+            final float nonNormOffsetX = mMagnificationBounds.width() / 2.0f
+                    + mMagnificationBounds.left - centerX * normScale;
+            final float nonNormOffsetY = mMagnificationBounds.height() / 2.0f
+                    + mMagnificationBounds.top - centerY * normScale;
+            changed |= updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY);
+
+            if (changed) {
+                onMagnificationChangedLocked();
+            }
+
+            return changed;
+        }
+
+        void offsetMagnifiedRegion(float offsetX, float offsetY, int id) {
+            synchronized (mLock) {
+                if (!mRegistered) {
+                    return;
+                }
+
+                final float nonNormOffsetX = mCurrentMagnificationSpec.offsetX - offsetX;
+                final float nonNormOffsetY = mCurrentMagnificationSpec.offsetY - offsetY;
+                if (updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY)) {
+                    onMagnificationChangedLocked();
+                }
+                if (id != INVALID_ID) {
+                    mIdOfLastServiceToMagnify = id;
+                }
+                sendSpecToAnimation(mCurrentMagnificationSpec, false);
+            }
+        }
+
+        boolean updateCurrentSpecWithOffsetsLocked(float nonNormOffsetX, float nonNormOffsetY) {
+            if (DEBUG) {
+                Slog.i(LOG_TAG,
+                        "updateCurrentSpecWithOffsetsLocked(nonNormOffsetX = " + nonNormOffsetX
+                                + ", nonNormOffsetY = " + nonNormOffsetY + ")");
+            }
+            boolean changed = false;
+            final float offsetX = MathUtils.constrain(
+                    nonNormOffsetX, getMinOffsetXLocked(), getMaxOffsetXLocked());
+            if (Float.compare(mCurrentMagnificationSpec.offsetX, offsetX) != 0) {
+                mCurrentMagnificationSpec.offsetX = offsetX;
+                changed = true;
+            }
+            final float offsetY = MathUtils.constrain(
+                    nonNormOffsetY, getMinOffsetYLocked(), getMaxOffsetYLocked());
+            if (Float.compare(mCurrentMagnificationSpec.offsetY, offsetY) != 0) {
+                mCurrentMagnificationSpec.offsetY = offsetY;
+                changed = true;
+            }
+            return changed;
+        }
+
+        float getMinOffsetXLocked() {
+            final float viewportWidth = mMagnificationBounds.width();
+            final float viewportLeft = mMagnificationBounds.left;
+            return (viewportLeft + viewportWidth) -
+                    (viewportLeft + viewportWidth) * mCurrentMagnificationSpec.scale;
+        }
+
+        float getMaxOffsetXLocked() {
+            return mMagnificationBounds.left -
+                    mMagnificationBounds.left * mCurrentMagnificationSpec.scale;
+        }
+
+        float getMinOffsetYLocked() {
+            final float viewportHeight = mMagnificationBounds.height();
+            final float viewportTop = mMagnificationBounds.top;
+            return (viewportTop + viewportHeight) -
+                    (viewportTop + viewportHeight) * mCurrentMagnificationSpec.scale;
+        }
+
+        float getMaxOffsetYLocked() {
+            return mMagnificationBounds.top -
+                    mMagnificationBounds.top * mCurrentMagnificationSpec.scale;
+        }
+
+        @Override
+        public String toString() {
+            return "DisplayMagnification{" +
+                    "mCurrentMagnificationSpec=" + mCurrentMagnificationSpec +
+                    ", mMagnificationRegion=" + mMagnificationRegion +
+                    ", mMagnificationBounds=" + mMagnificationBounds +
+                    ", mDisplayId=" + mDisplayId +
+                    ", mUserId=" + mUserId +
+                    ", mIdOfLastServiceToMagnify=" + mIdOfLastServiceToMagnify +
+                    ", mRegistered=" + mRegistered +
+                    ", mUnregisterPending=" + mUnregisterPending +
+                    '}';
+        }
+
+    }
 
     public MagnificationController(Context context, AccessibilityManagerService ams, Object lock) {
         this(context, ams, lock, null, LocalServices.getService(WindowManagerInternal.class),
                 new ValueAnimator(), new SettingsBridge(context.getContentResolver()));
-        mHandler = new Handler(context.getMainLooper(), this);
+        mHandler = new Handler(context.getMainLooper());
     }
 
     public MagnificationController(
@@ -164,9 +630,10 @@
         mAms = ams;
         mScreenStateObserver = new ScreenStateObserver(context, this);
         mLock = lock;
-        mSpecAnimationBridge = new SpecAnimationBridge(
-                context, mLock, mWindowManager, valueAnimator);
         mSettingsBridge = settingsBridge;
+        //TODO (multidisplay): Magnification is supported only for the default display.
+        mDisplay =  new DisplayMagnification(Display.DEFAULT_DISPLAY,
+                new SpecAnimationBridge(context, mLock, mWindowManager, valueAnimator));
     }
 
     /**
@@ -178,16 +645,9 @@
      */
     public void register() {
         synchronized (mLock) {
-            if (!mRegistered) {
-                mScreenStateObserver.register();
-                mWindowManager.setMagnificationCallbacks(mWMCallbacks);
-                mSpecAnimationBridge.setEnabled(true);
-                // Obtain initial state.
-                mWindowManager.getMagnificationRegion(mMagnificationRegion);
-                mMagnificationRegion.getBounds(mMagnificationBounds);
-                mRegistered = true;
-            }
+            mScreenStateObserver.register();
         }
+        mDisplay.register();
     }
 
     /**
@@ -196,33 +656,18 @@
      */
     public void unregister() {
         synchronized (mLock) {
-            if (!isMagnifying()) {
-                unregisterInternalLocked();
-            } else {
-                mUnregisterPending = true;
-                resetLocked(true);
-            }
+            mScreenStateObserver.unregister();
         }
+        mDisplay.unregister();
     }
-
+    
     /**
      * Check if we are registered. Note that we may be planning to unregister at any moment.
      *
      * @return {@code true} if the controller is registered. {@code false} otherwise.
      */
     public boolean isRegisteredLocked() {
-        return mRegistered;
-    }
-
-    private void unregisterInternalLocked() {
-        if (mRegistered) {
-            mSpecAnimationBridge.setEnabled(false);
-            mScreenStateObserver.unregister();
-            mWindowManager.setMagnificationCallbacks(null);
-            mMagnificationRegion.setEmpty();
-            mRegistered = false;
-        }
-        mUnregisterPending = false;
+        return mDisplay.isRegisteredLocked();
     }
 
     /**
@@ -230,32 +675,7 @@
      *         is > 1, {@code false} otherwise
      */
     public boolean isMagnifying() {
-        return mCurrentMagnificationSpec.scale > 1.0f;
-    }
-
-    /**
-     * Update our copy of the current magnification region
-     *
-     * @param magnified the magnified region
-     */
-    private void onMagnificationRegionChanged(Region magnified) {
-        synchronized (mLock) {
-            if (!mRegistered) {
-                // Don't update if we've unregistered
-                return;
-            }
-            if (!mMagnificationRegion.equals(magnified)) {
-                mMagnificationRegion.set(magnified);
-                mMagnificationRegion.getBounds(mMagnificationBounds);
-                // It's possible that our magnification spec is invalid with the new bounds.
-                // Adjust the current spec's offsets if necessary.
-                if (updateCurrentSpecWithOffsetsLocked(
-                        mCurrentMagnificationSpec.offsetX, mCurrentMagnificationSpec.offsetY)) {
-                    sendSpecToAnimation(mCurrentMagnificationSpec, false);
-                }
-                onMagnificationChangedLocked();
-            }
-        }
+        return mDisplay.isMagnifying();
     }
 
     /**
@@ -268,9 +688,8 @@
      *         magnified region, or {@code false} otherwise
      */
     public boolean magnificationRegionContains(float x, float y) {
-        synchronized (mLock) {
-            return mMagnificationRegion.contains((int) x, (int) y);
-        }
+        return mDisplay.magnificationRegionContains(x, y);
+
     }
 
     /**
@@ -282,9 +701,7 @@
      *                  region
      */
     public void getMagnificationBounds(@NonNull Rect outBounds) {
-        synchronized (mLock) {
-            outBounds.set(mMagnificationBounds);
-        }
+        mDisplay.getMagnificationBounds(outBounds);
     }
 
     /**
@@ -295,9 +712,7 @@
      * @param outRegion the region to populate
      */
     public void getMagnificationRegion(@NonNull Region outRegion) {
-        synchronized (mLock) {
-            outRegion.set(mMagnificationRegion);
-        }
+        mDisplay.getMagnificationRegion(outRegion);
     }
 
     /**
@@ -307,7 +722,7 @@
      * @return the scale
      */
     public float getScale() {
-        return mCurrentMagnificationSpec.scale;
+        return mDisplay.getScale();
     }
 
     /**
@@ -317,7 +732,7 @@
      * @return the X offset
      */
     public float getOffsetX() {
-        return mCurrentMagnificationSpec.offsetX;
+        return mDisplay.getOffsetX();
     }
 
 
@@ -328,10 +743,7 @@
      * @return the X coordinate
      */
     public float getCenterX() {
-        synchronized (mLock) {
-            return (mMagnificationBounds.width() / 2.0f
-                    + mMagnificationBounds.left - getOffsetX()) / getScale();
-        }
+        return mDisplay.getCenterX();
     }
 
     /**
@@ -341,7 +753,7 @@
      * @return the Y offset
      */
     public float getOffsetY() {
-        return mCurrentMagnificationSpec.offsetY;
+        return mDisplay.getOffsetY();
     }
 
     /**
@@ -351,43 +763,7 @@
      * @return the Y coordinate
      */
     public float getCenterY() {
-        synchronized (mLock) {
-            return (mMagnificationBounds.height() / 2.0f
-                    + mMagnificationBounds.top - getOffsetY()) / getScale();
-        }
-    }
-
-    /**
-     * Returns the scale currently used by the window manager. If an
-     * animation is in progress, this reflects the current state of the
-     * animation.
-     *
-     * @return the scale currently used by the window manager
-     */
-    private float getSentScale() {
-        return mSpecAnimationBridge.mSentMagnificationSpec.scale;
-    }
-
-    /**
-     * Returns the X offset currently used by the window manager. If an
-     * animation is in progress, this reflects the current state of the
-     * animation.
-     *
-     * @return the X offset currently used by the window manager
-     */
-    private float getSentOffsetX() {
-        return mSpecAnimationBridge.mSentMagnificationSpec.offsetX;
-    }
-
-    /**
-     * Returns the Y offset currently used by the window manager. If an
-     * animation is in progress, this reflects the current state of the
-     * animation.
-     *
-     * @return the Y offset currently used by the window manager
-     */
-    private float getSentOffsetY() {
-        return mSpecAnimationBridge.mSentMagnificationSpec.offsetY;
+        return mDisplay.getCenterY();
     }
 
     /**
@@ -400,24 +776,9 @@
      *         the spec did not change
      */
     public boolean reset(boolean animate) {
-        synchronized (mLock) {
-            return resetLocked(animate);
-        }
-    }
 
-    private boolean resetLocked(boolean animate) {
-        if (!mRegistered) {
-            return false;
-        }
-        final MagnificationSpec spec = mCurrentMagnificationSpec;
-        final boolean changed = !spec.isNop();
-        if (changed) {
-            spec.clear();
-            onMagnificationChangedLocked();
-        }
-        mIdOfLastServiceToMagnify = INVALID_ID;
-        sendSpecToAnimation(spec, animate);
-        return changed;
+        return mDisplay.reset(animate);
+
     }
 
     /**
@@ -435,30 +796,8 @@
      *         the spec did not change
      */
     public boolean setScale(float scale, float pivotX, float pivotY, boolean animate, int id) {
-        synchronized (mLock) {
-            if (!mRegistered) {
-                return false;
-            }
-            // Constrain scale immediately for use in the pivot calculations.
-            scale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
-
-            final Rect viewport = mTempRect;
-            mMagnificationRegion.getBounds(viewport);
-            final MagnificationSpec spec = mCurrentMagnificationSpec;
-            final float oldScale = spec.scale;
-            final float oldCenterX
-                    = (viewport.width() / 2.0f - spec.offsetX + viewport.left) / oldScale;
-            final float oldCenterY
-                    = (viewport.height() / 2.0f - spec.offsetY + viewport.top) / oldScale;
-            final float normPivotX = (pivotX - spec.offsetX) / oldScale;
-            final float normPivotY = (pivotY - spec.offsetY) / oldScale;
-            final float offsetX = (oldCenterX - normPivotX) * (oldScale / scale);
-            final float offsetY = (oldCenterY - normPivotY) * (oldScale / scale);
-            final float centerX = normPivotX + offsetX;
-            final float centerY = normPivotY + offsetY;
-            mIdOfLastServiceToMagnify = id;
-            return setScaleAndCenterLocked(scale, centerX, centerY, animate, id);
-        }
+            return mDisplay.
+                    setScale(scale, pivotX, pivotY, animate, id);
     }
 
     /**
@@ -471,17 +810,13 @@
      *                center
      * @param animate {@code true} to animate the transition, {@code false}
      *                to transition immediately
-     * @param id the ID of the service requesting the change
+     * @param id      the ID of the service requesting the change
      * @return {@code true} if the magnification spec changed, {@code false} if
-     *         the spec did not change
+     * the spec did not change
      */
     public boolean setCenter(float centerX, float centerY, boolean animate, int id) {
-        synchronized (mLock) {
-            if (!mRegistered) {
-                return false;
-            }
-            return setScaleAndCenterLocked(Float.NaN, centerX, centerY, animate, id);
-        }
+            return mDisplay.
+                    setScaleAndCenter(Float.NaN, centerX, centerY, animate, id);
     }
 
     /**
@@ -502,28 +837,8 @@
      */
     public boolean setScaleAndCenter(
             float scale, float centerX, float centerY, boolean animate, int id) {
-        synchronized (mLock) {
-            if (!mRegistered) {
-                return false;
-            }
-            return setScaleAndCenterLocked(scale, centerX, centerY, animate, id);
-        }
-    }
-
-    private boolean setScaleAndCenterLocked(float scale, float centerX, float centerY,
-            boolean animate, int id) {
-        if (DEBUG) {
-            Slog.i(LOG_TAG,
-                    "setScaleAndCenterLocked(scale = " + scale + ", centerX = " + centerX
-                            + ", centerY = " + centerY + ", animate = " + animate + ", id = " + id
-                            + ")");
-        }
-        final boolean changed = updateMagnificationSpecLocked(scale, centerX, centerY);
-        sendSpecToAnimation(mCurrentMagnificationSpec, animate);
-        if (isMagnifying() && (id != INVALID_ID)) {
-            mIdOfLastServiceToMagnify = id;
-        }
-        return changed;
+        return mDisplay.
+                setScaleAndCenter(scale, centerX, centerY, animate, id);
     }
 
     /**
@@ -531,27 +846,14 @@
      * opposite direction as the offsets passed in here.
      *
      * @param offsetX the amount in pixels to offset the region in the X direction, in current
-     * screen pixels.
+     *                screen pixels.
      * @param offsetY the amount in pixels to offset the region in the Y direction, in current
-     * screen pixels.
-     * @param id the ID of the service requesting the change
+     *                screen pixels.
+     * @param id      the ID of the service requesting the change
      */
     public void offsetMagnifiedRegion(float offsetX, float offsetY, int id) {
-        synchronized (mLock) {
-            if (!mRegistered) {
-                return;
-            }
-
-            final float nonNormOffsetX = mCurrentMagnificationSpec.offsetX - offsetX;
-            final float nonNormOffsetY = mCurrentMagnificationSpec.offsetY - offsetY;
-            if (updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY)) {
-                onMagnificationChangedLocked();
-            }
-            if (id != INVALID_ID) {
-                mIdOfLastServiceToMagnify = id;
-            }
-            sendSpecToAnimation(mCurrentMagnificationSpec, false);
-        }
+        mDisplay.offsetMagnifiedRegion(offsetX, offsetY,
+                id);
     }
 
     /**
@@ -560,28 +862,26 @@
      * @return The id
      */
     public int getIdOfLastServiceToMagnify() {
-        return mIdOfLastServiceToMagnify;
-    }
-
-    private void onMagnificationChangedLocked() {
-        mAms.notifyMagnificationChanged(mMagnificationRegion,
-                getScale(), getCenterX(), getCenterY());
-        if (mUnregisterPending && !isMagnifying()) {
-            unregisterInternalLocked();
-        }
+        return mDisplay.getIdOfLastServiceToMagnify();
     }
 
     /**
      * Persists the current magnification scale to the current user's settings.
      */
     public void persistScale() {
-        final float scale = mCurrentMagnificationSpec.scale;
+        persistScale(Display.DEFAULT_DISPLAY);
+    }
+    /**
+     * Persists the current magnification scale to the current user's settings.
+     */
+    public void persistScale(int displayId) {
+        final float scale = mDisplay.getScale();
         final int userId = mUserId;
 
         new AsyncTask<Void, Void, Void>() {
             @Override
             protected Void doInBackground(Void... params) {
-                mSettingsBridge.putMagnificationScale(scale, userId);
+                mSettingsBridge.putMagnificationScale(scale, displayId, userId);
                 return null;
             }
         }.execute();
@@ -595,98 +895,7 @@
      *         scale if none is available
      */
     public float getPersistedScale() {
-        return mSettingsBridge.getMagnificationScale(mUserId);
-    }
-
-    /**
-     * Updates the current magnification spec.
-     *
-     * @param scale the magnification scale
-     * @param centerX the unscaled, screen-relative X coordinate of the center
-     *                of the viewport, or {@link Float#NaN} to leave unchanged
-     * @param centerY the unscaled, screen-relative Y coordinate of the center
-     *                of the viewport, or {@link Float#NaN} to leave unchanged
-     * @return {@code true} if the magnification spec changed or {@code false}
-     *         otherwise
-     */
-    private boolean updateMagnificationSpecLocked(float scale, float centerX, float centerY) {
-        // Handle defaults.
-        if (Float.isNaN(centerX)) {
-            centerX = getCenterX();
-        }
-        if (Float.isNaN(centerY)) {
-            centerY = getCenterY();
-        }
-        if (Float.isNaN(scale)) {
-            scale = getScale();
-        }
-
-        // Compute changes.
-        boolean changed = false;
-
-        final float normScale = MathUtils.constrain(scale, MIN_SCALE, MAX_SCALE);
-        if (Float.compare(mCurrentMagnificationSpec.scale, normScale) != 0) {
-            mCurrentMagnificationSpec.scale = normScale;
-            changed = true;
-        }
-
-        final float nonNormOffsetX = mMagnificationBounds.width() / 2.0f
-                + mMagnificationBounds.left - centerX * normScale;
-        final float nonNormOffsetY = mMagnificationBounds.height() / 2.0f
-                + mMagnificationBounds.top - centerY * normScale;
-        changed |= updateCurrentSpecWithOffsetsLocked(nonNormOffsetX, nonNormOffsetY);
-
-        if (changed) {
-            onMagnificationChangedLocked();
-        }
-
-        return changed;
-    }
-
-    private boolean updateCurrentSpecWithOffsetsLocked(float nonNormOffsetX, float nonNormOffsetY) {
-        if (DEBUG) {
-            Slog.i(LOG_TAG,
-                    "updateCurrentSpecWithOffsetsLocked(nonNormOffsetX = " + nonNormOffsetX
-                            + ", nonNormOffsetY = " + nonNormOffsetY + ")");
-        }
-        boolean changed = false;
-        final float offsetX = MathUtils.constrain(
-            nonNormOffsetX, getMinOffsetXLocked(), getMaxOffsetXLocked());
-        if (Float.compare(mCurrentMagnificationSpec.offsetX, offsetX) != 0) {
-            mCurrentMagnificationSpec.offsetX = offsetX;
-            changed = true;
-        }
-        final float offsetY = MathUtils.constrain(
-            nonNormOffsetY, getMinOffsetYLocked(), getMaxOffsetYLocked());
-        if (Float.compare(mCurrentMagnificationSpec.offsetY, offsetY) != 0) {
-            mCurrentMagnificationSpec.offsetY = offsetY;
-            changed = true;
-        }
-        return changed;
-    }
-
-    private float getMinOffsetXLocked() {
-        final float viewportWidth = mMagnificationBounds.width();
-        final float viewportLeft = mMagnificationBounds.left;
-        return (viewportLeft + viewportWidth) -
-            (viewportLeft + viewportWidth) * mCurrentMagnificationSpec.scale;
-    }
-
-    private float getMaxOffsetXLocked() {
-        return mMagnificationBounds.left -
-            mMagnificationBounds.left * mCurrentMagnificationSpec.scale;
-    }
-
-    private float getMinOffsetYLocked() {
-        final float viewportHeight = mMagnificationBounds.height();
-        final float viewportTop = mMagnificationBounds.top;
-        return (viewportTop + viewportHeight) -
-            (viewportTop + viewportHeight) * mCurrentMagnificationSpec.scale;
-    }
-
-    private float getMaxOffsetYLocked() {
-        return mMagnificationBounds.top -
-            mMagnificationBounds.top * mCurrentMagnificationSpec.scale;
+        return mSettingsBridge.getMagnificationScale(Display.DEFAULT_DISPLAY, mUserId);
     }
 
     /**
@@ -706,20 +915,14 @@
         }
     }
 
-    /**
+   /**
      * Resets magnification if magnification and auto-update are both enabled.
      *
      * @param animate whether the animate the transition
      * @return whether was {@link #isMagnifying magnifying}
      */
-    boolean resetIfNeeded(boolean animate) {
-        synchronized (mLock) {
-            if (isMagnifying()) {
-                reset(animate);
-                return true;
-            }
-            return false;
-        }
+    public boolean resetIfNeeded(boolean animate) {
+        return mDisplay.resetIfNeeded(animate);
     }
 
     /**
@@ -728,132 +931,23 @@
      * @param connectionId the connection ID be disabled.
      * @return {@code true} on success, {@code false} on failure
      */
-    boolean resetIfNeeded(int connectionId) {
-        if (mIdOfLastServiceToMagnify == connectionId) {
-            return resetIfNeeded(true /*animate*/);
-        }
-        return false;
+    public boolean resetIfNeeded(int connectionId) {
+        return mDisplay.resetIfNeeded(connectionId);
     }
 
     void setForceShowMagnifiableBounds(boolean show) {
-        if (mRegistered) {
-            mWindowManager.setForceShowMagnifiableBounds(show);
-        }
-    }
-
-    private void getMagnifiedFrameInContentCoordsLocked(Rect outFrame) {
-        final float scale = getSentScale();
-        final float offsetX = getSentOffsetX();
-        final float offsetY = getSentOffsetY();
-        getMagnificationBounds(outFrame);
-        outFrame.offset((int) -offsetX, (int) -offsetY);
-        outFrame.scale(1.0f / scale);
-    }
-
-    private void requestRectangleOnScreen(int left, int top, int right, int bottom) {
-        synchronized (mLock) {
-            final Rect magnifiedFrame = mTempRect;
-            getMagnificationBounds(magnifiedFrame);
-            if (!magnifiedFrame.intersects(left, top, right, bottom)) {
-                return;
-            }
-
-            final Rect magnifFrameInScreenCoords = mTempRect1;
-            getMagnifiedFrameInContentCoordsLocked(magnifFrameInScreenCoords);
-
-            final float scrollX;
-            final float scrollY;
-            if (right - left > magnifFrameInScreenCoords.width()) {
-                final int direction = TextUtils
-                        .getLayoutDirectionFromLocale(Locale.getDefault());
-                if (direction == View.LAYOUT_DIRECTION_LTR) {
-                    scrollX = left - magnifFrameInScreenCoords.left;
-                } else {
-                    scrollX = right - magnifFrameInScreenCoords.right;
-                }
-            } else if (left < magnifFrameInScreenCoords.left) {
-                scrollX = left - magnifFrameInScreenCoords.left;
-            } else if (right > magnifFrameInScreenCoords.right) {
-                scrollX = right - magnifFrameInScreenCoords.right;
-            } else {
-                scrollX = 0;
-            }
-
-            if (bottom - top > magnifFrameInScreenCoords.height()) {
-                scrollY = top - magnifFrameInScreenCoords.top;
-            } else if (top < magnifFrameInScreenCoords.top) {
-                scrollY = top - magnifFrameInScreenCoords.top;
-            } else if (bottom > magnifFrameInScreenCoords.bottom) {
-                scrollY = bottom - magnifFrameInScreenCoords.bottom;
-            } else {
-                scrollY = 0;
-            }
-
-            final float scale = getScale();
-            offsetMagnifiedRegion(scrollX * scale, scrollY * scale, INVALID_ID);
-        }
-    }
-
-    private void sendSpecToAnimation(MagnificationSpec spec, boolean animate) {
-        if (DEBUG) {
-            Slog.i(LOG_TAG, "sendSpecToAnimation(spec = " + spec + ", animate = " + animate + ")");
-        }
-        if (Thread.currentThread().getId() == mMainThreadId) {
-            mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
-        } else {
-            mHandler.obtainMessage(MSG_SEND_SPEC_TO_ANIMATION,
-                    animate ? 1 : 0, 0, spec).sendToTarget();
-        }
+        mDisplay.setForceShowMagnifiableBounds(show);
     }
 
     private void onScreenTurnedOff() {
-        mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
-    }
-
-    public boolean handleMessage(Message msg) {
-        switch (msg.what) {
-            case MSG_SEND_SPEC_TO_ANIMATION:
-                final boolean animate = msg.arg1 == 1;
-                final MagnificationSpec spec = (MagnificationSpec) msg.obj;
-                mSpecAnimationBridge.updateSentSpecMainThread(spec, animate);
-                break;
-            case MSG_SCREEN_TURNED_OFF:
-                resetIfNeeded(false);
-                break;
-            case MSG_ON_MAGNIFIED_BOUNDS_CHANGED: {
-                final SomeArgs args = (SomeArgs) msg.obj;
-                final Region magnifiedBounds = (Region) args.arg1;
-                onMagnificationRegionChanged(magnifiedBounds);
-                magnifiedBounds.recycle();
-                args.recycle();
-            } break;
-            case MSG_ON_RECTANGLE_ON_SCREEN_REQUESTED: {
-                final SomeArgs args = (SomeArgs) msg.obj;
-                final int left = args.argi1;
-                final int top = args.argi2;
-                final int right = args.argi3;
-                final int bottom = args.argi4;
-                requestRectangleOnScreen(left, top, right, bottom);
-                args.recycle();
-            } break;
-            case MSG_ON_USER_CONTEXT_CHANGED:
-                resetIfNeeded(true);
-                break;
-        }
-        return true;
+        final Message m = PooledLambda.obtainMessage(
+                mDisplay::resetIfNeeded, false);
+        mHandler.sendMessage(m);
     }
 
     @Override
     public String toString() {
-        return "MagnificationController{" +
-                "mCurrentMagnificationSpec=" + mCurrentMagnificationSpec +
-                ", mMagnificationRegion=" + mMagnificationRegion +
-                ", mMagnificationBounds=" + mMagnificationBounds +
-                ", mUserId=" + mUserId +
-                ", mIdOfLastServiceToMagnify=" + mIdOfLastServiceToMagnify +
-                ", mRegistered=" + mRegistered +
-                ", mUnregisterPending=" + mUnregisterPending +
-                '}';
+        return mDisplay.toString();
     }
 
     /**
@@ -974,6 +1068,7 @@
     private static class ScreenStateObserver extends BroadcastReceiver {
         private final Context mContext;
         private final MagnificationController mController;
+        private boolean mRegistered = false;
 
         public ScreenStateObserver(Context context, MagnificationController controller) {
             mContext = context;
@@ -981,11 +1076,17 @@
         }
 
         public void register() {
-            mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+            if (!mRegistered) {
+                mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+                mRegistered = true;
+            }
         }
 
         public void unregister() {
-            mContext.unregisterReceiver(this);
+            if (mRegistered) {
+                mContext.unregisterReceiver(this);
+                mRegistered = false;
+            }
         }
 
         @Override
@@ -1002,14 +1103,17 @@
             mContentResolver = contentResolver;
         }
 
-        public void putMagnificationScale(float value, int userId) {
+        public void putMagnificationScale(float value, int displayId, int userId) {
             Settings.Secure.putFloatForUser(mContentResolver,
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE, value, userId);
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE + (
+                            Display.DEFAULT_DISPLAY == displayId ? "" : displayId),
+                    value, userId);
         }
 
-        public float getMagnificationScale(int userId) {
+        public float getMagnificationScale(int displayId, int userId) {
             return Settings.Secure.getFloatForUser(mContentResolver,
-                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+                    Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE
+                            + (Display.DEFAULT_DISPLAY == displayId ? "" : displayId),
                     DEFAULT_MAGNIFICATION_SCALE, userId);
         }
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
index ff29311..4bbf682 100644
--- a/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/UiAutomationManager.java
@@ -43,6 +43,8 @@
             new ComponentName("com.android.server.accessibility", "UiAutomation");
     private static final String LOG_TAG = "UiAutomationManager";
 
+    private final Object mLock;
+
     private UiAutomationService mUiAutomationService;
 
     private AccessibilityServiceInfo mUiAutomationServiceInfo;
@@ -51,6 +53,10 @@
 
     private int mUiAutomationFlags;
 
+    UiAutomationManager(Object lock) {
+        mLock = lock;
+    }
+
     private IBinder mUiAutomationServiceOwner;
     private final DeathRecipient mUiAutomationServiceOwnerDeathRecipient =
             new DeathRecipient() {
@@ -77,56 +83,62 @@
     void registerUiTestAutomationServiceLocked(IBinder owner,
             IAccessibilityServiceClient serviceClient,
             Context context, AccessibilityServiceInfo accessibilityServiceInfo,
-            int id, Handler mainHandler, Object lock,
+            int id, Handler mainHandler,
             AccessibilityManagerService.SecurityPolicy securityPolicy,
             AbstractAccessibilityServiceConnection.SystemSupport systemSupport,
             WindowManagerInternal windowManagerInternal,
             GlobalActionPerformer globalActionPerfomer, int flags) {
-        accessibilityServiceInfo.setComponentName(COMPONENT_NAME);
+        synchronized (mLock) {
+            accessibilityServiceInfo.setComponentName(COMPONENT_NAME);
 
-        if (mUiAutomationService != null) {
-            throw new IllegalStateException("UiAutomationService " + serviceClient
-                    + "already registered!");
+            if (mUiAutomationService != null) {
+                throw new IllegalStateException("UiAutomationService " + serviceClient
+                        + "already registered!");
+            }
+
+            try {
+                owner.linkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Couldn't register for the death of a UiTestAutomationService!",
+                        re);
+                return;
+            }
+
+            mSystemSupport = systemSupport;
+            mUiAutomationService = new UiAutomationService(context, accessibilityServiceInfo, id,
+                    mainHandler, mLock, securityPolicy, systemSupport, windowManagerInternal,
+                    globalActionPerfomer);
+            mUiAutomationServiceOwner = owner;
+            mUiAutomationFlags = flags;
+            mUiAutomationServiceInfo = accessibilityServiceInfo;
+            mUiAutomationService.mServiceInterface = serviceClient;
+            mUiAutomationService.onAdded();
+            try {
+                mUiAutomationService.mServiceInterface.asBinder().linkToDeath(mUiAutomationService,
+                        0);
+            } catch (RemoteException re) {
+                Slog.e(LOG_TAG, "Failed registering death link: " + re);
+                destroyUiAutomationService();
+                return;
+            }
+
+            mUiAutomationService.connectServiceUnknownThread();
         }
-
-        try {
-            owner.linkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Couldn't register for the death of a UiTestAutomationService!", re);
-            return;
-        }
-
-        mSystemSupport = systemSupport;
-        mUiAutomationService = new UiAutomationService(context, accessibilityServiceInfo, id,
-                mainHandler, lock, securityPolicy, systemSupport, windowManagerInternal,
-                globalActionPerfomer);
-        mUiAutomationServiceOwner = owner;
-        mUiAutomationFlags = flags;
-        mUiAutomationServiceInfo = accessibilityServiceInfo;
-        mUiAutomationService.mServiceInterface = serviceClient;
-        mUiAutomationService.onAdded();
-        try {
-            mUiAutomationService.mServiceInterface.asBinder().linkToDeath(mUiAutomationService, 0);
-        } catch (RemoteException re) {
-            Slog.e(LOG_TAG, "Failed registering death link: " + re);
-            destroyUiAutomationService();
-            return;
-        }
-
-        mUiAutomationService.connectServiceUnknownThread();
     }
 
     void unregisterUiTestAutomationServiceLocked(IAccessibilityServiceClient serviceClient) {
-        if ((mUiAutomationService == null)
-                || (serviceClient == null)
-                || (mUiAutomationService.mServiceInterface == null)
-                || (serviceClient.asBinder()
-                        != mUiAutomationService.mServiceInterface.asBinder())) {
-            throw new IllegalStateException("UiAutomationService " + serviceClient
-                    + " not registered!");
-        }
+        synchronized (mLock) {
+            if ((mUiAutomationService == null)
+                    || (serviceClient == null)
+                    || (mUiAutomationService.mServiceInterface == null)
+                    || (serviceClient.asBinder()
+                    != mUiAutomationService.mServiceInterface.asBinder())) {
+                throw new IllegalStateException("UiAutomationService " + serviceClient
+                        + " not registered!");
+            }
 
-        destroyUiAutomationService();
+            destroyUiAutomationService();
+        }
     }
 
     void sendAccessibilityEventLocked(AccessibilityEvent event) {
@@ -159,33 +171,48 @@
     }
 
     int getRelevantEventTypes() {
-        if (mUiAutomationService == null) return 0;
-        return mUiAutomationService.getRelevantEventTypes();
+        UiAutomationService uiAutomationService;
+        synchronized (mLock) {
+            uiAutomationService = mUiAutomationService;
+        }
+        if (uiAutomationService == null) return 0;
+        return uiAutomationService.getRelevantEventTypes();
     }
 
     @Nullable
     AccessibilityServiceInfo getServiceInfo() {
-        if (mUiAutomationService == null) return null;
-        return mUiAutomationService.getServiceInfo();
+        UiAutomationService uiAutomationService;
+        synchronized (mLock) {
+            uiAutomationService = mUiAutomationService;
+        }
+        if (uiAutomationService == null) return null;
+        return uiAutomationService.getServiceInfo();
     }
 
     void dumpUiAutomationService(FileDescriptor fd, final PrintWriter pw, String[] args) {
-        if (mUiAutomationService != null) {
-            mUiAutomationService.dump(fd, pw, args);
+        UiAutomationService uiAutomationService;
+        synchronized (mLock) {
+            uiAutomationService = mUiAutomationService;
+        }
+        if (uiAutomationService != null) {
+            uiAutomationService.dump(fd, pw, args);
         }
     }
 
     private void destroyUiAutomationService() {
-        mUiAutomationService.mServiceInterface.asBinder().unlinkToDeath(mUiAutomationService, 0);
-        mUiAutomationService.onRemoved();
-        mUiAutomationService.resetLocked();
-        mUiAutomationService = null;
-        mUiAutomationFlags = 0;
-        if (mUiAutomationServiceOwner != null) {
-            mUiAutomationServiceOwner.unlinkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0);
-            mUiAutomationServiceOwner = null;
+        synchronized (mLock) {
+            mUiAutomationService.mServiceInterface.asBinder().unlinkToDeath(mUiAutomationService,
+                    0);
+            mUiAutomationService.onRemoved();
+            mUiAutomationService.resetLocked();
+            mUiAutomationService = null;
+            mUiAutomationFlags = 0;
+            if (mUiAutomationServiceOwner != null) {
+                mUiAutomationServiceOwner.unlinkToDeath(mUiAutomationServiceOwnerDeathRecipient, 0);
+                mUiAutomationServiceOwner = null;
+            }
+            mSystemSupport.onClientChangeLocked(false);
         }
-        mSystemSupport.onClientChange(false);
     }
 
     private class UiAutomationService extends AbstractAccessibilityServiceConnection {
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index da52d40..39866a7 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -56,6 +56,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.pm.ShortcutServiceInternal;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -629,10 +630,10 @@
                     onClickIntent = mDevicePolicyManagerInternal.createShowAdminSupportIntent(
                             providerUserId, true);
                 } else {
-                    final String dialogMessage = mPackageManagerInternal.getSuspendedDialogMessage(
-                            providerPackage, providerUserId);
+                    final SuspendDialogInfo dialogInfo = mPackageManagerInternal
+                            .getSuspendedDialogInfo(providerPackage, providerUserId);
                     onClickIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(
-                            providerPackage, suspendingPackage, dialogMessage, providerUserId);
+                            providerPackage, suspendingPackage, dialogInfo, providerUserId);
                 }
             } else if (provider.maskedByQuietProfile) {
                 showBadge = true;
diff --git a/services/art-profile b/services/art-profile
index 3c60eee..742ca1c 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -207,7 +207,7 @@
 HPLandroid/hardware/weaver/V1_0/IWeaver;->setHALInstrumentation()V
 HPLandroid/hardware/weaver/V1_0/IWeaver;->unlinkToDeath(Landroid/os/IHwBinder$DeathRecipient;)Z
 HPLandroid/hardware/weaver/V1_0/IWeaver;->write(ILjava/util/ArrayList;Ljava/util/ArrayList;)I
-HPLandroid/media/IMediaExtractorUpdateService;->loadPlugins(Ljava/lang/String;)V
+HPLandroid/media/IMediaUpdateService;->loadPlugins(Ljava/lang/String;)V
 HPLandroid/net/apf/ApfGenerator$Instruction;-><init>(Landroid/net/apf/ApfGenerator;Landroid/net/apf/ApfGenerator$Opcodes;Landroid/net/apf/ApfGenerator$Register;)V
 HPLandroid/net/apf/ApfGenerator$Instruction;->calculateImmSize(IZ)B
 HPLandroid/net/apf/ApfGenerator$Instruction;->calculateTargetLabelOffset()I
@@ -2082,6 +2082,22 @@
 HPLcom/android/server/usage/StorageStatsService;->queryStatsForUid(Ljava/lang/String;ILjava/lang/String;)Landroid/app/usage/StorageStats;
 HPLcom/android/server/usage/UnixCalendar;->getTimeInMillis()J
 HPLcom/android/server/usage/UsageStatsDatabase$CheckinAction;->checkin(Lcom/android/server/usage/IntervalStats;)Z
+HPLcom/android/server/usage/UsageStatsProto;->readStringPool(Landroid/util/proto/ProtoInputStream;)Ljava/util/List;
+HPLcom/android/server/usage/UsageStatsProto;->loadUsageStats(Landroid/util/proto/ProtoInputStream;Lcom/android/server/usage/IntervalStats;Ljava/util/List;)V
+HPLcom/android/server/usage/UsageStatsProto;->loadCountAndTime(Landroid/util/proto/ProtoInputStream;JLcom/android/server/usage/IntervalStats;$EventTracker)V
+HPLcom/android/server/usage/UsageStatsProto;->loadChooserCounts(Landroid/util/proto/ProtoInputStream;Landroid/app/usage/UsageStats;)V
+HPLcom/android/server/usage/UsageStatsProto;->loadCountsForAction(Landroid/util/proto/ProtoInputStream;Landroid/util/ArrayMap;)V
+HPLcom/android/server/usage/UsageStatsProto;->loadConfigStats(Landroid/util/proto/ProtoInputStream;JLcom/android/server/usage/IntervalStats;)V
+HPLcom/android/server/usage/UsageStatsProto;->loadEvent(Landroid/util/proto/ProtoInputStream;JLcom/android/server/usage/IntervalStats;Ljava/util/List;)V
+HPLcom/android/server/usage/UsageStatsProto;->writeStringPool(Landroid/util/proto/ProtoOutputStream;Lcom/android/server/usage/IntervalStats;)V
+HPLcom/android/server/usage/UsageStatsProto;->writeUsageStats(Landroid/util/proto/ProtoOutputStream;JLcom/android/server/usage/IntervalStats;Landroid/app/usage/UsageStats;)V
+HPLcom/android/server/usage/UsageStatsProto;->writeCountAndTime(Landroid/util/proto/ProtoOutputStream;JIJ)V
+HPLcom/android/server/usage/UsageStatsProto;->writeChooserCounts(Landroid/util/proto/ProtoOutputStream;Landroid/app/usage/UsageStats;)V
+HPLcom/android/server/usage/UsageStatsProto;->writeCountsForAction(Landroid/util/proto/ProtoOutputStream;Landroid/util/ArrayMap;)V
+HPLcom/android/server/usage/UsageStatsProto;->writeConfigStats(Landroid/util/proto/ProtoOutputStream;JLcom/android/server/usage/IntervalStats;Landroid/app/usage/ConfigurationStats;Z)V
+HPLcom/android/server/usage/UsageStatsProto;->writeEvent(Landroid/util/proto/ProtoOutputStream;JLcom/android/server/usage/IntervalStats;Landroid/app/usage/UsageEvents$Event;)V
+HPLcom/android/server/usage/UsageStatsProto;->read(Ljava/io/InputStream;Lcom/android/server/usage/IntervalStats;)V
+HPLcom/android/server/usage/UsageStatsProto;->write(Ljava/io/OutputStream;Lcom/android/server/usage/IntervalStats;)V
 HPLcom/android/server/usage/UsageStatsService$2;->onUidStateChanged(IIJ)V
 HPLcom/android/server/usage/UsageStatsService$BinderService;->hasPermission(Ljava/lang/String;)Z
 HPLcom/android/server/usage/UsageStatsService$BinderService;->isAppInactive(Ljava/lang/String;I)Z
@@ -2254,8 +2270,8 @@
 HPLcom/android/server/wm/DisplayContent;->lambda$new$8(Lcom/android/server/wm/DisplayContent;Lcom/android/server/wm/WindowState;)V
 HPLcom/android/server/wm/DisplayContent;->prepareSurfaces()V
 HPLcom/android/server/wm/DisplayContent;->resetAnimationBackgroundAnimator()V
-HPLcom/android/server/wm/DisplayContent;->setTouchExcludeRegion(Lcom/android/server/wm/Task;)V
 HPLcom/android/server/wm/DisplayContent;->skipTraverseChild(Lcom/android/server/wm/WindowContainer;)Z
+HPLcom/android/server/wm/DisplayContent;->updateTouchExcludeRegion()V
 HPLcom/android/server/wm/DockedStackDividerController;->isResizing()Z
 HPLcom/android/server/wm/DragDropController;->dragDropActiveLocked()Z
 HPLcom/android/server/wm/InputMonitor$UpdateInputForAllWindowsConsumer;->accept(Lcom/android/server/wm/WindowState;)V
@@ -3977,9 +3993,9 @@
 PLandroid/hardware/weaver/V1_0/WeaverReadResponse;-><init>()V
 PLandroid/hardware/weaver/V1_0/WeaverReadResponse;->readEmbeddedFromParcel(Landroid/os/HwParcel;Landroid/os/HwBlob;J)V
 PLandroid/hardware/weaver/V1_0/WeaverReadResponse;->readFromParcel(Landroid/os/HwParcel;)V
-PLandroid/media/IMediaExtractorUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-PLandroid/media/IMediaExtractorUpdateService$Stub$Proxy;->loadPlugins(Ljava/lang/String;)V
-PLandroid/media/IMediaExtractorUpdateService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IMediaExtractorUpdateService;
+PLandroid/media/IMediaUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+PLandroid/media/IMediaUpdateService$Stub$Proxy;->loadPlugins(Ljava/lang/String;)V
+PLandroid/media/IMediaUpdateService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IMediaExtractorUpdateService;
 PLandroid/net/apf/-$$Lambda$ApfFilter$UV1wDVoVlbcxpr8zevj_aMFtUGw;-><init>()V
 PLandroid/net/apf/-$$Lambda$ApfFilter$UV1wDVoVlbcxpr8zevj_aMFtUGw;->applyAsInt(Ljava/lang/Object;)I
 PLandroid/net/apf/ApfCapabilities;-><init>(III)V
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index af33bd0..d3842b7 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -182,9 +182,7 @@
             final int userId = users.get(i).id;
             final boolean disabled = umi.getUserRestriction(userId, UserManager.DISALLOW_AUTOFILL);
             if (disabled) {
-                if (disabled) {
-                    Slog.i(TAG, "Disabling Autofill for user " + userId);
-                }
+                Slog.i(TAG, "Disabling Autofill for user " + userId);
                 mDisabledUsers.put(userId, disabled);
             }
         }
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 78facf8..14d68cb 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -185,23 +185,6 @@
         updateLocked(disabled);
     }
 
-    @Nullable
-    CharSequence getServiceName() {
-        final String packageName = getServicePackageName();
-        if (packageName == null) {
-            return null;
-        }
-
-        try {
-            final PackageManager pm = mContext.getPackageManager();
-            final ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
-            return pm.getApplicationLabel(info);
-        } catch (Exception e) {
-            Slog.e(TAG, "Could not get label for " + packageName + ": " + e);
-            return packageName;
-        }
-    }
-
     @GuardedBy("mLock")
     private int getServiceUidLocked() {
         if (mInfo == null) {
@@ -226,6 +209,7 @@
         return null;
     }
 
+    @Nullable
     ComponentName getServiceComponentName() {
         synchronized (mLock) {
             if (mInfo == null) {
@@ -706,17 +690,27 @@
         }
     }
 
-    @NonNull
-    CharSequence getServiceLabel() {
-        final CharSequence label = mInfo.getServiceInfo().loadSafeLabel(
+    /**
+     * Gets the user-visibile name of the service this service binds to, or {@code null} if the
+     * service is disabled.
+     */
+    @Nullable
+    @GuardedBy("mLock")
+    public CharSequence getServiceLabelLocked() {
+        return mInfo == null ? null : mInfo.getServiceInfo().loadSafeLabel(
                 mContext.getPackageManager(), 0 /* do not ellipsize */,
                 PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE | PackageItemInfo.SAFE_LABEL_FLAG_TRIM);
-        return label;
     }
 
+    /**
+     * Gets the icon of the service this service binds to, or {@code null} if the service is
+     * disabled.
+     */
     @NonNull
-    Drawable getServiceIcon() {
-        return mInfo.getServiceInfo().loadIcon(mContext.getPackageManager());
+    @Nullable
+    @GuardedBy("mLock")
+    Drawable getServiceIconLocked() {
+        return mInfo == null ? null : mInfo.getServiceInfo().loadIcon(mContext.getPackageManager());
     }
 
     /**
@@ -959,7 +953,7 @@
         } else {
             pw.println();
             mInfo.dump(prefix2, pw);
-            pw.print(prefix); pw.print("Service Label: "); pw.println(getServiceLabel());
+            pw.print(prefix); pw.print("Service Label: "); pw.println(getServiceLabelLocked());
             pw.print(prefix); pw.print("Target SDK: "); pw.println(getTargedSdkLocked());
         }
         pw.print(prefix); pw.print("Component from settings: ");
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index cf323fb..f85749a 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -48,6 +48,7 @@
 import android.content.IntentSender;
 import android.graphics.Bitmap;
 import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
 import android.metrics.LogMaker;
 import android.os.Binder;
 import android.os.Build;
@@ -311,8 +312,8 @@
                                 Slog.d(TAG, "Setting urlBar as id=" + urlBarId + " and domain "
                                         + mUrlBar.getWebDomain());
                             }
-                            final ViewState viewState = new ViewState(Session.this, urlBarId,
-                                    Session.this, ViewState.STATE_URL_BAR);
+                            final ViewState viewState = new ViewState(urlBarId, Session.this,
+                                    ViewState.STATE_URL_BAR);
                             mViewStates.put(urlBarId, viewState);
                         }
                     }
@@ -400,7 +401,9 @@
     @Nullable
     private AutofillValue findValueLocked(@NonNull AutofillId autofillId) {
         final AutofillValue value = findValueFromThisSessionOnlyLocked(autofillId);
-        if (value != null) return value;
+        if (value != null) {
+            return getSanitizedValue(createSanitizers(getSaveInfoLocked()), autofillId, value);
+        }
 
         // TODO(b/113281366): rather than explicitly look for previous session, it might be better
         // to merge the sessions when created (see note on mergePreviousSessionLocked())
@@ -415,7 +418,8 @@
                 final AutofillValue previousValue = previousSession
                         .findValueFromThisSessionOnlyLocked(autofillId);
                 if (previousValue != null) {
-                    return previousValue;
+                    return getSanitizedValue(createSanitizers(previousSession.getSaveInfoLocked()),
+                            autofillId, previousValue);
                 }
             }
         }
@@ -1746,7 +1750,18 @@
 
                 final IAutoFillManagerClient client = getClient();
                 mPendingSaveUi = new PendingUi(mActivityToken, id, client);
-                getUiForShowing().showSaveUi(mService.getServiceLabel(), mService.getServiceIcon(),
+
+                final CharSequence serviceLabel;
+                final Drawable serviceIcon;
+                synchronized (mLock) {
+                    serviceLabel = mService.getServiceLabelLocked();
+                    serviceIcon = mService.getServiceIconLocked();
+                }
+                if (serviceLabel == null || serviceIcon == null) {
+                    wtf(null, "showSaveLocked(): no service label or icon");
+                    return true;
+                }
+                getUiForShowing().showSaveUi(serviceLabel, serviceIcon,
                         mService.getServicePackageName(), saveInfo, this,
                         mComponentName, this, mPendingSaveUi, isUpdate, mCompatMode);
                 if (client != null) {
@@ -1798,8 +1813,6 @@
         return sanitizers;
     }
 
-    // TODO: this method is called a few times in the save process, we should cache its results into
-    // ViewState.
     @Nullable
     private AutofillValue getSanitizedValue(
             @Nullable ArrayMap<AutofillId, InternalSanitizer> sanitizers,
@@ -1807,13 +1820,22 @@
             @Nullable AutofillValue value) {
         if (sanitizers == null || value == null) return value;
 
-        final InternalSanitizer sanitizer = sanitizers.get(id);
-        if (sanitizer == null) {
-            return value;
-        }
+        final ViewState state = mViewStates.get(id);
+        AutofillValue sanitized = state == null ? null : state.getSanitizedValue();
+        if (sanitized == null) {
+            final InternalSanitizer sanitizer = sanitizers.get(id);
+            if (sanitizer == null) {
+                return value;
+            }
 
-        final AutofillValue sanitized = sanitizer.sanitize(value);
-        if (sDebug) Slog.d(TAG, "Value for " + id + "(" + value + ") sanitized to " + sanitized);
+            sanitized = sanitizer.sanitize(value);
+            if (sDebug) {
+                Slog.d(TAG, "Value for " + id + "(" + value + ") sanitized to " + sanitized);
+            }
+            if (state != null) {
+                state.setSanitizedValue(sanitized);
+            }
+        }
         return sanitized;
     }
 
@@ -2134,7 +2156,7 @@
                     || action == ACTION_VIEW_ENTERED) {
                 if (sVerbose) Slog.v(TAG, "Creating viewState for " + id);
                 boolean isIgnored = isIgnoredLocked(id);
-                viewState = new ViewState(this, id, this,
+                viewState = new ViewState(id, this,
                         isIgnored ? ViewState.STATE_IGNORED : ViewState.STATE_INITIAL);
                 mViewStates.put(id, viewState);
 
@@ -2315,9 +2337,19 @@
             filterText = value.getTextValue().toString();
         }
 
+        final CharSequence serviceLabel;
+        final Drawable serviceIcon;
+        synchronized (mLock) {
+            serviceLabel = mService.getServiceLabelLocked();
+            serviceIcon = mService.getServiceIconLocked();
+        }
+        if (serviceLabel == null || serviceIcon == null) {
+            wtf(null, "onFillReady(): no service label or icon");
+            return;
+        }
         getUiForShowing().showFillUi(filledId, response, filterText,
                 mService.getServicePackageName(), mComponentName,
-                mService.getServiceLabel(), mService.getServiceIcon(), this, id, mCompatMode);
+                serviceLabel, serviceIcon, this, id, mCompatMode);
 
         synchronized (mLock) {
             if (mUiShownTime == 0) {
@@ -2604,7 +2636,7 @@
         if (viewState != null)  {
             viewState.setState(state);
         } else {
-            viewState = new ViewState(this, id, this, state);
+            viewState = new ViewState(id, this, state);
             if (sVerbose) {
                 Slog.v(TAG, "Adding autofillable view with id " + id + " and state " + state);
             }
@@ -2652,12 +2684,6 @@
         }
     }
 
-    CharSequence getServiceName() {
-        synchronized (mLock) {
-            return mService.getServiceName();
-        }
-    }
-
     // TODO: this should never be null, but we got at least one occurrence, probably due to a race.
     @GuardedBy("mLock")
     @Nullable
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index a8dae03..2cc6d20 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -77,7 +77,6 @@
     public final AutofillId id;
 
     private final Listener mListener;
-    private final Session mSession;
 
     private FillResponse mResponse;
     private AutofillValue mCurrentValue;
@@ -87,8 +86,7 @@
     private int mState;
     private String mDatasetId;
 
-    ViewState(Session session, AutofillId id, Listener listener, int state) {
-        mSession = session;
+    ViewState(AutofillId id, Listener listener, int state) {
         this.id = id;
         mListener = listener;
         mState = state;
@@ -141,10 +139,6 @@
         mResponse = response;
     }
 
-    CharSequence getServiceName() {
-        return mSession.getServiceName();
-    }
-
     int getState() {
         return mState;
     }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 1b97926..eb31e78 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -159,7 +159,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.atomic.AtomicInteger;
 
-public class BackupManagerService implements BackupManagerServiceInterface {
+public class BackupManagerService {
 
     public static final String TAG = "BackupManagerService";
     public static final boolean DEBUG = true;
@@ -701,7 +701,6 @@
     // Utility: build a new random integer token. The low bits are the ordinal of the
     // operation for near-time uniqueness, and the upper bits are random for app-
     // side unpredictability.
-    @Override
     public int generateRandomIntegerToken() {
         int token = mTokenGenerator.nextInt();
         if (token < 0) token = -token;
@@ -1108,12 +1107,10 @@
         return array;
     }
 
-    @Override
     public boolean setBackupPassword(String currentPw, String newPw) {
         return mBackupPasswordManager.setBackupPassword(currentPw, newPw);
     }
 
-    @Override
     public boolean hasBackupPassword() {
         return mBackupPasswordManager.hasBackupPassword();
     }
@@ -1590,7 +1587,6 @@
 
     // Get the restore-set token for the best-available restore set for this package:
     // the active set if possible, else the ancestral one.  Returns zero if none available.
-    @Override
     public long getAvailableRestoreToken(String packageName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getAvailableRestoreToken");
@@ -1608,12 +1604,10 @@
         return token;
     }
 
-    @Override
     public int requestBackup(String[] packages, IBackupObserver observer, int flags) {
         return requestBackup(packages, observer, null, flags);
     }
 
-    @Override
     public int requestBackup(String[] packages, IBackupObserver observer,
             IBackupManagerMonitor monitor, int flags) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "requestBackup");
@@ -1702,7 +1696,6 @@
     }
 
     // Cancel all running backups.
-    @Override
     public void cancelBackups() {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "cancelBackups");
         if (MORE_DEBUG) {
@@ -1732,7 +1725,6 @@
         }
     }
 
-    @Override
     public void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
             int operationType) {
         if (operationType != OP_TYPE_BACKUP_WAIT && operationType != OP_TYPE_RESTORE_WAIT) {
@@ -1790,7 +1782,6 @@
     }
 
     // synchronous waiter case
-    @Override
     public boolean waitUntilOperationComplete(int token) {
         if (MORE_DEBUG) {
             Slog.i(TAG, "Blocking until operation complete for "
@@ -1895,7 +1886,6 @@
     }
 
 
-    @Override
     public void tearDownAgentAndKill(ApplicationInfo app) {
         if (app == null) {
             // Null means the system package, so just quietly move on.  :)
@@ -2049,7 +2039,6 @@
      * @return Whether ongoing work will continue.  The return value here will be passed
      * along as the return value to the scheduled job's onStartJob() callback.
      */
-    @Override
     public boolean beginFullBackup(FullBackupJob scheduledJob) {
         final long now = System.currentTimeMillis();
         final long fullBackupInterval;
@@ -2224,7 +2213,6 @@
 
     // The job scheduler says our constraints don't hold any more,
     // so tear down any ongoing backup task right away.
-    @Override
     public void endFullBackup() {
         // offload the mRunningFullBackupTask.handleCancel() call to another thread,
         // as we might have to wait for mCancelLock
@@ -2331,7 +2319,6 @@
 
     // ----- IBackupManager binder interface -----
 
-    @Override
     public void dataChanged(final String packageName) {
         final int callingUserHandle = UserHandle.getCallingUserId();
         if (callingUserHandle != UserHandle.USER_SYSTEM) {
@@ -2362,7 +2349,6 @@
     }
 
     // Run an initialize operation for the given transport
-    @Override
     public void initializeTransports(String[] transportNames, IBackupObserver observer) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
                 "initializeTransport");
@@ -2382,7 +2368,6 @@
     }
 
     // Clear the given package's backup data from the current transport
-    @Override
     public void clearBackupData(String transportName, String packageName) {
         if (DEBUG) Slog.v(TAG, "clearBackupData() of " + packageName + " on " + transportName);
         PackageInfo info;
@@ -2438,7 +2423,6 @@
 
     // Run a backup pass immediately for any applications that have declared
     // that they have pending updates.
-    @Override
     public void backupNow() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP, "backupNow");
 
@@ -2480,7 +2464,6 @@
     //
     // This is the variant used by 'adb backup'; it requires on-screen confirmation
     // by the user because it can be used to offload data over untrusted USB.
-    @Override
     public void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
             boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
             boolean compress, boolean doKeyValue, String[] pkgList) {
@@ -2558,7 +2541,6 @@
         }
     }
 
-    @Override
     public void fullTransportBackup(String[] pkgNames) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP,
                 "fullTransportBackup");
@@ -2618,7 +2600,6 @@
         }
     }
 
-    @Override
     public void adbRestore(ParcelFileDescriptor fd) {
         mContext.enforceCallingPermission(android.Manifest.permission.BACKUP, "adbRestore");
 
@@ -2719,7 +2700,6 @@
 
     // Confirm that the previously-requested full backup/restore operation can proceed.  This
     // is used to require a user-facing disclosure about the operation.
-    @Override
     public void acknowledgeAdbBackupOrRestore(int token, boolean allow,
             String curPassword, String encPpassword, IFullBackupRestoreObserver observer) {
         if (DEBUG) {
@@ -2819,7 +2799,6 @@
     }
 
     // Enable/disable backups
-    @Override
     public void setBackupEnabled(boolean enable) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupEnabled");
@@ -2887,7 +2866,6 @@
     }
 
     // Enable/disable automatic restore of app data at install time
-    @Override
     public void setAutoRestore(boolean doAutoRestore) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setAutoRestore");
@@ -2907,7 +2885,6 @@
     }
 
     // Mark the backup service as having been provisioned
-    @Override
     public void setBackupProvisioned(boolean available) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "setBackupProvisioned");
@@ -2917,7 +2894,6 @@
     }
 
     // Report whether the backup mechanism is currently enabled
-    @Override
     public boolean isBackupEnabled() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "isBackupEnabled");
@@ -2925,7 +2901,6 @@
     }
 
     // Report the name of the currently active transport
-    @Override
     public String getCurrentTransport() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getCurrentTransport");
@@ -2938,7 +2913,6 @@
      * Returns the {@link ComponentName} of the host service of the selected transport or {@code
      * null} if no transport selected or if the transport selected is not registered.
      */
-    @Override
     @Nullable
     public ComponentName getCurrentTransportComponent() {
         mContext.enforceCallingOrSelfPermission(
@@ -2954,7 +2928,6 @@
     }
 
     // Report all known, available backup transports
-    @Override
     public String[] listAllTransports() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "listAllTransports");
@@ -2962,14 +2935,12 @@
         return mTransportManager.getRegisteredTransportNames();
     }
 
-    @Override
     public ComponentName[] listAllTransportComponents() {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "listAllTransportComponents");
         return mTransportManager.getRegisteredTransportComponents();
     }
 
-    @Override
     public String[] getTransportWhitelist() {
         // No permission check, intentionally.
         Set<ComponentName> whitelistedComponents = mTransportManager.getTransportWhitelist();
@@ -3006,7 +2977,6 @@
      * @throws SecurityException If the UID of the calling process differs from the package UID of
      *     {@code transportComponent} or if the caller does NOT have BACKUP permission.
      */
-    @Override
     public void updateTransportAttributes(
             ComponentName transportComponent,
             String name,
@@ -3070,7 +3040,6 @@
     }
 
     /** Selects transport {@code transportName} and returns previous selected transport. */
-    @Override
     @Deprecated
     @Nullable
     public String selectBackupTransport(String transportName) {
@@ -3089,7 +3058,6 @@
         }
     }
 
-    @Override
     public void selectBackupTransportAsync(
             ComponentName transportComponent, ISelectBackupTransportCallback listener) {
         mContext.enforceCallingOrSelfPermission(
@@ -3161,7 +3129,6 @@
     // Supply the configuration Intent for the given transport.  If the name is not one
     // of the available transports, or if the transport does not supply any configuration
     // UI, the method returns null.
-    @Override
     public Intent getConfigurationIntent(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getConfigurationIntent");
@@ -3186,7 +3153,6 @@
      * @param transportName The name of the registered transport.
      * @return The current destination string or null if the transport is not registered.
      */
-    @Override
     public String getDestinationString(String transportName) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.BACKUP, "getDestinationString");
@@ -3204,7 +3170,6 @@
     }
 
     // Supply the manage-data intent for the given transport.
-    @Override
     public Intent getDataManagementIntent(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getDataManagementIntent");
@@ -3223,7 +3188,6 @@
 
     // Supply the menu label for affordances that fire the manage-data intent
     // for the given transport.
-    @Override
     public String getDataManagementLabel(String transportName) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.BACKUP,
                 "getDataManagementLabel");
@@ -3242,7 +3206,6 @@
 
     // Callback: a requested backup agent has been instantiated.  This should only
     // be called from the Activity Manager.
-    @Override
     public void agentConnected(String packageName, IBinder agentBinder) {
         synchronized (mAgentConnectLock) {
             if (Binder.getCallingUid() == Process.SYSTEM_UID) {
@@ -3261,7 +3224,6 @@
     // Callback: a backup agent has failed to come up, or has unexpectedly quit.
     // If the agent failed to come up in the first place, the agentBinder argument
     // will be null.  This should only be called from the Activity Manager.
-    @Override
     public void agentDisconnected(String packageName) {
         // TODO: handle backup being interrupted
         synchronized (mAgentConnectLock) {
@@ -3278,7 +3240,6 @@
 
     // An application being installed will need a restore pass, then the Package Manager
     // will need to be told when the restore is finished.
-    @Override
     public void restoreAtInstall(String packageName, int token) {
         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
             Slog.w(TAG, "Non-system process uid=" + Binder.getCallingUid()
@@ -3364,7 +3325,6 @@
     }
 
     // Hand off a restore session
-    @Override
     public IRestoreSession beginRestoreSession(String packageName, String transport) {
         if (DEBUG) {
             Slog.v(TAG, "beginRestoreSession: pkg=" + packageName
@@ -3430,7 +3390,6 @@
 
     // Note that a currently-active backup agent has notified us that it has
     // completed the given outstanding asynchronous backup/restore operation.
-    @Override
     public void opComplete(int token, long result) {
         if (MORE_DEBUG) {
             Slog.v(TAG, "opComplete: " + Integer.toHexString(token) + " result=" + result);
@@ -3468,7 +3427,6 @@
         }
     }
 
-    @Override
     public boolean isAppEligibleForBackup(String packageName) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.BACKUP, "isAppEligibleForBackup");
@@ -3490,7 +3448,6 @@
         }
     }
 
-    @Override
     public String[] filterAppsEligibleForBackup(String[] packages) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.BACKUP, "filterAppsEligibleForBackup");
@@ -3517,7 +3474,6 @@
         }
     }
 
-    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
 
@@ -3667,7 +3623,6 @@
     }
 
 
-    @Override
     public IBackupManager getBackupManagerBinder() {
         return mBackupManagerBinder;
     }
diff --git a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java b/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.java
deleted file mode 100644
index a38a0e9..0000000
--- a/services/backup/java/com/android/server/backup/BackupManagerServiceInterface.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 com.android.server.backup;
-
-import android.annotation.Nullable;
-import android.app.IBackupAgent;
-import android.app.backup.IBackupManager;
-import android.app.backup.IBackupManagerMonitor;
-import android.app.backup.IBackupObserver;
-import android.app.backup.IFullBackupRestoreObserver;
-import android.app.backup.IRestoreSession;
-import android.app.backup.ISelectBackupTransportCallback;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.ApplicationInfo;
-import android.os.IBinder;
-import android.os.ParcelFileDescriptor;
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Interface for BackupManagerService.
- *
- * Current and future implementations of BackupManagerService should use this interface, so that
- * Trampoline is able to switch between them.
- */
-public interface BackupManagerServiceInterface {
-
-  void unlockSystemUser();
-
-  // Utility: build a new random integer token
-  int generateRandomIntegerToken();
-
-  boolean setBackupPassword(String currentPw, String newPw);
-
-  boolean hasBackupPassword();
-
-  // Get the restore-set token for the best-available restore set for this package:
-  // the active set if possible, else the ancestral one.  Returns zero if none available.
-  long getAvailableRestoreToken(String packageName);
-
-  int requestBackup(String[] packages, IBackupObserver observer, int flags);
-
-  int requestBackup(String[] packages, IBackupObserver observer,
-      IBackupManagerMonitor monitor, int flags);
-
-  // Cancel all running backups.
-  void cancelBackups();
-
-  void prepareOperationTimeout(int token, long interval, BackupRestoreTask callback,
-      int operationType);
-
-  // synchronous waiter case
-  boolean waitUntilOperationComplete(int token);
-
-  void tearDownAgentAndKill(ApplicationInfo app);
-
-  boolean beginFullBackup(FullBackupJob scheduledJob);
-
-  // The job scheduler says our constraints don't hold any more,
-  // so tear down any ongoing backup task right away.
-  void endFullBackup();
-
-  void dataChanged(String packageName);
-
-  // Initialize the given transport
-  void initializeTransports(String[] transportName, IBackupObserver observer);
-
-  // Clear the given package's backup data from the current transport
-  void clearBackupData(String transportName, String packageName);
-
-  // Run a backup pass immediately for any applications that have declared
-  // that they have pending updates.
-  void backupNow();
-
-  // Run a backup pass for the given packages, writing the resulting data stream
-  // to the supplied file descriptor.  This method is synchronous and does not return
-  // to the caller until the backup has been completed.
-  //
-  // This is the variant used by 'adb backup'; it requires on-screen confirmation
-  // by the user because it can be used to offload data over untrusted USB.
-  void adbBackup(ParcelFileDescriptor fd, boolean includeApks, boolean includeObbs,
-      boolean includeShared, boolean doWidgets, boolean doAllApps, boolean includeSystem,
-      boolean compress, boolean doKeyValue, String[] pkgList);
-
-  void fullTransportBackup(String[] pkgNames);
-
-  void adbRestore(ParcelFileDescriptor fd);
-
-  // Confirm that the previously-requested full backup/restore operation can proceed.  This
-  // is used to require a user-facing disclosure about the operation.
-  void acknowledgeAdbBackupOrRestore(int token, boolean allow,
-      String curPassword, String encPpassword, IFullBackupRestoreObserver observer);
-
-  // Enable/disable backups
-  void setBackupEnabled(boolean enable);
-
-  // Enable/disable automatic restore of app data at install time
-  void setAutoRestore(boolean doAutoRestore);
-
-  // Mark the backup service as having been provisioned
-  void setBackupProvisioned(boolean available);
-
-  // Report whether the backup mechanism is currently enabled
-  boolean isBackupEnabled();
-
-  // Update the transport attributes
-  void updateTransportAttributes(
-          ComponentName transportComponent,
-          String name,
-          Intent configurationIntent,
-          String currentDestinationString,
-          Intent dataManagementIntent,
-          String dataManagementLabel);
-
-  // Report the name of the currently active transport
-  String getCurrentTransport();
-
-  // Report the component name of the host service of the currently active transport
-  @Nullable
-  ComponentName getCurrentTransportComponent();
-
-  // Report all known, available backup transports
-  String[] listAllTransports();
-
-  ComponentName[] listAllTransportComponents();
-
-  String[] getTransportWhitelist();
-
-  // Select which transport to use for the next backup operation.
-  String selectBackupTransport(String transport);
-
-  void selectBackupTransportAsync(ComponentName transport,
-      ISelectBackupTransportCallback listener);
-
-  // Supply the configuration Intent for the given transport.  If the name is not one
-  // of the available transports, or if the transport does not supply any configuration
-  // UI, the method returns null.
-  Intent getConfigurationIntent(String transportName);
-
-  // Supply the configuration summary string for the given transport.  If the name is
-  // not one of the available transports, or if the transport does not supply any
-  // summary / destination string, the method can return null.
-  //
-  // This string is used VERBATIM as the summary text of the relevant Settings item!
-  String getDestinationString(String transportName);
-
-  // Supply the manage-data intent for the given transport.
-  Intent getDataManagementIntent(String transportName);
-
-  // Supply the menu label for affordances that fire the manage-data intent
-  // for the given transport.
-  String getDataManagementLabel(String transportName);
-
-  // Callback: a requested backup agent has been instantiated.  This should only
-  // be called from the Activity Manager.
-  void agentConnected(String packageName, IBinder agentBinder);
-
-  // Callback: a backup agent has failed to come up, or has unexpectedly quit.
-  // If the agent failed to come up in the first place, the agentBinder argument
-  // will be null.  This should only be called from the Activity Manager.
-  void agentDisconnected(String packageName);
-
-  // An application being installed will need a restore pass, then the Package Manager
-  // will need to be told when the restore is finished.
-  void restoreAtInstall(String packageName, int token);
-
-  // Hand off a restore session
-  IRestoreSession beginRestoreSession(String packageName, String transport);
-
-  // Note that a currently-active backup agent has notified us that it has
-  // completed the given outstanding asynchronous backup/restore operation.
-  void opComplete(int token, long result);
-
-  boolean isAppEligibleForBackup(String packageName);
-
-  String[] filterAppsEligibleForBackup(String[] packages);
-
-  void dump(FileDescriptor fd, PrintWriter pw, String[] args);
-
-  IBackupManager getBackupManagerBinder();
-
-  // Gets access to the backup/restore agent timeout parameters.
-  BackupAgentTimeoutParameters getAgentTimeoutParameters();
-}
diff --git a/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java b/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
index fbec5cb..bb14576 100644
--- a/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/KeyValueAdbRestoreEngine.java
@@ -39,7 +39,7 @@
     private static final String TAG = "KeyValueAdbRestoreEngine";
     private static final boolean DEBUG = false;
 
-    private final BackupManagerServiceInterface mBackupManagerService;
+    private final BackupManagerService mBackupManagerService;
     private final File mDataDir;
 
     FileMetadata mInfo;
@@ -48,7 +48,7 @@
     IBackupAgent mAgent;
     int mToken;
 
-    public KeyValueAdbRestoreEngine(BackupManagerServiceInterface backupManagerService,
+    public KeyValueAdbRestoreEngine(BackupManagerService backupManagerService,
             File dataDir, FileMetadata info, ParcelFileDescriptor inFD, IBackupAgent agent,
             int token) {
         mBackupManagerService = backupManagerService;
diff --git a/services/backup/java/com/android/server/backup/Trampoline.java b/services/backup/java/com/android/server/backup/Trampoline.java
index 787d667..818154b 100644
--- a/services/backup/java/com/android/server/backup/Trampoline.java
+++ b/services/backup/java/com/android/server/backup/Trampoline.java
@@ -76,7 +76,7 @@
     final Context mContext;
     final File mSuppressFile;   // existence testing & creating synchronized on 'this'
     final boolean mGlobalDisable;
-    volatile BackupManagerServiceInterface mService;
+    volatile BackupManagerService mService;
 
     private HandlerThread mHandlerThread;
 
@@ -100,7 +100,7 @@
                 BACKUP_SUPPRESS_FILENAME);
     }
 
-    protected BackupManagerServiceInterface createBackupManagerService() {
+    protected BackupManagerService createBackupManagerService() {
         return BackupManagerService.create(mContext, this, mHandlerThread);
     }
 
@@ -135,7 +135,7 @@
             initialize(UserHandle.USER_SYSTEM);
             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 
-            BackupManagerServiceInterface svc = mService;
+            BackupManagerService svc = mService;
             Slog.i(TAG, "Unlocking system user; mService=" + mService);
             if (svc != null) {
                 svc.unlockSystemUser();
@@ -198,7 +198,7 @@
 
     @Override
     public void dataChanged(String packageName) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.dataChanged(packageName);
         }
@@ -207,7 +207,7 @@
     @Override
     public void initializeTransports(String[] transportNames, IBackupObserver observer)
             throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.initializeTransports(transportNames, observer);
         }
@@ -216,7 +216,7 @@
     @Override
     public void clearBackupData(String transportName, String packageName)
             throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.clearBackupData(transportName, packageName);
         }
@@ -224,7 +224,7 @@
 
     @Override
     public void agentConnected(String packageName, IBinder agent) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.agentConnected(packageName, agent);
         }
@@ -232,7 +232,7 @@
 
     @Override
     public void agentDisconnected(String packageName) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.agentDisconnected(packageName);
         }
@@ -240,7 +240,7 @@
 
     @Override
     public void restoreAtInstall(String packageName, int token) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.restoreAtInstall(packageName, token);
         }
@@ -248,7 +248,7 @@
 
     @Override
     public void setBackupEnabled(boolean isEnabled) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.setBackupEnabled(isEnabled);
         }
@@ -256,7 +256,7 @@
 
     @Override
     public void setAutoRestore(boolean doAutoRestore) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.setAutoRestore(doAutoRestore);
         }
@@ -264,7 +264,7 @@
 
     @Override
     public void setBackupProvisioned(boolean isProvisioned) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.setBackupProvisioned(isProvisioned);
         }
@@ -272,25 +272,25 @@
 
     @Override
     public boolean isBackupEnabled() throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.isBackupEnabled() : false;
     }
 
     @Override
     public boolean setBackupPassword(String currentPw, String newPw) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.setBackupPassword(currentPw, newPw) : false;
     }
 
     @Override
     public boolean hasBackupPassword() throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.hasBackupPassword() : false;
     }
 
     @Override
     public void backupNow() throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.backupNow();
         }
@@ -301,7 +301,7 @@
             boolean includeShared, boolean doWidgets, boolean allApps,
             boolean allIncludesSystem, boolean doCompress, boolean doKeyValue, String[] packageNames)
                     throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.adbBackup(fd, includeApks, includeObbs, includeShared, doWidgets,
                     allApps, allIncludesSystem, doCompress, doKeyValue, packageNames);
@@ -310,7 +310,7 @@
 
     @Override
     public void fullTransportBackup(String[] packageNames) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.fullTransportBackup(packageNames);
         }
@@ -318,7 +318,7 @@
 
     @Override
     public void adbRestore(ParcelFileDescriptor fd) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.adbRestore(fd);
         }
@@ -328,7 +328,7 @@
     public void acknowledgeFullBackupOrRestore(int token, boolean allow, String curPassword,
             String encryptionPassword, IFullBackupRestoreObserver observer)
                     throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.acknowledgeAdbBackupOrRestore(token, allow,
                     curPassword, encryptionPassword, observer);
@@ -337,7 +337,7 @@
 
     @Override
     public String getCurrentTransport() throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.getCurrentTransport() : null;
     }
 
@@ -348,25 +348,25 @@
     @Override
     @Nullable
     public ComponentName getCurrentTransportComponent() {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.getCurrentTransportComponent() : null;
     }
 
     @Override
     public String[] listAllTransports() throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.listAllTransports() : null;
     }
 
     @Override
     public ComponentName[] listAllTransportComponents() throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.listAllTransportComponents() : null;
     }
 
     @Override
     public String[] getTransportWhitelist() {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.getTransportWhitelist() : null;
     }
 
@@ -378,7 +378,7 @@
             String currentDestinationString,
             @Nullable Intent dataManagementIntent,
             String dataManagementLabel) {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.updateTransportAttributes(
                     transportComponent,
@@ -392,14 +392,14 @@
 
     @Override
     public String selectBackupTransport(String transport) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.selectBackupTransport(transport) : null;
     }
 
     @Override
     public void selectBackupTransportAsync(ComponentName transport,
             ISelectBackupTransportCallback listener) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.selectBackupTransportAsync(transport, listener);
         } else {
@@ -415,38 +415,38 @@
 
     @Override
     public Intent getConfigurationIntent(String transport) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.getConfigurationIntent(transport) : null;
     }
 
     @Override
     public String getDestinationString(String transport) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.getDestinationString(transport) : null;
     }
 
     @Override
     public Intent getDataManagementIntent(String transport) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.getDataManagementIntent(transport) : null;
     }
 
     @Override
     public String getDataManagementLabel(String transport) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.getDataManagementLabel(transport) : null;
     }
 
     @Override
     public IRestoreSession beginRestoreSession(String packageName, String transportID)
             throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.beginRestoreSession(packageName, transportID) : null;
     }
 
     @Override
     public void opComplete(int token, long result) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.opComplete(token, result);
         }
@@ -454,26 +454,26 @@
 
     @Override
     public long getAvailableRestoreToken(String packageName) {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.getAvailableRestoreToken(packageName) : 0;
     }
 
     @Override
     public boolean isAppEligibleForBackup(String packageName) {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.isAppEligibleForBackup(packageName) : false;
     }
 
     @Override
     public String[] filterAppsEligibleForBackup(String[] packages) {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.filterAppsEligibleForBackup(packages) : null;
     }
 
     @Override
     public int requestBackup(String[] packages, IBackupObserver observer,
             IBackupManagerMonitor monitor, int flags) throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc == null) {
             return BackupManager.ERROR_BACKUP_NOT_ALLOWED;
         }
@@ -482,7 +482,7 @@
 
     @Override
     public void cancelBackups() throws RemoteException {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.cancelBackups();
         }
@@ -492,7 +492,7 @@
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
 
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.dump(fd, pw, args);
         } else {
@@ -503,12 +503,12 @@
     // Full backup/restore entry points - non-Binder; called directly
     // by the full-backup scheduled job
     /* package */ boolean beginFullBackup(FullBackupJob scheduledJob) {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         return (svc != null) ? svc.beginFullBackup(scheduledJob) : false;
     }
 
     /* package */ void endFullBackup() {
-        BackupManagerServiceInterface svc = mService;
+        BackupManagerService svc = mService;
         if (svc != null) {
             svc.endFullBackup();
         }
diff --git a/services/backup/java/com/android/server/backup/encryption/chunk/ChunkOrderingType.java b/services/backup/java/com/android/server/backup/encryption/chunk/ChunkOrderingType.java
new file mode 100644
index 0000000..df36c94
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunk/ChunkOrderingType.java
@@ -0,0 +1,30 @@
+/*
+ * 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.backup.encryption.chunk;
+
+import static com.android.server.backup.encryption.chunk.ChunksMetadataProto.CHUNK_ORDERING_TYPE_UNSPECIFIED;
+import static com.android.server.backup.encryption.chunk.ChunksMetadataProto.EXPLICIT_STARTS;
+import static com.android.server.backup.encryption.chunk.ChunksMetadataProto.INLINE_LENGTHS;
+
+import android.annotation.IntDef;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** IntDef corresponding to the ChunkOrderingType enum in the ChunksMetadataProto protobuf. */
+@IntDef({CHUNK_ORDERING_TYPE_UNSPECIFIED, EXPLICIT_STARTS, INLINE_LENGTHS})
+@Retention(RetentionPolicy.SOURCE)
+public @interface ChunkOrderingType {}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/BackupWriter.java b/services/backup/java/com/android/server/backup/encryption/chunking/BackupWriter.java
new file mode 100644
index 0000000..68d9d14
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/BackupWriter.java
@@ -0,0 +1,43 @@
+/*
+ * 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.backup.encryption.chunking;
+
+import java.io.IOException;
+
+/** Writes backup data either as a diff script or as raw data, determined by the implementation. */
+public interface BackupWriter {
+    /** Writes the given bytes to the output. */
+    void writeBytes(byte[] bytes) throws IOException;
+
+    /**
+     * Writes an existing chunk from the previous backup to the output.
+     *
+     * <p>Note: not all implementations support this method.
+     */
+    void writeChunk(long start, int length) throws IOException;
+
+    /** Returns the number of bytes written, included bytes copied from the old file. */
+    long getBytesWritten();
+
+    /**
+     * Indicates that no more bytes or chunks will be written.
+     *
+     * <p>After calling this, you may not call {@link #writeBytes(byte[])} or {@link
+     * #writeChunk(long, int)}
+     */
+    void flush() throws IOException;
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunk.java b/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunk.java
new file mode 100644
index 0000000..1f936eb
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunk.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.backup.encryption.chunking;
+
+import com.android.internal.util.Preconditions;
+import com.android.server.backup.encryption.chunk.ChunkHash;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A chunk of a file encrypted using AES/GCM.
+ *
+ * <p>TODO(b/116575321): After all code is ported, remove the factory method and rename
+ * encryptedBytes(), key() and nonce().
+ */
+public class EncryptedChunk {
+    public static final int KEY_LENGTH_BYTES = ChunkHash.HASH_LENGTH_BYTES;
+    public static final int NONCE_LENGTH_BYTES = 12;
+
+    /**
+     * Constructs a new instance with the given key, nonce, and encrypted bytes.
+     *
+     * @param key SHA-256 Hmac of the chunk plaintext.
+     * @param nonce Nonce with which the bytes of the chunk were encrypted.
+     * @param encryptedBytes Encrypted bytes of the chunk.
+     */
+    public static EncryptedChunk create(ChunkHash key, byte[] nonce, byte[] encryptedBytes) {
+        Preconditions.checkArgument(
+                nonce.length == NONCE_LENGTH_BYTES, "Nonce does not have the correct length.");
+        return new EncryptedChunk(key, nonce, encryptedBytes);
+    }
+
+    private ChunkHash mKey;
+    private byte[] mNonce;
+    private byte[] mEncryptedBytes;
+
+    private EncryptedChunk(ChunkHash key, byte[] nonce, byte[] encryptedBytes) {
+        mKey = key;
+        mNonce = nonce;
+        mEncryptedBytes = encryptedBytes;
+    }
+
+    /** The SHA-256 Hmac of the plaintext bytes of the chunk. */
+    public ChunkHash key() {
+        return mKey;
+    }
+
+    /** The nonce with which the chunk was encrypted. */
+    public byte[] nonce() {
+        return mNonce;
+    }
+
+    /** The encrypted bytes of the chunk. */
+    public byte[] encryptedBytes() {
+        return mEncryptedBytes;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof EncryptedChunk)) {
+            return false;
+        }
+
+        EncryptedChunk encryptedChunkOrdering = (EncryptedChunk) o;
+        return Arrays.equals(mEncryptedBytes, encryptedChunkOrdering.mEncryptedBytes)
+                && Arrays.equals(mNonce, encryptedChunkOrdering.mNonce)
+                && mKey.equals(encryptedChunkOrdering.mKey);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mKey, Arrays.hashCode(mNonce), Arrays.hashCode(mEncryptedBytes));
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java b/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java
new file mode 100644
index 0000000..eaf701c
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/EncryptedChunkEncoder.java
@@ -0,0 +1,45 @@
+/*
+ * 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.backup.encryption.chunking;
+
+import com.android.server.backup.encryption.chunk.ChunkOrderingType;
+import java.io.IOException;
+
+/** Encodes an {@link EncryptedChunk} as bytes to write to the encrypted backup file. */
+public interface EncryptedChunkEncoder {
+    /**
+     * Encodes the given chunk and asks the writer to write it.
+     *
+     * <p>The chunk will be encoded in the format [nonce]+[encrypted data].
+     *
+     * <p>TODO(b/116575321): Choose a more descriptive method name after the code move is done.
+     */
+    void writeChunkToWriter(BackupWriter writer, EncryptedChunk chunk) throws IOException;
+
+    /**
+     * Returns the length in bytes that this chunk would be if encoded with {@link
+     * #writeChunkToWriter}.
+     */
+    int getEncodedLengthOfChunk(EncryptedChunk chunk);
+
+    /**
+     * Returns the {@link ChunkOrderingType} that must be included in the backup file, when using
+     * this decoder, so that the file may be correctly decoded.
+     */
+    @ChunkOrderingType
+    int getChunkOrderingType();
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java b/services/backup/java/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java
new file mode 100644
index 0000000..5c902ca
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoder.java
@@ -0,0 +1,68 @@
+/*
+ * 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.backup.encryption.chunking;
+
+import com.android.server.backup.encryption.chunk.ChunkOrderingType;
+import com.android.server.backup.encryption.chunk.ChunksMetadataProto;
+import java.io.IOException;
+
+/**
+ * Encodes an {@link EncryptedChunk} as bytes, prepending the length of the chunk.
+ *
+ * <p>This allows us to decode the backup file during restore without any extra information about
+ * the boundaries of the chunks. The backup file should contain a chunk ordering in mode {@link
+ * ChunksMetadataProto#INLINE_LENGTHS}.
+ *
+ * <p>We use this implementation during key value backup.
+ */
+public class InlineLengthsEncryptedChunkEncoder implements EncryptedChunkEncoder {
+    public static final int BYTES_LENGTH = Integer.SIZE / Byte.SIZE;
+
+    private final LengthlessEncryptedChunkEncoder mLengthlessEncryptedChunkEncoder =
+            new LengthlessEncryptedChunkEncoder();
+
+    @Override
+    public void writeChunkToWriter(BackupWriter writer, EncryptedChunk chunk) throws IOException {
+        int length = mLengthlessEncryptedChunkEncoder.getEncodedLengthOfChunk(chunk);
+        writer.writeBytes(toByteArray(length));
+        mLengthlessEncryptedChunkEncoder.writeChunkToWriter(writer, chunk);
+    }
+
+    @Override
+    public int getEncodedLengthOfChunk(EncryptedChunk chunk) {
+        return BYTES_LENGTH + mLengthlessEncryptedChunkEncoder.getEncodedLengthOfChunk(chunk);
+    }
+
+    @Override
+    @ChunkOrderingType
+    public int getChunkOrderingType() {
+        return ChunksMetadataProto.INLINE_LENGTHS;
+    }
+
+    /**
+     * Returns a big-endian representation of {@code value} in a 4-element byte array; equivalent to
+     * {@code ByteBuffer.allocate(4).putInt(value).array()}. For example, the input value {@code
+     * 0x12131415} would yield the byte array {@code {0x12, 0x13, 0x14, 0x15}}.
+     *
+     * <p>Equivalent to guava's Ints.toByteArray.
+     */
+    static byte[] toByteArray(int value) {
+        return new byte[] {
+            (byte) (value >> 24), (byte) (value >> 16), (byte) (value >> 8), (byte) value
+        };
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java b/services/backup/java/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java
new file mode 100644
index 0000000..4b84981
--- /dev/null
+++ b/services/backup/java/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoder.java
@@ -0,0 +1,51 @@
+/*
+ * 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.backup.encryption.chunking;
+
+import com.android.server.backup.encryption.chunk.ChunkOrderingType;
+import com.android.server.backup.encryption.chunk.ChunksMetadataProto;
+import java.io.IOException;
+
+/**
+ * Encodes an {@link EncryptedChunk} as bytes without including any information about the length of
+ * the chunk.
+ *
+ * <p>In order for us to decode the backup file during restore it must include a chunk ordering in
+ * mode {@link ChunksMetadataProto#EXPLICIT_STARTS}, which contains the boundaries of the chunks in
+ * the encrypted file. This information allows us to decode the backup file and divide it into
+ * chunks without including the length of each chunk inline.
+ *
+ * <p>We use this implementation during full backup.
+ */
+public class LengthlessEncryptedChunkEncoder implements EncryptedChunkEncoder {
+    @Override
+    public void writeChunkToWriter(BackupWriter writer, EncryptedChunk chunk) throws IOException {
+        writer.writeBytes(chunk.nonce());
+        writer.writeBytes(chunk.encryptedBytes());
+    }
+
+    @Override
+    public int getEncodedLengthOfChunk(EncryptedChunk chunk) {
+        return chunk.nonce().length + chunk.encryptedBytes().length;
+    }
+
+    @Override
+    @ChunkOrderingType
+    public int getChunkOrderingType() {
+        return ChunksMetadataProto.EXPLICIT_STARTS;
+    }
+}
diff --git a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
index 6904b3f..3a5232a 100644
--- a/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
+++ b/services/backup/java/com/android/server/backup/keyvalue/KeyValueBackupTask.java
@@ -708,8 +708,6 @@
             } else {
                 throw TaskException.create();
             }
-        } finally {
-            mBlankStateFile.delete();
         }
         checkAgentResult(packageInfo, agentResult);
     }
@@ -1037,8 +1035,13 @@
 
     private void cleanUpAgent(@StateTransaction int stateTransaction) {
         applyStateTransaction(stateTransaction);
-        mBackupDataFile.delete();
+        if (mBackupDataFile != null) {
+            mBackupDataFile.delete();
+        }
         mBlankStateFile.delete();
+        mSavedStateFile = null;
+        mBackupDataFile = null;
+        mNewStateFile = null;
         tryCloseFileDescriptor(mSavedState, "old state");
         tryCloseFileDescriptor(mBackupData, "backup data");
         tryCloseFileDescriptor(mNewState, "new state");
@@ -1059,7 +1062,9 @@
                 mNewStateFile.renameTo(mSavedStateFile);
                 break;
             case StateTransaction.DISCARD_NEW:
-                mNewStateFile.delete();
+                if (mNewStateFile != null) {
+                    mNewStateFile.delete();
+                }
                 break;
             case StateTransaction.DISCARD_ALL:
                 mSavedStateFile.delete();
diff --git a/services/core/Android.bp b/services/core/Android.bp
index d9519e0..2fa2941 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -4,6 +4,7 @@
     aidl: {
         include_dirs: [
             "frameworks/native/aidl/binder",
+            "frameworks/native/cmds/dumpstate/binder",
             "system/core/storaged/binder",
             "system/netd/server/binder",
             "system/vold/binder",
@@ -11,6 +12,7 @@
     },
     srcs: [
         "java/**/*.java",
+        ":dumpstate_aidl",
         ":netd_aidl",
         ":netd_metrics_aidl",
         ":installd_aidl",
@@ -44,6 +46,7 @@
         "android.hardware.configstore-V1.0-java",
         "android.hardware.contexthub-V1.0-java",
         "android.hidl.manager-V1.0-java",
+        "netd_aidl_interface-java",
     ],
 }
 
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index ad2f82c..38b9647 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -142,6 +142,8 @@
     static final boolean RECORD_DEVICE_IDLE_ALARMS = false;
     static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
 
+    static final int TICK_HISTORY_DEPTH = 10;
+
     // Indices into the APP_STANDBY_MIN_DELAYS and KEYS_APP_STANDBY_DELAY arrays
     static final int ACTIVE_INDEX = 0;
     static final int WORKING_INDEX = 1;
@@ -176,21 +178,25 @@
     private long mNextNonWakeUpSetAt;
     private long mLastWakeup;
     private long mLastTrigger;
+
     private long mLastTickSet;
-    private long mLastTickIssued; // elapsed
     private long mLastTickReceived;
     private long mLastTickAdded;
     private long mLastTickRemoved;
+    // ring buffer of recent TIME_TICK issuance, in the elapsed timebase
+    private final long[] mTickHistory = new long[TICK_HISTORY_DEPTH];
+    private int mNextTickHistory;
+
     private final Injector mInjector;
     int mBroadcastRefCount = 0;
     PowerManager.WakeLock mWakeLock;
-    boolean mLastWakeLockUnimportantForLogging;
     ArrayList<Alarm> mPendingNonWakeupAlarms = new ArrayList<>();
     ArrayList<InFlight> mInFlight = new ArrayList<>();
     AlarmHandler mHandler;
     ClockReceiver mClockReceiver;
     final DeliveryTracker mDeliveryTracker = new DeliveryTracker();
-    PendingIntent mTimeTickSender;
+    Intent mTimeTickIntent;
+    IAlarmListener mTimeTickTrigger;
     PendingIntent mDateChangeSender;
     Random mRandom;
     boolean mInteractive = true;
@@ -279,14 +285,21 @@
     @VisibleForTesting
     final class Constants extends ContentObserver {
         // Key names stored in the settings value.
-        private static final String KEY_MIN_FUTURITY = "min_futurity";
-        private static final String KEY_MIN_INTERVAL = "min_interval";
-        private static final String KEY_MAX_INTERVAL = "max_interval";
-        private static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time";
-        private static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time";
-        private static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION
+        @VisibleForTesting
+        static final String KEY_MIN_FUTURITY = "min_futurity";
+        @VisibleForTesting
+        static final String KEY_MIN_INTERVAL = "min_interval";
+        @VisibleForTesting
+        static final String KEY_MAX_INTERVAL = "max_interval";
+        @VisibleForTesting
+        static final String KEY_ALLOW_WHILE_IDLE_SHORT_TIME = "allow_while_idle_short_time";
+        @VisibleForTesting
+        static final String KEY_ALLOW_WHILE_IDLE_LONG_TIME = "allow_while_idle_long_time";
+        @VisibleForTesting
+        static final String KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION
                 = "allow_while_idle_whitelist_duration";
-        private static final String KEY_LISTENER_TIMEOUT = "listener_timeout";
+        @VisibleForTesting
+        static final String KEY_LISTENER_TIMEOUT = "listener_timeout";
 
         // Keys for specifying throttling delay based on app standby bucketing
         private final String[] KEYS_APP_STANDBY_DELAY = {
@@ -509,7 +522,7 @@
             end = clampPositive(seed.maxWhenElapsed);
             flags = seed.flags;
             alarms.add(seed);
-            if (seed.operation == mTimeTickSender) {
+            if (seed.listener == mTimeTickTrigger) {
                 mLastTickAdded = mInjector.getCurrentTimeMillis();
             }
         }
@@ -534,7 +547,7 @@
                 index = 0 - index - 1;
             }
             alarms.add(index, alarm);
-            if (alarm.operation == mTimeTickSender) {
+            if (alarm.listener == mTimeTickTrigger) {
                 mLastTickAdded = mInjector.getCurrentTimeMillis();
             }
             if (DEBUG_BATCH) {
@@ -572,7 +585,7 @@
                     if (alarm.alarmClock != null) {
                         mNextAlarmClockMayChange = true;
                     }
-                    if (alarm.operation == mTimeTickSender) {
+                    if (alarm.listener == mTimeTickTrigger) {
                         mLastTickRemoved = mInjector.getCurrentTimeMillis();
                     }
                 } else {
@@ -690,8 +703,7 @@
             Alarm a = alarms.get(i);
 
             final int alarmPrio;
-            if (a.operation != null
-                    && Intent.ACTION_TIME_TICK.equals(a.operation.getIntent().getAction())) {
+            if (a.listener == mTimeTickTrigger) {
                 alarmPrio = PRIO_TICK;
             } else if (a.wakeup) {
                 alarmPrio = PRIO_WAKEUP;
@@ -823,7 +835,7 @@
         }
         final int batchSize = alarms.size();
         for (int j = 0; j < batchSize; j++) {
-            if (alarms.get(j).operation == mTimeTickSender) {
+            if (alarms.get(j).listener == mTimeTickTrigger) {
                 return true;
             }
         }
@@ -1111,10 +1123,7 @@
         updateNextAlarmClockLocked();
 
         // And send a TIME_TICK right now, since it is important to get the UI updated.
-        try {
-            mTimeTickSender.send();
-        } catch (PendingIntent.CanceledException e) {
-        }
+        mHandler.post(() ->  getContext().sendBroadcastAsUser(mTimeTickIntent, UserHandle.ALL));
     }
 
     static final class InFlight {
@@ -1312,12 +1321,36 @@
             }
             mWakeLock = mInjector.getAlarmWakeLock();
 
-            mTimeTickSender = PendingIntent.getBroadcastAsUser(getContext(), 0,
-                    new Intent(Intent.ACTION_TIME_TICK).addFlags(
-                            Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                                    | Intent.FLAG_RECEIVER_FOREGROUND
-                                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS), 0,
-                    UserHandle.ALL);
+            mTimeTickIntent = new Intent(Intent.ACTION_TIME_TICK).addFlags(
+                    Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                    | Intent.FLAG_RECEIVER_FOREGROUND
+                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+
+            mTimeTickTrigger = new IAlarmListener.Stub() {
+                @Override
+                public void doAlarm(final IAlarmCompleteListener callback) throws RemoteException {
+                    if (DEBUG_BATCH) {
+                        Slog.v(TAG, "Received TIME_TICK alarm; rescheduling");
+                    }
+
+                    // Via handler because dispatch invokes this within its lock.  OnAlarmListener
+                    // takes care of this automatically, but we're using the direct internal
+                    // interface here rather than that client-side wrapper infrastructure.
+                    mHandler.post(() -> {
+                        getContext().sendBroadcastAsUser(mTimeTickIntent, UserHandle.ALL);
+
+                        try {
+                            callback.alarmComplete(this);
+                        } catch (RemoteException e) { /* local method call */ }
+                    });
+
+                    synchronized (mLock) {
+                        mLastTickReceived = mInjector.getCurrentTimeMillis();
+                    }
+                    mClockReceiver.scheduleTimeTickEvent();
+                }
+            };
+
             Intent intent = new Intent(Intent.ACTION_DATE_CHANGED);
             intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
@@ -1438,12 +1471,9 @@
         }
     }
 
-    void removeImpl(PendingIntent operation) {
-        if (operation == null) {
-            return;
-        }
+    void removeImpl(PendingIntent operation, IAlarmListener listener) {
         synchronized (mLock) {
-            removeLocked(operation, null);
+            removeLocked(operation, listener);
         }
     }
 
@@ -1887,9 +1917,9 @@
             pw.println("  App Standby Parole: " + mAppStandbyParole);
             pw.println();
 
-            final long nowRTC = mInjector.getCurrentTimeMillis();
             final long nowELAPSED = mInjector.getElapsedRealtime();
             final long nowUPTIME = SystemClock.uptimeMillis();
+            final long nowRTC = mInjector.getCurrentTimeMillis();
             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
 
             pw.print("  nowRTC="); pw.print(nowRTC);
@@ -1899,13 +1929,27 @@
             pw.print("  mLastTimeChangeClockTime="); pw.print(mLastTimeChangeClockTime);
             pw.print("="); pw.println(sdf.format(new Date(mLastTimeChangeClockTime)));
             pw.print("  mLastTimeChangeRealtime="); pw.println(mLastTimeChangeRealtime);
-            pw.print("  mLastTickIssued=");
-            pw.println(sdf.format(new Date(nowRTC - (nowELAPSED - mLastTickIssued))));
             pw.print("  mLastTickReceived="); pw.println(sdf.format(new Date(mLastTickReceived)));
             pw.print("  mLastTickSet="); pw.println(sdf.format(new Date(mLastTickSet)));
             pw.print("  mLastTickAdded="); pw.println(sdf.format(new Date(mLastTickAdded)));
             pw.print("  mLastTickRemoved="); pw.println(sdf.format(new Date(mLastTickRemoved)));
 
+            if (RECORD_ALARMS_IN_HISTORY) {
+                pw.println();
+                pw.println("  Recent TIME_TICK history:");
+                int i = mNextTickHistory;
+                do {
+                    i--;
+                    if (i < 0) i = TICK_HISTORY_DEPTH - 1;
+                    final long time = mTickHistory[i];
+                    pw.print("    ");
+                    pw.println((time > 0)
+                            ? sdf.format(new Date(nowRTC - (nowELAPSED - time)))
+                            : "-");
+                } while (i != mNextTickHistory);
+                pw.println();
+            }
+
             SystemServiceManager ssm = LocalServices.getService(SystemServiceManager.class);
             if (ssm != null) {
                 pw.println();
@@ -3640,8 +3684,8 @@
                         }
                         // StatsLog requires currentTimeMillis(), which == nowRTC to within usecs.
                         StatsLog.write(StatsLog.WALL_CLOCK_TIME_SHIFTED, nowRTC);
-                        removeImpl(mTimeTickSender);
-                        removeImpl(mDateChangeSender);
+                        removeImpl(null, mTimeTickTrigger);
+                        removeImpl(mDateChangeSender, null);
                         rebatchAllAlarms();
                         mClockReceiver.scheduleTimeTickEvent();
                         mClockReceiver.scheduleDateChangedEvent();
@@ -3764,14 +3808,8 @@
     void setWakelockWorkSource(PendingIntent pi, WorkSource ws, int type, String tag,
             int knownUid, boolean first) {
         try {
-            final boolean unimportant = pi == mTimeTickSender;
-            mWakeLock.setUnimportantForLogging(unimportant);
-            if (first || mLastWakeLockUnimportantForLogging) {
-                mWakeLock.setHistoryTag(tag);
-            } else {
-                mWakeLock.setHistoryTag(null);
-            }
-            mLastWakeLockUnimportantForLogging = unimportant;
+            mWakeLock.setHistoryTag(first ? tag : null);
+
             if (ws != null) {
                 mWakeLock.setWorkSource(ws);
                 return;
@@ -3828,7 +3866,7 @@
                             if (alarm.repeatInterval > 0) {
                                 // This IntentSender is no longer valid, but this
                                 // is a repeating alarm, so toss the hoser.
-                                removeImpl(alarm.operation);
+                                removeImpl(alarm.operation, null);
                             }
                         }
                     }
@@ -3886,22 +3924,13 @@
     class ClockReceiver extends BroadcastReceiver {
         public ClockReceiver() {
             IntentFilter filter = new IntentFilter();
-            filter.addAction(Intent.ACTION_TIME_TICK);
             filter.addAction(Intent.ACTION_DATE_CHANGED);
             getContext().registerReceiver(this, filter);
         }
 
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {
-                if (DEBUG_BATCH) {
-                    Slog.v(TAG, "Received TIME_TICK alarm; rescheduling");
-                }
-                synchronized (mLock) {
-                    mLastTickReceived = mInjector.getCurrentTimeMillis();
-                }
-                scheduleTimeTickEvent();
-            } else if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
+            if (intent.getAction().equals(Intent.ACTION_DATE_CHANGED)) {
                 // Since the kernel does not keep track of DST, we need to
                 // reset the TZ information at the beginning of each day
                 // based off of the current Zone gmt offset + userspace tracked
@@ -3923,7 +3952,7 @@
 
             final WorkSource workSource = null; // Let system take blame for time tick events.
             setImpl(ELAPSED_REALTIME, mInjector.getElapsedRealtime() + tickEventDelay, 0,
-                    0, mTimeTickSender, null, null, AlarmManager.FLAG_STANDALONE, workSource,
+                    0, null, mTimeTickTrigger, null, AlarmManager.FLAG_STANDALONE, workSource,
                     null, Process.myUid(), "android");
 
             // Finally, remember when we set the tick alarm
@@ -4333,10 +4362,6 @@
                 // PendingIntent alarm
                 mSendCount++;
 
-                if (alarm.priorityClass.priority == PRIO_TICK) {
-                    mLastTickIssued = nowELAPSED;
-                }
-
                 try {
                     alarm.operation.send(getContext(), 0,
                             mBackgroundIntent.putExtra(
@@ -4344,13 +4369,10 @@
                                     mDeliveryTracker, mHandler, null,
                                     allowWhileIdle ? mIdleOptions : null);
                 } catch (PendingIntent.CanceledException e) {
-                    if (alarm.operation == mTimeTickSender) {
-                        Slog.wtf(TAG, "mTimeTickSender canceled");
-                    }
                     if (alarm.repeatInterval > 0) {
                         // This IntentSender is no longer valid, but this
                         // is a repeating alarm, so toss it
-                        removeImpl(alarm.operation);
+                        removeImpl(alarm.operation, null);
                     }
                     // No actual delivery was possible, so the delivery tracker's
                     // 'finished' callback won't be invoked.  We also don't need
@@ -4362,6 +4384,16 @@
             } else {
                 // Direct listener callback alarm
                 mListenerCount++;
+
+                if (RECORD_ALARMS_IN_HISTORY) {
+                    if (alarm.listener == mTimeTickTrigger) {
+                        mTickHistory[mNextTickHistory++] = nowELAPSED;
+                        if (mNextTickHistory >= TICK_HISTORY_DEPTH) {
+                            mNextTickHistory = 0;
+                        }
+                    }
+                }
+
                 try {
                     if (DEBUG_LISTENER_CALLBACK) {
                         Slog.v(TAG, "Alarm to uid=" + alarm.uid
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 953c99f..1c8d99a 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -35,6 +35,8 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
+import static android.net.NetworkPolicyManager.RULE_NONE;
+import static android.net.NetworkPolicyManager.uidRulesToString;
 import static android.os.Process.INVALID_UID;
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
@@ -189,6 +191,7 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Comparator;
+import java.util.ConcurrentModificationException;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -257,6 +260,14 @@
     @GuardedBy("mVpns")
     private LockdownVpnTracker mLockdownTracker;
 
+    /**
+     * Stale copy of uid rules provided by NPMS. As long as they are accessed only in internal
+     * handler thread, they don't need a lock.
+     */
+    private SparseIntArray mUidRules = new SparseIntArray();
+    /** Flag indicating if background data is restricted. */
+    private boolean mRestrictBackground;
+
     final private Context mContext;
     // 0 is full bad, 100 is full good
     private int mDefaultInetConditionPublished = 0;
@@ -419,6 +430,16 @@
     // Handle private DNS validation status updates.
     private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
 
+    /**
+     * Used to handle onUidRulesChanged event from NetworkPolicyManagerService.
+     */
+    private static final int EVENT_UID_RULES_CHANGED = 39;
+
+    /**
+     * Used to handle onRestrictBackgroundChanged event from NetworkPolicyManagerService.
+     */
+    private static final int EVENT_DATA_SAVER_CHANGED = 40;
+
     private static String eventName(int what) {
         return sMagicDecoderRing.get(what, Integer.toString(what));
     }
@@ -780,6 +801,9 @@
         mKeyStore = KeyStore.getInstance();
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
 
+        // To ensure uid rules are synchronized with Network Policy, register for
+        // NetworkPolicyManagerService events must happen prior to NetworkPolicyManagerService
+        // reading existing policy from disk.
         try {
             mPolicyManager.registerListener(mPolicyListener);
         } catch (RemoteException e) {
@@ -910,7 +934,8 @@
         registerPrivateDnsSettingsCallbacks();
     }
 
-    private Tethering makeTethering() {
+    @VisibleForTesting
+    protected Tethering makeTethering() {
         // TODO: Move other elements into @Overridden getters.
         final TetheringDependencies deps = new TetheringDependencies() {
             @Override
@@ -1116,11 +1141,6 @@
         if (ignoreBlocked) {
             return false;
         }
-        // Networks are never blocked for system services
-        // TODO: consider moving this check to NetworkPolicyManagerInternal.isUidNetworkingBlocked.
-        if (isSystem(uid)) {
-            return false;
-        }
         synchronized (mVpns) {
             final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
             if (vpn != null && vpn.isBlockingUid(uid)) {
@@ -1150,6 +1170,17 @@
         mNetworkInfoBlockingLogs.log(action + " " + uid);
     }
 
+    private void maybeLogBlockedStatusChanged(NetworkRequestInfo nri, Network net,
+            boolean blocked) {
+        if (nri == null || net == null || !LOGD_BLOCKED_NETWORKINFO) {
+            return;
+        }
+        String action = blocked ? "BLOCKED" : "UNBLOCKED";
+        log(String.format("Blocked status changed to %s for %d(%d) on netId %d", blocked,
+                nri.mUid, nri.request.requestId, net.netId));
+        mNetworkInfoBlockingLogs.log(action + " " + nri.mUid);
+    }
+
     /**
      * Apply any relevant filters to {@link NetworkState} for the given UID. For
      * example, this may mark the network as {@link DetailedState#BLOCKED} based
@@ -1651,10 +1682,17 @@
     private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
         @Override
         public void onUidRulesChanged(int uid, int uidRules) {
-            // TODO: notify UID when it has requested targeted updates
+            mHandler.sendMessage(mHandler.obtainMessage(EVENT_UID_RULES_CHANGED, uid, uidRules));
         }
         @Override
         public void onRestrictBackgroundChanged(boolean restrictBackground) {
+            // caller is NPMS, since we only register with them
+            if (LOGD_BLOCKED_NETWORKINFO) {
+                log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
+            }
+            mHandler.sendMessage(mHandler.obtainMessage(
+                    EVENT_DATA_SAVER_CHANGED, restrictBackground ? 1 : 0, 0));
+
             // TODO: relocate this specific callback in Tethering.
             if (restrictBackground) {
                 log("onRestrictBackgroundChanged(true): disabling tethering");
@@ -1663,6 +1701,50 @@
         }
     };
 
+    void handleUidRulesChanged(int uid, int newRules) {
+        // skip update when we've already applied rules
+        final int oldRules = mUidRules.get(uid, RULE_NONE);
+        if (oldRules == newRules) return;
+
+        maybeNotifyNetworkBlockedForNewUidRules(uid, newRules);
+
+        if (newRules == RULE_NONE) {
+            mUidRules.delete(uid);
+        } else {
+            mUidRules.put(uid, newRules);
+        }
+    }
+
+    void handleRestrictBackgroundChanged(boolean restrictBackground) {
+        if (mRestrictBackground == restrictBackground) return;
+
+        for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
+            final boolean curMetered = nai.networkCapabilities.isMetered();
+            maybeNotifyNetworkBlocked(nai, curMetered, curMetered, mRestrictBackground,
+                    restrictBackground);
+        }
+
+        mRestrictBackground = restrictBackground;
+    }
+
+    private boolean isUidNetworkingWithVpnBlocked(int uid, int uidRules, boolean isNetworkMetered,
+            boolean isBackgroundRestricted) {
+        synchronized (mVpns) {
+            final Vpn vpn = mVpns.get(UserHandle.getUserId(uid));
+            // Because the return value of this function depends on the list of UIDs the
+            // always-on VPN blocks when in lockdown mode, when the always-on VPN changes that
+            // list all state depending on the return value of this function has to be recomputed.
+            // TODO: add a trigger when the always-on VPN sets its blocked UIDs to reevaluate and
+            // send the necessary onBlockedStatusChanged callbacks.
+            if (vpn != null && vpn.isBlockingUid(uid)) {
+                return true;
+            }
+        }
+
+        return mPolicyManagerInternal.isUidNetworkingBlocked(uid, uidRules,
+                isNetworkMetered, isBackgroundRestricted);
+    }
+
     /**
      * Require that the caller is either in the same user or has appropriate permission to interact
      * across users.
@@ -1679,6 +1761,16 @@
                 "ConnectivityService");
     }
 
+    private void enforceAnyPermissionOf(String... permissions) {
+        for (String permission : permissions) {
+            if (mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED) {
+                return;
+            }
+        }
+        throw new SecurityException(
+            "Requires one of the following permissions: " + String.join(", ", permissions) + ".");
+    }
+
     private void enforceInternetPermission() {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.INTERNET,
@@ -1723,6 +1815,13 @@
                 "ConnectivityService");
     }
 
+    private void enforceNetworkStackSettingsOrSetup() {
+        enforceAnyPermissionOf(
+            android.Manifest.permission.NETWORK_SETTINGS,
+            android.Manifest.permission.NETWORK_SETUP_WIZARD,
+            android.Manifest.permission.NETWORK_STACK);
+    }
+
     private boolean checkNetworkStackPermission() {
         return PERMISSION_GRANTED == mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.NETWORK_STACK);
@@ -1798,7 +1897,8 @@
 
     private void sendStickyBroadcast(Intent intent) {
         synchronized (this) {
-            if (!mSystemReady) {
+            if (!mSystemReady
+                    && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                 mInitialBroadcast = new Intent(intent);
             }
             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
@@ -1837,7 +1937,7 @@
     }
 
     void systemReady() {
-        loadGlobalProxy();
+        mProxyTracker.loadGlobalProxy();
         registerNetdEventCallback();
 
         synchronized (this) {
@@ -1847,8 +1947,6 @@
                 mInitialBroadcast = null;
             }
         }
-        // load the global proxy at startup
-        mHandler.sendMessage(mHandler.obtainMessage(EVENT_APPLY_GLOBAL_HTTP_PROXY));
 
         // Try bringing up tracker, but KeyStore won't be ready yet for secondary users so wait
         // for user to unlock device too.
@@ -2102,6 +2200,28 @@
         pw.decreaseIndent();
         pw.println();
 
+        pw.print("Restrict background: ");
+        pw.println(mRestrictBackground);
+        pw.println();
+
+        pw.println("Status for known UIDs:");
+        pw.increaseIndent();
+        final int size = mUidRules.size();
+        for (int i = 0; i < size; i++) {
+            // Don't crash if the array is modified while dumping in bugreports.
+            try {
+                final int uid = mUidRules.keyAt(i);
+                final int uidRules = mUidRules.get(uid, RULE_NONE);
+                pw.println("UID=" + uid + " rules=" + uidRulesToString(uidRules));
+            } catch (ArrayIndexOutOfBoundsException e) {
+                pw.println("  ArrayIndexOutOfBoundsException");
+            } catch (ConcurrentModificationException e) {
+                pw.println("  ConcurrentModificationException");
+            }
+        }
+        pw.println();
+        pw.decreaseIndent();
+
         pw.println("Network Requests:");
         pw.increaseIndent();
         dumpNetworkRequests(pw);
@@ -3089,7 +3209,7 @@
                     break;
                 }
                 case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
-                    handleDeprecatedGlobalHttpProxy();
+                    mProxyTracker.loadDeprecatedGlobalHttpProxy();
                     break;
                 }
                 case EVENT_PROXY_HAS_CHANGED: {
@@ -3179,6 +3299,12 @@
                     handlePrivateDnsValidationUpdate(
                             (PrivateDnsValidationUpdate) msg.obj);
                     break;
+                case EVENT_UID_RULES_CHANGED:
+                    handleUidRulesChanged(msg.arg1, msg.arg2);
+                    break;
+                case EVENT_DATA_SAVER_CHANGED:
+                    handleRestrictBackgroundChanged(toBool(msg.arg1));
+                    break;
             }
         }
     }
@@ -3455,31 +3581,6 @@
         mProxyTracker.setGlobalProxy(proxyProperties);
     }
 
-    private void loadGlobalProxy() {
-        ContentResolver res = mContext.getContentResolver();
-        String host = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST);
-        int port = Settings.Global.getInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, 0);
-        String exclList = Settings.Global.getString(res,
-                Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
-        String pacFileUrl = Settings.Global.getString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC);
-        if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
-            ProxyInfo proxyProperties;
-            if (!TextUtils.isEmpty(pacFileUrl)) {
-                proxyProperties = new ProxyInfo(pacFileUrl);
-            } else {
-                proxyProperties = new ProxyInfo(host, port, exclList);
-            }
-            if (!proxyProperties.isValid()) {
-                if (DBG) log("Invalid proxy properties, ignoring: " + proxyProperties.toString());
-                return;
-            }
-
-            synchronized (mProxyTracker.mProxyLock) {
-                mProxyTracker.mGlobalProxy = proxyProperties;
-            }
-        }
-    }
-
     @Override
     @Nullable
     public ProxyInfo getGlobalProxy() {
@@ -3504,30 +3605,7 @@
         ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
 
         if (!ProxyTracker.proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
-            mProxyTracker.sendProxyBroadcast(mProxyTracker.getDefaultProxy());
-        }
-    }
-
-    private void handleDeprecatedGlobalHttpProxy() {
-        final String proxy = Settings.Global.getString(mContext.getContentResolver(),
-                Settings.Global.HTTP_PROXY);
-        if (!TextUtils.isEmpty(proxy)) {
-            String data[] = proxy.split(":");
-            if (data.length == 0) {
-                return;
-            }
-
-            final String proxyHost = data[0];
-            int proxyPort = 8080;
-            if (data.length > 1) {
-                try {
-                    proxyPort = Integer.parseInt(data[1]);
-                } catch (NumberFormatException e) {
-                    return;
-                }
-            }
-            final ProxyInfo p = new ProxyInfo(proxyHost, proxyPort, "");
-            setGlobalProxy(p);
+            mProxyTracker.sendProxyBroadcast();
         }
     }
 
@@ -3815,6 +3893,8 @@
     private void setLockdownTracker(LockdownVpnTracker tracker) {
         // Shutdown any existing tracker
         final LockdownVpnTracker existing = mLockdownTracker;
+        // TODO: Add a trigger when the always-on VPN enable/disable to reevaluate and send the
+        // necessary onBlockedStatusChanged callbacks.
         mLockdownTracker = null;
         if (existing != null) {
             existing.shutdown();
@@ -4033,7 +4113,7 @@
 
     @Override
     public void setAirplaneMode(boolean enable) {
-        enforceConnectivityInternalPermission();
+        enforceNetworkStackSettingsOrSetup();
         final long ident = Binder.clearCallingIdentity();
         try {
             final ContentResolver cr = mContext.getContentResolver();
@@ -4814,15 +4894,14 @@
         }
     }
 
-    private String getNetworkPermission(NetworkCapabilities nc) {
-        // TODO: make these permission strings AIDL constants instead.
+    private int getNetworkPermission(NetworkCapabilities nc) {
         if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
-            return NetworkManagementService.PERMISSION_SYSTEM;
+            return INetd.PERMISSION_SYSTEM;
         }
         if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
-            return NetworkManagementService.PERMISSION_NETWORK;
+            return INetd.PERMISSION_NETWORK;
         }
-        return null;
+        return INetd.PERMISSION_NONE;
     }
 
     /**
@@ -4895,9 +4974,9 @@
 
         if (Objects.equals(nai.networkCapabilities, newNc)) return;
 
-        final String oldPermission = getNetworkPermission(nai.networkCapabilities);
-        final String newPermission = getNetworkPermission(newNc);
-        if (!Objects.equals(oldPermission, newPermission) && nai.created && !nai.isVPN()) {
+        final int oldPermission = getNetworkPermission(nai.networkCapabilities);
+        final int newPermission = getNetworkPermission(newNc);
+        if (oldPermission != newPermission && nai.created && !nai.isVPN()) {
             try {
                 mNMS.setNetworkPermission(nai.network.netId, newPermission);
             } catch (RemoteException e) {
@@ -4926,12 +5005,20 @@
             notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_CAP_CHANGED);
         }
 
-        // Report changes that are interesting for network statistics tracking.
         if (prevNc != null) {
-            final boolean meteredChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_METERED) !=
-                    newNc.hasCapability(NET_CAPABILITY_NOT_METERED);
+            final boolean oldMetered = prevNc.isMetered();
+            final boolean newMetered = newNc.isMetered();
+            final boolean meteredChanged = oldMetered != newMetered;
+
+            if (meteredChanged) {
+                maybeNotifyNetworkBlocked(nai, oldMetered, newMetered, mRestrictBackground,
+                        mRestrictBackground);
+            }
+
             final boolean roamingChanged = prevNc.hasCapability(NET_CAPABILITY_NOT_ROAMING) !=
                     newNc.hasCapability(NET_CAPABILITY_NOT_ROAMING);
+
+            // Report changes that are interesting for network statistics tracking.
             if (meteredChanged || roamingChanged) {
                 notifyIfacesChangedForNetworkStats();
             }
@@ -5061,6 +5148,8 @@
             case ConnectivityManager.CALLBACK_AVAILABLE: {
                 putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities));
                 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
+                // For this notification, arg1 contains the blocked status.
+                msg.arg1 = arg1;
                 break;
             }
             case ConnectivityManager.CALLBACK_LOSING: {
@@ -5078,6 +5167,10 @@
                 putParcelable(bundle, new LinkProperties(networkAgent.linkProperties));
                 break;
             }
+            case ConnectivityManager.CALLBACK_BLK_CHANGED: {
+                msg.arg1 = arg1;
+                break;
+            }
         }
         msg.what = notificationType;
         msg.setData(bundle);
@@ -5562,15 +5655,7 @@
 
             if (networkAgent.isVPN()) {
                 // Temporarily disable the default proxy (not global).
-                synchronized (mProxyTracker.mProxyLock) {
-                    if (!mProxyTracker.mDefaultProxyDisabled) {
-                        mProxyTracker.mDefaultProxyDisabled = true;
-                        if (mProxyTracker.mGlobalProxy == null
-                                && mProxyTracker.mDefaultProxy != null) {
-                            mProxyTracker.sendProxyBroadcast(null);
-                        }
-                    }
-                }
+                mProxyTracker.setDefaultProxyEnabled(false);
                 // TODO: support proxy per network.
             }
 
@@ -5592,15 +5677,7 @@
         } else if (state == NetworkInfo.State.DISCONNECTED) {
             networkAgent.asyncChannel.disconnect();
             if (networkAgent.isVPN()) {
-                synchronized (mProxyTracker.mProxyLock) {
-                    if (mProxyTracker.mDefaultProxyDisabled) {
-                        mProxyTracker.mDefaultProxyDisabled = false;
-                        if (mProxyTracker.mGlobalProxy == null
-                                && mProxyTracker.mDefaultProxy != null) {
-                            mProxyTracker.sendProxyBroadcast(mProxyTracker.mDefaultProxy);
-                        }
-                    }
-                }
+                mProxyTracker.setDefaultProxyEnabled(true);
                 updateUids(networkAgent, networkAgent.networkCapabilities, null);
             }
             disconnectAndDestroyNetwork(networkAgent);
@@ -5649,7 +5726,76 @@
             return;
         }
 
-        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, 0);
+        final boolean metered = nai.networkCapabilities.isMetered();
+        final boolean blocked = isUidNetworkingWithVpnBlocked(nri.mUid, mUidRules.get(nri.mUid),
+                metered, mRestrictBackground);
+        callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_AVAILABLE, blocked ? 1 : 0);
+    }
+
+    /**
+     * Notify of the blocked state apps with a registered callback matching a given NAI.
+     *
+     * Unlike other callbacks, blocked status is different between each individual uid. So for
+     * any given nai, all requests need to be considered according to the uid who filed it.
+     *
+     * @param nai The target NetworkAgentInfo.
+     * @param oldMetered True if the previous network capabilities is metered.
+     * @param newRestrictBackground True if data saver is enabled.
+     */
+    private void maybeNotifyNetworkBlocked(NetworkAgentInfo nai, boolean oldMetered,
+            boolean newMetered, boolean oldRestrictBackground, boolean newRestrictBackground) {
+
+        for (int i = 0; i < nai.numNetworkRequests(); i++) {
+            NetworkRequest nr = nai.requestAt(i);
+            NetworkRequestInfo nri = mNetworkRequests.get(nr);
+            final int uidRules = mUidRules.get(nri.mUid);
+            final boolean oldBlocked, newBlocked;
+            // mVpns lock needs to be hold here to ensure that the active VPN cannot be changed
+            // between these two calls.
+            synchronized (mVpns) {
+                oldBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, oldMetered,
+                        oldRestrictBackground);
+                newBlocked = isUidNetworkingWithVpnBlocked(nri.mUid, uidRules, newMetered,
+                        newRestrictBackground);
+            }
+            if (oldBlocked != newBlocked) {
+                callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED,
+                        encodeBool(newBlocked));
+            }
+        }
+    }
+
+    /**
+     * Notify apps with a given UID of the new blocked state according to new uid rules.
+     * @param uid The uid for which the rules changed.
+     * @param newRules The new rules to apply.
+     */
+    private void maybeNotifyNetworkBlockedForNewUidRules(int uid, int newRules) {
+        for (final NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
+            final boolean metered = nai.networkCapabilities.isMetered();
+            final boolean oldBlocked, newBlocked;
+            // TODO: Consider that doze mode or turn on/off battery saver would deliver lots of uid
+            // rules changed event. And this function actually loop through all connected nai and
+            // its requests. It seems that mVpns lock will be grabbed frequently in this case.
+            // Reduce the number of locking or optimize the use of lock are likely needed in future.
+            synchronized (mVpns) {
+                oldBlocked = isUidNetworkingWithVpnBlocked(
+                        uid, mUidRules.get(uid), metered, mRestrictBackground);
+                newBlocked = isUidNetworkingWithVpnBlocked(
+                        uid, newRules, metered, mRestrictBackground);
+            }
+            if (oldBlocked == newBlocked) {
+                return;
+            }
+            final int arg = encodeBool(newBlocked);
+            for (int i = 0; i < nai.numNetworkRequests(); i++) {
+                NetworkRequest nr = nai.requestAt(i);
+                NetworkRequestInfo nri = mNetworkRequests.get(nr);
+                if (nri != null && nri.mUid == uid) {
+                    callCallbackForRequest(nri, nai, ConnectivityManager.CALLBACK_BLK_CHANGED, arg);
+                }
+            }
+        }
     }
 
     private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, DetailedState state, int type) {
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index a34c2b9..af9d4c8 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -54,6 +54,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
+import android.os.PowerManager.ServiceType;
 import android.os.PowerManagerInternal;
 import android.os.Process;
 import android.os.RemoteCallbackList;
@@ -77,6 +78,7 @@
 import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
 import com.android.internal.os.AtomicFile;
 import com.android.internal.os.BackgroundThread;
@@ -104,6 +106,153 @@
 
 /**
  * Keeps track of device idleness and drives low power mode based on that.
+ *
+ * Test: atest com.android.server.DeviceIdleControllerTest
+ *
+ * Current idling state machine (as of Android 9 Pie). This can be visualized using Graphviz:
+
+   digraph {
+     subgraph deep {
+       label="deep";
+
+       STATE_ACTIVE [label="STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon"]
+       STATE_INACTIVE [label="STATE_INACTIVE\nScreen off AND Not charging"]
+       STATE_QUICK_DOZE_DELAY [
+         label="STATE_QUICK_DOZE_DELAY\n"
+             + "Screen off AND Not charging\n"
+             + "Location, motion detection, and significant motion monitoring turned off"
+       ]
+       STATE_IDLE_PENDING [
+         label="STATE_IDLE_PENDING\nSignificant motion monitoring turned on"
+       ]
+       STATE_SENSING [label="STATE_SENSING\nMonitoring for ANY motion"]
+       STATE_LOCATING [
+         label="STATE_LOCATING\nRequesting location, motion monitoring still on"
+       ]
+       STATE_IDLE [
+         label="STATE_IDLE\nLocation and motion detection turned off\n"
+             + "Significant motion monitoring state unchanged"
+       ]
+       STATE_IDLE_MAINTENANCE [label="STATE_IDLE_MAINTENANCE\n"]
+
+       STATE_ACTIVE -> STATE_INACTIVE [
+         label="becomeInactiveIfAppropriateLocked() AND Quick Doze not enabled"
+       ]
+       STATE_ACTIVE -> STATE_QUICK_DOZE_DELAY [
+         label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+       ]
+
+       STATE_INACTIVE -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_INACTIVE -> STATE_IDLE_PENDING [label="stepIdleStateLocked()"]
+       STATE_INACTIVE -> STATE_QUICK_DOZE_DELAY [
+         label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+       ]
+
+       STATE_IDLE_PENDING -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_IDLE_PENDING -> STATE_SENSING [label="stepIdleStateLocked()"]
+       STATE_IDLE_PENDING -> STATE_QUICK_DOZE_DELAY [
+         label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+       ]
+
+       STATE_SENSING -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_SENSING -> STATE_LOCATING [label="stepIdleStateLocked()"]
+       STATE_SENSING -> STATE_QUICK_DOZE_DELAY [
+         label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+       ]
+       STATE_SENSING -> STATE_IDLE [
+         label="stepIdleStateLocked()\n"
+             + "No Location Manager OR (no Network provider AND no GPS provider)"
+       ]
+
+       STATE_LOCATING -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_LOCATING -> STATE_QUICK_DOZE_DELAY [
+         label="becomeInactiveIfAppropriateLocked() AND Quick Doze enabled"
+       ]
+       STATE_LOCATING -> STATE_IDLE [label="stepIdleStateLocked()"]
+
+       STATE_QUICK_DOZE_DELAY -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_QUICK_DOZE_DELAY -> STATE_IDLE [label="stepIdleStateLocked()"]
+
+       STATE_IDLE -> STATE_ACTIVE [label="handleMotionDetectedLocked(), becomeActiveLocked()"]
+       STATE_IDLE -> STATE_IDLE_MAINTENANCE [label="stepIdleStateLocked()"]
+
+       STATE_IDLE_MAINTENANCE -> STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+       STATE_IDLE_MAINTENANCE -> STATE_IDLE [
+         label="stepIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
+       ]
+     }
+
+     subgraph light {
+       label="light"
+
+       LIGHT_STATE_ACTIVE [
+         label="LIGHT_STATE_ACTIVE\nScreen on OR Charging OR Alarm going off soon"
+       ]
+       LIGHT_STATE_INACTIVE [label="LIGHT_STATE_INACTIVE\nScreen off AND Not charging"]
+       LIGHT_STATE_PRE_IDLE [
+         label="LIGHT_STATE_PRE_IDLE\n"
+             + "Delay going into LIGHT_STATE_IDLE due to some running jobs or alarms"
+       ]
+       LIGHT_STATE_IDLE [label="LIGHT_STATE_IDLE\n"]
+       LIGHT_STATE_WAITING_FOR_NETWORK [
+         label="LIGHT_STATE_WAITING_FOR_NETWORK\n"
+             + "Coming out of LIGHT_STATE_IDLE, waiting for network"
+       ]
+       LIGHT_STATE_IDLE_MAINTENANCE [label="LIGHT_STATE_IDLE_MAINTENANCE\n"]
+       LIGHT_STATE_OVERRIDE [
+         label="LIGHT_STATE_OVERRIDE\nDevice in deep doze, light no longer changing states"
+       ]
+
+       LIGHT_STATE_ACTIVE -> LIGHT_STATE_INACTIVE [
+         label="becomeInactiveIfAppropriateLocked()"
+       ]
+       LIGHT_STATE_ACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
+
+       LIGHT_STATE_INACTIVE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
+       LIGHT_STATE_INACTIVE -> LIGHT_STATE_PRE_IDLE [label="active jobs"]
+       LIGHT_STATE_INACTIVE -> LIGHT_STATE_IDLE [label="no active jobs"]
+       LIGHT_STATE_INACTIVE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
+
+       LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
+       LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_IDLE [
+         label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
+       ]
+       LIGHT_STATE_PRE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
+
+       LIGHT_STATE_IDLE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
+       LIGHT_STATE_IDLE -> LIGHT_STATE_WAITING_FOR_NETWORK [label="no network"]
+       LIGHT_STATE_IDLE -> LIGHT_STATE_IDLE_MAINTENANCE
+       LIGHT_STATE_IDLE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
+
+       LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
+       LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_IDLE_MAINTENANCE
+       LIGHT_STATE_WAITING_FOR_NETWORK -> LIGHT_STATE_OVERRIDE [
+         label="deep goes to STATE_IDLE"
+       ]
+
+       LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_ACTIVE [label="becomeActiveLocked()"]
+       LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_IDLE [
+         label="stepLightIdleStateLocked(), exitMaintenanceEarlyIfNeededLocked()"
+       ]
+       LIGHT_STATE_IDLE_MAINTENANCE -> LIGHT_STATE_OVERRIDE [label="deep goes to STATE_IDLE"]
+
+       LIGHT_STATE_OVERRIDE -> LIGHT_STATE_ACTIVE [
+         label="handleMotionDetectedLocked(), becomeActiveLocked()"
+       ]
+     }
+   }
  */
 public class DeviceIdleController extends SystemService
         implements AnyMotionDetector.DeviceIdleCallback {
@@ -121,11 +270,9 @@
     private ActivityTaskManagerInternal mLocalActivityTaskManager;
     private PowerManagerInternal mLocalPowerManager;
     private PowerManager mPowerManager;
-    private ConnectivityService mConnectivityService;
     private INetworkPolicyManager mNetworkPolicyManager;
     private SensorManager mSensorManager;
     private Sensor mMotionSensor;
-    private LocationManager mLocationManager;
     private LocationRequest mLocationRequest;
     private Intent mIdleIntent;
     private Intent mLightIdleIntent;
@@ -133,6 +280,7 @@
     private final AppStateTracker mAppStateTracker;
     private boolean mLightEnabled;
     private boolean mDeepEnabled;
+    private boolean mQuickDozeActivated;
     private boolean mForceIdle;
     private boolean mNetworkConnected;
     private boolean mScreenOn;
@@ -148,21 +296,35 @@
     private boolean mScreenLocked;
 
     /** Device is currently active. */
-    private static final int STATE_ACTIVE = 0;
+    @VisibleForTesting
+    static final int STATE_ACTIVE = 0;
     /** Device is inactive (screen off, no motion) and we are waiting to for idle. */
-    private static final int STATE_INACTIVE = 1;
+    @VisibleForTesting
+    static final int STATE_INACTIVE = 1;
     /** Device is past the initial inactive period, and waiting for the next idle period. */
-    private static final int STATE_IDLE_PENDING = 2;
+    @VisibleForTesting
+    static final int STATE_IDLE_PENDING = 2;
     /** Device is currently sensing motion. */
-    private static final int STATE_SENSING = 3;
+    @VisibleForTesting
+    static final int STATE_SENSING = 3;
     /** Device is currently finding location (and may still be sensing). */
-    private static final int STATE_LOCATING = 4;
+    @VisibleForTesting
+    static final int STATE_LOCATING = 4;
     /** Device is in the idle state, trying to stay asleep as much as possible. */
-    private static final int STATE_IDLE = 5;
+    @VisibleForTesting
+    static final int STATE_IDLE = 5;
     /** Device is in the idle state, but temporarily out of idle to do regular maintenance. */
-    private static final int STATE_IDLE_MAINTENANCE = 6;
+    @VisibleForTesting
+    static final int STATE_IDLE_MAINTENANCE = 6;
+    /**
+     * Device is inactive and should go straight into idle (foregoing motion and location
+     * monitoring), but allow some time for current work to complete first.
+     */
+    @VisibleForTesting
+    static final int STATE_QUICK_DOZE_DELAY = 7;
 
-    private static String stateToString(int state) {
+    @VisibleForTesting
+    static String stateToString(int state) {
         switch (state) {
             case STATE_ACTIVE: return "ACTIVE";
             case STATE_INACTIVE: return "INACTIVE";
@@ -171,26 +333,36 @@
             case STATE_LOCATING: return "LOCATING";
             case STATE_IDLE: return "IDLE";
             case STATE_IDLE_MAINTENANCE: return "IDLE_MAINTENANCE";
+            case STATE_QUICK_DOZE_DELAY: return "QUICK_DOZE_DELAY";
             default: return Integer.toString(state);
         }
     }
 
     /** Device is currently active. */
-    private static final int LIGHT_STATE_ACTIVE = 0;
+    @VisibleForTesting
+    static final int LIGHT_STATE_ACTIVE = 0;
     /** Device is inactive (screen off) and we are waiting to for the first light idle. */
-    private static final int LIGHT_STATE_INACTIVE = 1;
+    @VisibleForTesting
+    static final int LIGHT_STATE_INACTIVE = 1;
     /** Device is about to go idle for the first time, wait for current work to complete. */
-    private static final int LIGHT_STATE_PRE_IDLE = 3;
+    @VisibleForTesting
+    static final int LIGHT_STATE_PRE_IDLE = 3;
     /** Device is in the light idle state, trying to stay asleep as much as possible. */
-    private static final int LIGHT_STATE_IDLE = 4;
+    @VisibleForTesting
+    static final int LIGHT_STATE_IDLE = 4;
     /** Device is in the light idle state, we want to go in to idle maintenance but are
      * waiting for network connectivity before doing so. */
-    private static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5;
+    @VisibleForTesting
+    static final int LIGHT_STATE_WAITING_FOR_NETWORK = 5;
     /** Device is in the light idle state, but temporarily out of idle to do regular maintenance. */
-    private static final int LIGHT_STATE_IDLE_MAINTENANCE = 6;
+    @VisibleForTesting
+    static final int LIGHT_STATE_IDLE_MAINTENANCE = 6;
     /** Device light idle state is overriden, now applying deep doze state. */
-    private static final int LIGHT_STATE_OVERRIDE = 7;
-    private static String lightStateToString(int state) {
+    @VisibleForTesting
+    static final int LIGHT_STATE_OVERRIDE = 7;
+
+    @VisibleForTesting
+    static String lightStateToString(int state) {
         switch (state) {
             case LIGHT_STATE_ACTIVE: return "ACTIVE";
             case LIGHT_STATE_INACTIVE: return "INACTIVE";
@@ -382,6 +554,8 @@
         public void onAlarm() {
             if (mState == STATE_SENSING) {
                 synchronized (DeviceIdleController.this) {
+                    // Restart the device idle progression in case the device moved but the screen
+                    // didn't turn on.
                     becomeInactiveIfAppropriateLocked();
                 }
             }
@@ -422,11 +596,16 @@
         }
     };
 
-    private final class MotionListener extends TriggerEventListener
+    @VisibleForTesting
+    final class MotionListener extends TriggerEventListener
             implements SensorEventListener {
 
         boolean active = false;
 
+        public boolean isActive() {
+            return active;
+        }
+
         @Override
         public void onTrigger(TriggerEvent event) {
             synchronized (DeviceIdleController.this) {
@@ -472,7 +651,7 @@
             active = false;
         }
     }
-    private final MotionListener mMotionListener = new MotionListener();
+    @VisibleForTesting final MotionListener mMotionListener = new MotionListener();
 
     private final LocationListener mGenericLocationListener = new LocationListener() {
         @Override
@@ -521,7 +700,8 @@
      * global Settings. Any access to this class or its fields should be done while
      * holding the DeviceIdleController lock.
      */
-    private final class Constants extends ContentObserver {
+    @VisibleForTesting
+    final class Constants extends ContentObserver {
         // Key names stored in the settings value.
         private static final String KEY_LIGHT_IDLE_AFTER_INACTIVE_TIMEOUT
                 = "light_after_inactive_to";
@@ -544,6 +724,7 @@
         private static final String KEY_IDLE_PENDING_TIMEOUT = "idle_pending_to";
         private static final String KEY_MAX_IDLE_PENDING_TIMEOUT = "max_idle_pending_to";
         private static final String KEY_IDLE_PENDING_FACTOR = "idle_pending_factor";
+        private static final String KEY_QUICK_DOZE_DELAY_TIMEOUT = "quick_doze_delay_to";
         private static final String KEY_IDLE_TIMEOUT = "idle_to";
         private static final String KEY_MAX_IDLE_TIMEOUT = "max_idle_to";
         private static final String KEY_IDLE_FACTOR = "idle_factor";
@@ -594,7 +775,7 @@
         public float LIGHT_IDLE_FACTOR;
 
         /**
-         * This is the maximum time we will run in idle maintenence mode.
+         * This is the maximum time we will run in idle maintenance mode.
          * @see Settings.Global#DEVICE_IDLE_CONSTANTS
          * @see #KEY_LIGHT_MAX_IDLE_TIMEOUT
          */
@@ -720,6 +901,15 @@
         public float IDLE_PENDING_FACTOR;
 
         /**
+         * This is amount of time we will wait from the point where we go into
+         * STATE_QUICK_DOZE_DELAY until we actually go into STATE_IDLE, while waiting for jobs
+         * and other current activity to finish.
+         * @see Settings.Global#DEVICE_IDLE_CONSTANTS
+         * @see #KEY_QUICK_DOZE_DELAY_TIMEOUT
+         */
+        public long QUICK_DOZE_DELAY_TIMEOUT;
+
+        /**
          * This is the initial time that we want to sit in the idle state before waking up
          * again to return to pending idle and allowing normal work to run.
          * @see Settings.Global#DEVICE_IDLE_CONSTANTS
@@ -855,6 +1045,8 @@
                         !COMPRESS_TIME ? 10 * 60 * 1000L : 60 * 1000L);
                 IDLE_PENDING_FACTOR = mParser.getFloat(KEY_IDLE_PENDING_FACTOR,
                         2f);
+                QUICK_DOZE_DELAY_TIMEOUT = mParser.getDurationMillis(
+                        KEY_QUICK_DOZE_DELAY_TIMEOUT, !COMPRESS_TIME ? 60 * 1000L : 15 * 1000L);
                 IDLE_TIMEOUT = mParser.getDurationMillis(KEY_IDLE_TIMEOUT,
                         !COMPRESS_TIME ? 60 * 60 * 1000L : 6 * 60 * 1000L);
                 MAX_IDLE_TIMEOUT = mParser.getDurationMillis(KEY_MAX_IDLE_TIMEOUT,
@@ -949,6 +1141,10 @@
             pw.print("    "); pw.print(KEY_IDLE_PENDING_FACTOR); pw.print("=");
             pw.println(IDLE_PENDING_FACTOR);
 
+            pw.print("    "); pw.print(KEY_QUICK_DOZE_DELAY_TIMEOUT); pw.print("=");
+            TimeUtils.formatDuration(QUICK_DOZE_DELAY_TIMEOUT, pw);
+            pw.println();
+
             pw.print("    "); pw.print(KEY_IDLE_TIMEOUT); pw.print("=");
             TimeUtils.formatDuration(IDLE_TIMEOUT, pw);
             pw.println();
@@ -1360,6 +1556,59 @@
         }
     }
 
+    static class Injector {
+        private final Context mContext;
+        private ConnectivityService mConnectivityService;
+        private LocationManager mLocationManager;
+
+        Injector(Context ctx) {
+            mContext = ctx;
+        }
+
+        AlarmManager getAlarmManager() {
+            return mContext.getSystemService(AlarmManager.class);
+        }
+
+        AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm,
+                AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) {
+            return new AnyMotionDetector(getPowerManager(), handler, sm, callback, angleThreshold);
+        }
+
+        AppStateTracker getAppStateTracker(Context ctx, Looper looper) {
+            return new AppStateTracker(ctx, looper);
+        }
+
+        ConnectivityService getConnectivityService() {
+            if (mConnectivityService == null) {
+                mConnectivityService = (ConnectivityService) ServiceManager.getService(
+                        Context.CONNECTIVITY_SERVICE);
+            }
+            return mConnectivityService;
+        }
+
+        Constants getConstants(DeviceIdleController controller, Handler handler,
+                ContentResolver resolver) {
+            return controller.new Constants(handler, resolver);
+        }
+
+        LocationManager getLocationManager() {
+            if (mLocationManager == null) {
+                mLocationManager = mContext.getSystemService(LocationManager.class);
+            }
+            return mLocationManager;
+        }
+
+        MyHandler getHandler(DeviceIdleController controller) {
+            return controller.new MyHandler(BackgroundThread.getHandler().getLooper());
+        }
+
+        PowerManager getPowerManager() {
+            return mContext.getSystemService(PowerManager.class);
+        }
+    }
+
+    private final Injector mInjector;
+
     private ActivityTaskManagerInternal.ScreenObserver mScreenObserver =
             new ActivityTaskManagerInternal.ScreenObserver() {
                 @Override
@@ -1373,14 +1622,19 @@
                 }
             };
 
-    public DeviceIdleController(Context context) {
+    @VisibleForTesting DeviceIdleController(Context context, Injector injector) {
         super(context);
+        mInjector = injector;
         mConfigFile = new AtomicFile(new File(getSystemDir(), "deviceidle.xml"));
-        mHandler = new MyHandler(BackgroundThread.getHandler().getLooper());
-        mAppStateTracker = new AppStateTracker(context, FgThread.get().getLooper());
+        mHandler = mInjector.getHandler(this);
+        mAppStateTracker = mInjector.getAppStateTracker(context, FgThread.get().getLooper());
         LocalServices.addService(AppStateTracker.class, mAppStateTracker);
     }
 
+    public DeviceIdleController(Context context) {
+        this(context, new Injector(context));
+    }
+
     boolean isAppOnWhitelistInternal(int appid) {
         synchronized (this) {
             return Arrays.binarySearch(mPowerSaveWhitelistAllAppIdArray, appid) >= 0;
@@ -1434,7 +1688,7 @@
                 }
             }
 
-            mConstants = new Constants(mHandler, getContext().getContentResolver());
+            mConstants = mInjector.getConstants(this, mHandler, getContext().getContentResolver());
 
             readConfigFileLocked();
             updateWhitelistAppIdsLocked();
@@ -1459,20 +1713,18 @@
     public void onBootPhase(int phase) {
         if (phase == PHASE_SYSTEM_SERVICES_READY) {
             synchronized (this) {
-                mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
+                mAlarmManager = mInjector.getAlarmManager();
                 mBatteryStats = BatteryStatsService.getService();
                 mLocalActivityManager = getLocalService(ActivityManagerInternal.class);
                 mLocalActivityTaskManager = getLocalService(ActivityTaskManagerInternal.class);
                 mLocalPowerManager = getLocalService(PowerManagerInternal.class);
-                mPowerManager = getContext().getSystemService(PowerManager.class);
+                mPowerManager = mInjector.getPowerManager();
                 mActiveIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                         "deviceidle_maint");
                 mActiveIdleWakeLock.setReferenceCounted(false);
                 mGoingIdleWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                         "deviceidle_going_idle");
                 mGoingIdleWakeLock.setReferenceCounted(true);
-                mConnectivityService = (ConnectivityService)ServiceManager.getService(
-                        Context.CONNECTIVITY_SERVICE);
                 mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface(
                         ServiceManager.getService(Context.NETWORK_POLICY_SERVICE));
                 mNetworkPolicyManagerInternal = getLocalService(NetworkPolicyManagerInternal.class);
@@ -1495,8 +1747,6 @@
 
                 if (getContext().getResources().getBoolean(
                         com.android.internal.R.bool.config_autoPowerModePrefetchLocation)) {
-                    mLocationManager = (LocationManager) getContext().getSystemService(
-                            Context.LOCATION_SERVICE);
                     mLocationRequest = new LocationRequest()
                         .setQuality(LocationRequest.ACCURACY_FINE)
                         .setInterval(0)
@@ -1506,9 +1756,8 @@
 
                 float angleThreshold = getContext().getResources().getInteger(
                         com.android.internal.R.integer.config_autoPowerModeThresholdAngle) / 100f;
-                mAnyMotionDetector = new AnyMotionDetector(
-                        (PowerManager) getContext().getSystemService(Context.POWER_SERVICE),
-                        mHandler, mSensorManager, this, angleThreshold);
+                mAnyMotionDetector = mInjector.getAnyMotionDetector(mHandler, mSensorManager, this,
+                        angleThreshold);
 
                 mAppStateTracker.onSystemServicesReady();
 
@@ -1541,6 +1790,16 @@
                         mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray);
                 mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
 
+                mLocalPowerManager.registerLowPowerModeObserver(ServiceType.QUICK_DOZE,
+                        state -> {
+                            synchronized (DeviceIdleController.this) {
+                                updateQuickDozeFlagLocked(state.batterySaverEnabled);
+                            }
+                        });
+                updateQuickDozeFlagLocked(
+                        mLocalPowerManager.getLowPowerState(
+                                ServiceType.QUICK_DOZE).batterySaverEnabled);
+
                 mLocalActivityTaskManager.registerScreenObserver(mScreenObserver);
 
                 passWhiteListsToForceAppStandbyTrackerLocked();
@@ -1968,10 +2227,17 @@
         }
     }
 
+    @VisibleForTesting
+    boolean isNetworkConnected() {
+        synchronized (this) {
+            return mNetworkConnected;
+        }
+    }
+
     void updateConnectivityState(Intent connIntent) {
         ConnectivityService cm;
         synchronized (this) {
-            cm = mConnectivityService;
+            cm = mInjector.getConnectivityService();
         }
         if (cm == null) {
             return;
@@ -2005,6 +2271,13 @@
         }
     }
 
+    @VisibleForTesting
+    boolean isScreenOn() {
+        synchronized (this) {
+            return mScreenOn;
+        }
+    }
+
     void updateInteractivityLocked() {
         // The interactivity state from the power manager tells us whether the display is
         // in a state that we need to keep things running so they will update at a normal
@@ -2024,6 +2297,13 @@
         }
     }
 
+    @VisibleForTesting
+    boolean isCharging() {
+        synchronized (this) {
+            return mCharging;
+        }
+    }
+
     void updateChargingLocked(boolean charging) {
         if (DEBUG) Slog.i(TAG, "updateChargingLocked: charging=" + charging);
         if (!charging && mCharging) {
@@ -2039,6 +2319,27 @@
         }
     }
 
+    @VisibleForTesting
+    boolean isQuickDozeEnabled() {
+        synchronized (this) {
+            return mQuickDozeActivated;
+        }
+    }
+
+    /** Updates the quick doze flag and enters deep doze if appropriate. */
+    @VisibleForTesting
+    void updateQuickDozeFlagLocked(boolean enabled) {
+        if (DEBUG) Slog.i(TAG, "updateQuickDozeFlagLocked: enabled=" + enabled);
+        mQuickDozeActivated = enabled;
+        if (enabled) {
+            // If Quick Doze is enabled, see if we should go straight into it.
+            becomeInactiveIfAppropriateLocked();
+        }
+        // Going from Deep Doze to Light Idle (if quick doze becomes disabled) is tricky and
+        // probably not worth the overhead, so leave in deep doze if that's the case until the
+        // next natural time to come out of it.
+    }
+
     void keyguardShowingLocked(boolean showing) {
         if (DEBUG) Slog.i(TAG, "keyguardShowing=" + showing);
         if (mScreenLocked != showing) {
@@ -2071,17 +2372,53 @@
         }
     }
 
+    /** Must only be used in tests. */
+    @VisibleForTesting
+    void setDeepEnabledForTest(boolean enabled) {
+        synchronized (this) {
+            mDeepEnabled = enabled;
+        }
+    }
+
+    /** Must only be used in tests. */
+    @VisibleForTesting
+    void setLightEnabledForTest(boolean enabled) {
+        synchronized (this) {
+            mLightEnabled = enabled;
+        }
+    }
+
     void becomeInactiveIfAppropriateLocked() {
         if (DEBUG) Slog.d(TAG, "becomeInactiveIfAppropriateLocked()");
         if ((!mScreenOn && !mCharging) || mForceIdle) {
-            // Screen has turned off; we are now going to become inactive and start
-            // waiting to see if we will ultimately go idle.
-            if (mState == STATE_ACTIVE && mDeepEnabled) {
-                mState = STATE_INACTIVE;
-                if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
-                resetIdleManagementLocked();
-                scheduleAlarmLocked(mInactiveTimeout, false);
-                EventLogTags.writeDeviceIdle(mState, "no activity");
+            // Become inactive and determine if we will ultimately go idle.
+            if (mDeepEnabled) {
+                if (mQuickDozeActivated) {
+                    if (mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
+                            || mState == STATE_IDLE_MAINTENANCE) {
+                        // Already "idling". Don't want to restart the process.
+                        // mLightState can't be LIGHT_STATE_ACTIVE if mState is any of these 3
+                        // values, so returning here is safe.
+                        return;
+                    }
+                    if (DEBUG) {
+                        Slog.d(TAG, "Moved from "
+                                + stateToString(mState) + " to STATE_QUICK_DOZE_DELAY");
+                    }
+                    mState = STATE_QUICK_DOZE_DELAY;
+                    // Make sure any motion sensing or locating is stopped.
+                    resetIdleManagementLocked();
+                    // Wait a small amount of time in case something (eg: background service from
+                    // recently closed app) needs to finish running.
+                    scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
+                    EventLogTags.writeDeviceIdle(mState, "no activity");
+                } else if (mState == STATE_ACTIVE) {
+                    mState = STATE_INACTIVE;
+                    if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE");
+                    resetIdleManagementLocked();
+                    scheduleAlarmLocked(mInactiveTimeout, false);
+                    EventLogTags.writeDeviceIdle(mState, "no activity");
+                }
             }
             if (mLightState == LIGHT_STATE_ACTIVE && mLightEnabled) {
                 mLightState = LIGHT_STATE_INACTIVE;
@@ -2093,7 +2430,7 @@
         }
     }
 
-    void resetIdleManagementLocked() {
+    private void resetIdleManagementLocked() {
         mNextIdlePendingDelay = 0;
         mNextIdleDelay = 0;
         mNextLightIdleDelay = 0;
@@ -2104,7 +2441,7 @@
         mAnyMotionDetector.stop();
     }
 
-    void resetLightIdleManagementLocked() {
+    private void resetLightIdleManagementLocked() {
         cancelLightAlarmLocked();
     }
 
@@ -2117,6 +2454,23 @@
         }
     }
 
+    /**
+     * Must only be used in tests.
+     *
+     * This sets the state value directly and thus doesn't trigger any behavioral changes.
+     */
+    @VisibleForTesting
+    void setLightStateForTest(int lightState) {
+        synchronized (this) {
+            mLightState = lightState;
+        }
+    }
+
+    @VisibleForTesting
+    int getLightState() {
+        return mLightState;
+    }
+
     void stepLightIdleStateLocked(String reason) {
         if (mLightState == LIGHT_STATE_OVERRIDE) {
             // If we are already in deep device idle mode, then
@@ -2200,6 +2554,12 @@
         }
     }
 
+    @VisibleForTesting
+    int getState() {
+        return mState;
+    }
+
+    @VisibleForTesting
     void stepIdleStateLocked(String reason) {
         if (DEBUG) Slog.d(TAG, "stepIdleStateLocked: mState=" + mState);
         EventLogTags.writeDeviceIdleStep();
@@ -2220,9 +2580,6 @@
                 // for motion and sleep some more while doing so.
                 startMonitoringMotionLocked();
                 scheduleAlarmLocked(mConstants.IDLE_AFTER_INACTIVE_TIMEOUT, false);
-                // Reset the upcoming idle delays.
-                mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
-                mNextIdleDelay = mConstants.IDLE_TIMEOUT;
                 mState = STATE_IDLE_PENDING;
                 if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_IDLE_PENDING.");
                 EventLogTags.writeDeviceIdle(mState, reason);
@@ -2245,18 +2602,19 @@
                 if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING.");
                 EventLogTags.writeDeviceIdle(mState, reason);
                 scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
-                if (mLocationManager != null
-                        && mLocationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
-                    mLocationManager.requestLocationUpdates(mLocationRequest,
+                LocationManager locationManager = mInjector.getLocationManager();
+                if (locationManager != null
+                        && locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
+                    locationManager.requestLocationUpdates(mLocationRequest,
                             mGenericLocationListener, mHandler.getLooper());
                     mLocating = true;
                 } else {
                     mHasNetworkLocation = false;
                 }
-                if (mLocationManager != null
-                        && mLocationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
+                if (locationManager != null
+                        && locationManager.getProvider(LocationManager.GPS_PROVIDER) != null) {
                     mHasGps = true;
-                    mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
+                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5,
                             mGpsLocationListener, mHandler.getLooper());
                     mLocating = true;
                 } else {
@@ -2274,6 +2632,13 @@
                 cancelLocatingLocked();
                 mAnyMotionDetector.stop();
 
+                // Intentional fallthrough -- time to go into IDLE state.
+            case STATE_QUICK_DOZE_DELAY:
+                // Reset the upcoming idle delays.
+                mNextIdlePendingDelay = mConstants.IDLE_PENDING_TIMEOUT;
+                mNextIdleDelay = mConstants.IDLE_TIMEOUT;
+
+                // Everything is in place to go into IDLE state.
             case STATE_IDLE_MAINTENANCE:
                 scheduleAlarmLocked(mNextIdleDelay, true);
                 if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
@@ -2331,6 +2696,14 @@
         }
     }
 
+    /** Must only be used in tests. */
+    @VisibleForTesting
+    void setActiveIdleOpsForTest(int count) {
+        synchronized (this) {
+            mActiveIdleOpCount = count;
+        }
+    }
+
     void setJobsActive(boolean active) {
         synchronized (this) {
             mJobsActive = active;
@@ -2504,8 +2877,9 @@
 
     void cancelLocatingLocked() {
         if (mLocating) {
-            mLocationManager.removeUpdates(mGenericLocationListener);
-            mLocationManager.removeUpdates(mGpsLocationListener);
+            LocationManager locationManager = mInjector.getLocationManager();
+            locationManager.removeUpdates(mGenericLocationListener);
+            locationManager.removeUpdates(mGpsLocationListener);
             mLocating = false;
         }
     }
@@ -2519,11 +2893,15 @@
 
     void scheduleAlarmLocked(long delay, boolean idleUntil) {
         if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
-        if (mMotionSensor == null) {
+        if (mMotionSensor == null && !(mState == STATE_QUICK_DOZE_DELAY || mState == STATE_IDLE
+                  || mState == STATE_IDLE_MAINTENANCE)) {
             // If there is no motion sensor on this device, then we won't schedule
             // alarms, because we can't determine if the device is not moving.  This effectively
             // turns off normal execution of device idling, although it is still possible to
             // manually poke it by pretending like the alarm is going off.
+            // STATE_QUICK_DOZE_DELAY skips the motion sensing so if the state is past the motion
+            // sensing stage (ie, is QUICK_DOZE_DELAY, IDLE, or IDLE_MAINTENANCE), then idling
+            // can continue until the user interacts with the device.
             return;
         }
         mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
@@ -2952,6 +3330,7 @@
                             case "light": pw.println(lightStateToString(mLightState)); break;
                             case "deep": pw.println(stateToString(mState)); break;
                             case "force": pw.println(mForceIdle); break;
+                            case "quick": pw.println(mQuickDozeActivated); break;
                             case "screen": pw.println(mScreenOn); break;
                             case "charging": pw.println(mCharging); break;
                             case "network": pw.println(mNetworkConnected); break;
diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java
index b7b5bd9..8077e34 100644
--- a/services/core/java/com/android/server/GestureLauncherService.java
+++ b/services/core/java/com/android/server/GestureLauncherService.java
@@ -356,6 +356,12 @@
 
     public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive,
             MutableBoolean outLaunched) {
+        if (event.isLongPress()) {
+            // Long presses are sent as a second key down. If the long press threshold is set lower
+            // than the double tap of sequence interval thresholds, this could cause false double
+            // taps or consecutive taps, so we want to ignore the long press event.
+            return false;
+        }
         boolean launched = false;
         boolean intercept = false;
         long powerTapInterval;
diff --git a/services/core/java/com/android/server/IpSecService.java b/services/core/java/com/android/server/IpSecService.java
index a69d416..8c25917 100644
--- a/services/core/java/com/android/server/IpSecService.java
+++ b/services/core/java/com/android/server/IpSecService.java
@@ -19,6 +19,8 @@
 import static android.Manifest.permission.DUMP;
 import static android.net.IpSecManager.INVALID_RESOURCE_ID;
 import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNSPEC;
 import static android.system.OsConstants.EINVAL;
 import static android.system.OsConstants.IPPROTO_UDP;
 import static android.system.OsConstants.SOCK_DGRAM;
@@ -63,6 +65,8 @@
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.PrintWriter;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
@@ -1426,6 +1430,17 @@
                         + "or Encryption algorithms");
     }
 
+    private int getFamily(String inetAddress) {
+        int family = AF_UNSPEC;
+        InetAddress checkAddress = NetworkUtils.numericToInetAddress(inetAddress);
+        if (checkAddress instanceof Inet4Address) {
+            family = AF_INET;
+        } else if (checkAddress instanceof Inet6Address) {
+            family = AF_INET6;
+        }
+        return family;
+    }
+
     /**
      * Checks an IpSecConfig parcel to ensure that the contents are sane and throws an
      * IllegalArgumentException if they are not.
@@ -1479,6 +1494,26 @@
         // Require a valid source address for all transforms.
         checkInetAddress(config.getSourceAddress());
 
+        // Check to ensure source and destination have the same address family.
+        String sourceAddress = config.getSourceAddress();
+        String destinationAddress = config.getDestinationAddress();
+        int sourceFamily = getFamily(sourceAddress);
+        int destinationFamily = getFamily(destinationAddress);
+        if (sourceFamily != destinationFamily) {
+            throw new IllegalArgumentException(
+                    "Source address ("
+                            + sourceAddress
+                            + ") and destination address ("
+                            + destinationAddress
+                            + ") have different address families.");
+        }
+
+        // Throw an error if UDP Encapsulation is not used in IPv4.
+        if (config.getEncapType() != IpSecTransform.ENCAP_NONE && sourceFamily != AF_INET) {
+            throw new IllegalArgumentException(
+                    "UDP Encapsulation is not supported for this address family");
+        }
+
         switch (config.getMode()) {
             case IpSecTransform.MODE_TRANSPORT:
                 break;
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 232c151..93bdcbb 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -76,6 +76,7 @@
 import android.util.EventLog;
 import android.util.Log;
 import android.util.Slog;
+
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.location.ProviderProperties;
 import com.android.internal.location.ProviderRequest;
@@ -99,6 +100,7 @@
 import com.android.server.location.LocationRequestStatistics.PackageStatistics;
 import com.android.server.location.MockProvider;
 import com.android.server.location.PassiveProvider;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -1764,9 +1766,7 @@
 
         if (enabled) {
             p.enable();
-            if (listeners > 0) {
-                applyRequirementsLocked(provider);
-            }
+            applyRequirementsLocked(provider);
         } else {
             p.disable();
         }
diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java
index 96ce6a4..2dee3a0 100644
--- a/services/core/java/com/android/server/LooperStatsService.java
+++ b/services/core/java/com/android/server/LooperStatsService.java
@@ -27,6 +27,7 @@
 import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.text.format.DateFormat;
 import android.util.KeyValueListParser;
 import android.util.Slog;
 
@@ -91,7 +92,9 @@
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
-        List<LooperStats.ExportedEntry> entries = mStats.getEntries();
+        pw.print("Start time: ");
+        pw.println(DateFormat.format("yyyy-MM-dd HH:mm:ss", mStats.getStartTimeMillis()));
+        final List<LooperStats.ExportedEntry> entries = mStats.getEntries();
         entries.sort(Comparator
                 .comparing((LooperStats.ExportedEntry entry) -> entry.workSourceUid)
                 .thenComparing(entry -> entry.threadName)
@@ -109,14 +112,28 @@
                 "max_latency_micros",
                 "total_cpu_micros",
                 "max_cpu_micros",
+                "recorded_delay_message_count",
+                "total_delay_millis",
+                "max_delay_millis",
                 "exception_count"));
         pw.println(header);
         for (LooperStats.ExportedEntry entry : entries) {
-            pw.printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n", entry.workSourceUid,
-                    entry.threadName, entry.handlerClassName, entry.messageName,
-                    entry.isInteractive, entry.messageCount, entry.recordedMessageCount,
-                    entry.totalLatencyMicros, entry.maxLatencyMicros, entry.cpuUsageMicros,
-                    entry.maxCpuUsageMicros, entry.exceptionCount);
+            pw.printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
+                    entry.workSourceUid,
+                    entry.threadName,
+                    entry.handlerClassName,
+                    entry.messageName,
+                    entry.isInteractive,
+                    entry.messageCount,
+                    entry.recordedMessageCount,
+                    entry.totalLatencyMicros,
+                    entry.maxLatencyMicros,
+                    entry.cpuUsageMicros,
+                    entry.maxCpuUsageMicros,
+                    entry.recordedDelayMessageCount,
+                    entry.delayMillis,
+                    entry.maxDelayMillis,
+                    entry.exceptionCount);
         }
     }
 
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index de930f7..f510d83 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -57,6 +57,7 @@
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.INetd;
+import android.net.TetherStatsParcel;
 import android.net.INetworkManagementEventObserver;
 import android.net.ITetheringStatsProvider;
 import android.net.InterfaceConfiguration;
@@ -169,19 +170,6 @@
      */
     public static final String LIMIT_GLOBAL_ALERT = "globalAlert";
 
-    /**
-     * String to pass to netd to indicate that a network is only accessible
-     * to apps that have the CHANGE_NETWORK_STATE permission.
-     */
-    public static final String PERMISSION_NETWORK = "NETWORK";
-
-    /**
-     * String to pass to netd to indicate that a network is only
-     * accessible to system apps and those with the CONNECTIVITY_INTERNAL
-     * permission.
-     */
-    public static final String PERMISSION_SYSTEM = "SYSTEM";
-
     static class NetdResponseCode {
         /* Keep in sync with system/netd/server/ResponseCode.h */
         public static final int InterfaceListResult       = 110;
@@ -222,6 +210,9 @@
 
     static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1;
 
+    static final boolean MODIFY_OPERATION_ADD = true;
+    static final boolean MODIFY_OPERATION_REMOVE = false;
+
     /**
      * Binder context for this service
      */
@@ -1121,41 +1112,47 @@
 
     @Override
     public void addRoute(int netId, RouteInfo route) {
-        modifyRoute("add", "" + netId, route);
+        modifyRoute(MODIFY_OPERATION_ADD, netId, route);
     }
 
     @Override
     public void removeRoute(int netId, RouteInfo route) {
-        modifyRoute("remove", "" + netId, route);
+        modifyRoute(MODIFY_OPERATION_REMOVE, netId, route);
     }
 
-    private void modifyRoute(String action, String netId, RouteInfo route) {
+    private void modifyRoute(boolean add, int netId, RouteInfo route) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        final Command cmd = new Command("network", "route", action, netId);
-
-        // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
-        cmd.appendArg(route.getInterface());
-        cmd.appendArg(route.getDestination().toString());
+        final String ifName = route.getInterface();
+        final String dst = route.getDestination().toString();
+        final String nextHop;
 
         switch (route.getType()) {
             case RouteInfo.RTN_UNICAST:
                 if (route.hasGateway()) {
-                    cmd.appendArg(route.getGateway().getHostAddress());
+                    nextHop = route.getGateway().getHostAddress();
+                } else {
+                    nextHop = INetd.NEXTHOP_NONE;
                 }
                 break;
             case RouteInfo.RTN_UNREACHABLE:
-                cmd.appendArg("unreachable");
+                nextHop = INetd.NEXTHOP_UNREACHABLE;
                 break;
             case RouteInfo.RTN_THROW:
-                cmd.appendArg("throw");
+                nextHop = INetd.NEXTHOP_THROW;
+                break;
+            default:
+                nextHop = INetd.NEXTHOP_NONE;
                 break;
         }
-
         try {
-            mConnector.execute(cmd);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            if (add) {
+                mNetdService.networkAddRoute(netId, ifName, dst, nextHop);
+            } else {
+                mNetdService.networkRemoveRoute(netId, ifName, dst, nextHop);
+            }
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -1844,31 +1841,30 @@
                 return new NetworkStats(SystemClock.elapsedRealtime(), 0);
             }
 
-            final PersistableBundle bundle;
+            final TetherStatsParcel[] tetherStatsVec;
             try {
-                bundle = mNetdService.tetherGetStats();
+                tetherStatsVec = mNetdService.tetherGetStats();
             } catch (RemoteException | ServiceSpecificException e) {
                 throw new IllegalStateException("problem parsing tethering stats: ", e);
             }
 
             final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(),
-                    bundle.size());
+                tetherStatsVec.length);
             final NetworkStats.Entry entry = new NetworkStats.Entry();
 
-            for (String iface : bundle.keySet()) {
-                long[] statsArray = bundle.getLongArray(iface);
+            for (TetherStatsParcel tetherStats : tetherStatsVec) {
                 try {
-                    entry.iface = iface;
+                    entry.iface = tetherStats.iface;
                     entry.uid = UID_TETHERING;
                     entry.set = SET_DEFAULT;
                     entry.tag = TAG_NONE;
-                    entry.rxBytes   = statsArray[INetd.TETHER_STATS_RX_BYTES];
-                    entry.rxPackets = statsArray[INetd.TETHER_STATS_RX_PACKETS];
-                    entry.txBytes   = statsArray[INetd.TETHER_STATS_TX_BYTES];
-                    entry.txPackets = statsArray[INetd.TETHER_STATS_TX_PACKETS];
+                    entry.rxBytes   = tetherStats.rxBytes;
+                    entry.rxPackets = tetherStats.rxPackets;
+                    entry.txBytes   = tetherStats.txBytes;
+                    entry.txPackets = tetherStats.txPackets;
                     stats.combineValues(entry);
                 } catch (ArrayIndexOutOfBoundsException e) {
-                    throw new IllegalStateException("invalid tethering stats for " + iface, e);
+                    throw new IllegalStateException("invalid tethering stats " + e);
                 }
             }
 
@@ -1916,44 +1912,21 @@
     @Override
     public void addVpnUidRanges(int netId, UidRange[] ranges) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
-        argv[0] = "users";
-        argv[1] = "add";
-        argv[2] = netId;
-        int argc = 3;
-        // Avoid overly long commands by limiting number of UID ranges per command.
-        for (int i = 0; i < ranges.length; i++) {
-            argv[argc++] = ranges[i].toString();
-            if (i == (ranges.length - 1) || argc == argv.length) {
-                try {
-                    mConnector.execute("network", Arrays.copyOf(argv, argc));
-                } catch (NativeDaemonConnectorException e) {
-                    throw e.rethrowAsParcelableException();
-                }
-                argc = 3;
-            }
+
+        try {
+            mNetdService.networkAddUidRanges(netId, ranges);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
     @Override
     public void removeVpnUidRanges(int netId, UidRange[] ranges) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
-        argv[0] = "users";
-        argv[1] = "remove";
-        argv[2] = netId;
-        int argc = 3;
-        // Avoid overly long commands by limiting number of UID ranges per command.
-        for (int i = 0; i < ranges.length; i++) {
-            argv[argc++] = ranges[i].toString();
-            if (i == (ranges.length - 1) || argc == argv.length) {
-                try {
-                    mConnector.execute("network", Arrays.copyOf(argv, argc));
-                } catch (NativeDaemonConnectorException e) {
-                    throw e.rethrowAsParcelableException();
-                }
-                argc = 3;
-            }
+        try {
+            mNetdService.networkRemoveUidRanges(netId, ranges);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2412,17 +2385,13 @@
     }
 
     @Override
-    public void createPhysicalNetwork(int netId, String permission) {
+    public void createPhysicalNetwork(int netId, int permission) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            if (permission != null) {
-                mConnector.execute("network", "create", netId, permission);
-            } else {
-                mConnector.execute("network", "create", netId);
-            }
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkCreatePhysical(netId, permission);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2431,10 +2400,9 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "create", netId, "vpn", hasDNS ? "1" : "0",
-                    secure ? "1" : "0");
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkCreateVpn(netId, hasDNS, secure);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2455,20 +2423,24 @@
 
     @Override
     public void addInterfaceToNetwork(String iface, int netId) {
-        modifyInterfaceInNetwork("add", "" + netId, iface);
+        modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface);
     }
 
     @Override
     public void removeInterfaceFromNetwork(String iface, int netId) {
-        modifyInterfaceInNetwork("remove", "" + netId, iface);
+        modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface);
     }
 
-    private void modifyInterfaceInNetwork(String action, String netId, String iface) {
+    private void modifyInterfaceInNetwork(boolean add, int netId, String iface) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
         try {
-            mConnector.execute("network", "interface", action, netId, iface);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            if (add) {
+                mNetdService.networkAddInterface(netId, iface);
+            } else {
+                mNetdService.networkRemoveInterface(netId, iface);
+            }
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2476,20 +2448,20 @@
     public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        final Command cmd = new Command("network", "route", "legacy", uid, "add", netId);
-
-        // create triplet: interface dest-ip-addr/prefixlength gateway-ip-addr
         final LinkAddress la = routeInfo.getDestinationLinkAddress();
-        cmd.appendArg(routeInfo.getInterface());
-        cmd.appendArg(la.getAddress().getHostAddress() + "/" + la.getPrefixLength());
-        if (routeInfo.hasGateway()) {
-            cmd.appendArg(routeInfo.getGateway().getHostAddress());
-        }
+        final String ifName = routeInfo.getInterface();
+        final String dst = la.toString();
+        final String nextHop;
 
+        if (routeInfo.hasGateway()) {
+            nextHop = routeInfo.getGateway().getHostAddress();
+        } else {
+            nextHop = "";
+        }
         try {
-            mConnector.execute(cmd);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2498,9 +2470,9 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "default", "set", netId);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkSetDefault(netId);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2509,49 +2481,41 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "default", "clear");
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkClearDefault();
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
     @Override
-    public void setNetworkPermission(int netId, String permission) {
+    public void setNetworkPermission(int netId, int permission) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            if (permission != null) {
-                mConnector.execute("network", "permission", "network", "set", permission, netId);
-            } else {
-                mConnector.execute("network", "permission", "network", "clear", netId);
-            }
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkSetPermissionForNetwork(netId, permission);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
+    private int parsePermission(String permission) {
+        if (permission.equals("NETWORK")) {
+            return INetd.PERMISSION_NETWORK;
+        }
+        if (permission.equals("SYSTEM")) {
+            return INetd.PERMISSION_SYSTEM;
+        }
+        return INetd.PERMISSION_NONE;
+    }
 
     @Override
     public void setPermission(String permission, int[] uids) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        Object[] argv = new Object[4 + MAX_UID_RANGES_PER_COMMAND];
-        argv[0] = "permission";
-        argv[1] = "user";
-        argv[2] = "set";
-        argv[3] = permission;
-        int argc = 4;
-        // Avoid overly long commands by limiting number of UIDs per command.
-        for (int i = 0; i < uids.length; ++i) {
-            argv[argc++] = uids[i];
-            if (i == uids.length - 1 || argc == argv.length) {
-                try {
-                    mConnector.execute("network", Arrays.copyOf(argv, argc));
-                } catch (NativeDaemonConnectorException e) {
-                    throw e.rethrowAsParcelableException();
-                }
-                argc = 4;
-            }
+        try {
+            mNetdService.networkSetPermissionForUser(parsePermission(permission), uids);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2559,22 +2523,10 @@
     public void clearPermission(int[] uids) {
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
-        Object[] argv = new Object[3 + MAX_UID_RANGES_PER_COMMAND];
-        argv[0] = "permission";
-        argv[1] = "user";
-        argv[2] = "clear";
-        int argc = 3;
-        // Avoid overly long commands by limiting number of UIDs per command.
-        for (int i = 0; i < uids.length; ++i) {
-            argv[argc++] = uids[i];
-            if (i == uids.length - 1 || argc == argv.length) {
-                try {
-                    mConnector.execute("network", Arrays.copyOf(argv, argc));
-                } catch (NativeDaemonConnectorException e) {
-                    throw e.rethrowAsParcelableException();
-                }
-                argc = 3;
-            }
+        try {
+            mNetdService.networkClearPermissionForUser(uids);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2583,9 +2535,9 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "protect", "allow", uid);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkSetProtectAllow(uid);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
@@ -2594,26 +2546,26 @@
         mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
         try {
-            mConnector.execute("network", "protect", "deny", uid);
-        } catch (NativeDaemonConnectorException e) {
-            throw e.rethrowAsParcelableException();
+            mNetdService.networkSetProtectDeny(uid);
+        } catch (RemoteException | ServiceSpecificException e) {
+            throw new IllegalStateException(e);
         }
     }
 
     @Override
     public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) {
-        modifyInterfaceInNetwork("add", "local", iface);
+        modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.NETID_LOCAL, iface);
 
         for (RouteInfo route : routes) {
             if (!route.isDefaultRoute()) {
-                modifyRoute("add", "local", route);
+                modifyRoute(MODIFY_OPERATION_ADD, INetd.NETID_LOCAL, route);
             }
         }
     }
 
     @Override
     public void removeInterfaceFromLocalNetwork(String iface) {
-        modifyInterfaceInNetwork("remove", "local", iface);
+        modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.NETID_LOCAL, iface);
     }
 
     @Override
@@ -2622,7 +2574,7 @@
 
         for (RouteInfo route : routes) {
             try {
-                modifyRoute("remove", "local", route);
+                modifyRoute(MODIFY_OPERATION_REMOVE, INetd.NETID_LOCAL, route);
             } catch (IllegalStateException e) {
                 failures++;
             }
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 0deaee7..526aebe 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -59,6 +59,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.function.pooled.PooledLambda;
 
+import com.android.server.wm.ActivityTaskManagerInternal;
 import dalvik.system.DexFile;
 import dalvik.system.VMRuntime;
 
@@ -103,6 +104,7 @@
     public @interface AppKey {}
 
     private final Context mContext;
+    private final ActivityTaskManagerInternal mAtmInternal;
     private final ActivityManagerInternal mAmInternal;
     private final IActivityManager mAm;
     private final UserManager mUserManager;
@@ -164,6 +166,7 @@
         }
         mPinnerHandler = new PinnerHandler(BackgroundThread.get().getLooper());
 
+        mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
         mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
         mAm = ActivityManager.getService();
 
@@ -380,7 +383,7 @@
     }
 
     private ApplicationInfo getHomeInfo(int userHandle) {
-        Intent intent = mAmInternal.getHomeIntent();
+        Intent intent = mAtmInternal.getHomeIntent();
         return getApplicationInfoForIntent(intent, userHandle, false);
     }
 
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 21f54dd..858dced 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -3150,10 +3150,10 @@
 
             if (toSystem) {
                 // Everything else goes into sandbox.
-                return device + "Android/sandbox/" + sandboxId.replace(':', '/') + "/" + devicePath;
+                return device + "Android/sandbox/" + sandboxId + "/" + devicePath;
             } else {
                 // Does path belong to this sandbox? If so, leave sandbox.
-                final String sandboxPrefix = "Android/sandbox/" + sandboxId.replace(':', '/') + "/";
+                final String sandboxPrefix = "Android/sandbox/" + sandboxId + "/";
                 if (devicePath.startsWith(sandboxPrefix)) {
                     return device + devicePath.substring(sandboxPrefix.length());
                 }
@@ -3754,7 +3754,7 @@
         }
 
         @Override
-        public void mountExternalStorageForApp(String packageName, int appId, String sharedUserId,
+        public void prepareSandboxForApp(String packageName, int appId, String sharedUserId,
                 int userId) {
             final String sandboxId;
             synchronized (mPackagesLock) {
@@ -3771,7 +3771,41 @@
             }
 
             try {
-                mVold.mountExternalStorageForApp(packageName, appId, sandboxId, userId);
+                mVold.prepareSandboxForApp(packageName, appId, sandboxId, userId);
+            } catch (Exception e) {
+                Slog.wtf(TAG, e);
+            }
+        }
+
+        @Override
+        public void destroySandboxForApp(String packageName, int userId) {
+            if (!ENABLE_ISOLATED_STORAGE) {
+                return;
+            }
+            final int appId;
+            final String sandboxId;
+            synchronized (mPackagesLock) {
+                final ArraySet<String> userPackages = getAvailablePackagesForUserPL(userId);
+                userPackages.remove(packageName);
+                appId = mAppIds.get(packageName);
+                sandboxId = mSandboxIds.get(appId);
+
+                // If the package is not uninstalled in any other users, remove appId and sandboxId
+                // corresponding to it from the internal state.
+                boolean installedInAnyUser = false;
+                for (int i = mPackages.size() - 1; i >= 0; --i) {
+                    if (mPackages.valueAt(i).contains(packageName)) {
+                        installedInAnyUser = true;
+                        break;
+                    }
+                }
+                if (!installedInAnyUser) {
+                    mAppIds.remove(packageName);
+                    mSandboxIds.remove(appId);
+                }
+            }
+            try {
+                mVold.destroySandboxForApp(packageName, appId, sandboxId, userId);
             } catch (Exception e) {
                 Slog.wtf(TAG, e);
             }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index fb8894b..65f3c03 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -49,6 +49,7 @@
 import android.telephony.TelephonyManager;
 import android.telephony.VoLteServiceState;
 import android.util.LocalLog;
+import android.util.StatsLog;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.IBatteryStats;
@@ -215,6 +216,9 @@
 
     private int mPreferredDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
+    @TelephonyManager.RadioPowerState
+    private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
+
     private final LocalLog mLocalLog = new LocalLog(100);
 
     private PreciseDataConnectionState mPreciseDataConnectionState =
@@ -761,6 +765,13 @@
                             remove(r.binder);
                         }
                     }
+                    if ((events & PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED) != 0) {
+                        try {
+                            r.callback.onRadioPowerStateChanged(mRadioPowerState);
+                        } catch (RemoteException ex) {
+                            remove(r.binder);
+                        }
+                    }
                 }
             }
         } else {
@@ -1608,6 +1619,32 @@
         }
     }
 
+    public void notifyRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) {
+        if (!checkNotifyPermission("notifyRadioPowerStateChanged()")) {
+            return;
+        }
+
+        if (VDBG) {
+            log("notifyRadioPowerStateChanged: state= " + state);
+        }
+
+        synchronized (mRecords) {
+            mRadioPowerState = state;
+
+            for (Record r : mRecords) {
+                if (r.matchPhoneStateListenerEvent(
+                        PhoneStateListener.LISTEN_RADIO_POWER_STATE_CHANGED)) {
+                    try {
+                        r.callback.onRadioPowerStateChanged(state);
+                    } catch (RemoteException ex) {
+                        mRemoveList.add(r.binder);
+                    }
+                }
+            }
+            handleRemoveListLocked();
+        }
+    }
+
     @Override
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
@@ -1645,6 +1682,7 @@
             pw.println("mVoLteServiceState=" + mVoLteServiceState);
             pw.println("mPhoneCapability=" + mPhoneCapability);
             pw.println("mPreferredDataSubId=" + mPreferredDataSubId);
+            pw.println("mRadioPowerState=" + mRadioPowerState);
 
             pw.decreaseIndent();
 
@@ -1719,8 +1757,12 @@
         try {
             if (state == TelephonyManager.CALL_STATE_IDLE) {
                 mBatteryStats.notePhoneOff();
+                StatsLog.write(StatsLog.PHONE_STATE_CHANGED,
+                        StatsLog.PHONE_STATE_CHANGED__STATE__OFF);
             } else {
                 mBatteryStats.notePhoneOn();
+                StatsLog.write(StatsLog.PHONE_STATE_CHANGED,
+                        StatsLog.PHONE_STATE_CHANGED__STATE__ON);
             }
         } catch (RemoteException e) {
             /* The remote entity disappeared, we can safely ignore the exception. */
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index b2be5e6..793a177 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -1270,26 +1270,36 @@
         public int onCommand(String cmd) {
             if ("vibrate".equals(cmd)) {
                 return runVibrate();
+            } else if ("prebaked".equals(cmd)) {
+                return runPrebaked();
             }
             return handleDefaultCommands(cmd);
         }
 
+        private boolean checkDoNotDisturb() {
+            try {
+                final int zenMode = Settings.Global.getInt(mContext.getContentResolver(),
+                        Settings.Global.ZEN_MODE);
+                if (zenMode != Settings.Global.ZEN_MODE_OFF) {
+                    try (PrintWriter pw = getOutPrintWriter();) {
+                        pw.print("Ignoring because device is on DND mode ");
+                        pw.println(DebugUtils.flagsToString(Settings.Global.class, "ZEN_MODE_",
+                                zenMode));
+                        return true;
+                    }
+                }
+            } catch (SettingNotFoundException e) {
+                // ignore
+            }
+
+            return false;
+        }
+
         private int runVibrate() {
             Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runVibrate");
             try {
-                try {
-                    final int zenMode = Settings.Global.getInt(mContext.getContentResolver(),
-                            Settings.Global.ZEN_MODE);
-                    if (zenMode != Settings.Global.ZEN_MODE_OFF) {
-                        try (PrintWriter pw = getOutPrintWriter();) {
-                            pw.print("Ignoring because device is on DND mode ");
-                            pw.println(DebugUtils.flagsToString(Settings.Global.class, "ZEN_MODE_",
-                                    zenMode));
-                            return 0;
-                        }
-                    }
-                } catch (SettingNotFoundException e) {
-                    // ignore
+                if (checkDoNotDisturb()) {
+                    return 0;
                 }
 
                 final long duration = Long.parseLong(getNextArgRequired());
@@ -1311,6 +1321,30 @@
             }
         }
 
+        private int runPrebaked() {
+            Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "runPrebaked");
+            try {
+                if (checkDoNotDisturb()) {
+                    return 0;
+                }
+
+                final int id = Integer.parseInt(getNextArgRequired());
+
+                String description = getNextArg();
+                if (description == null) {
+                    description = "Shell command";
+                }
+
+                VibrationEffect effect =
+                        VibrationEffect.get(id, false);
+                vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
+                        "Shell Command", mToken);
+                return 0;
+            } finally {
+                Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
+            }
+        }
+
         @Override
         public void onHelp() {
             try (PrintWriter pw = getOutPrintWriter();) {
@@ -1321,6 +1355,9 @@
                 pw.println("  vibrate duration [description]");
                 pw.println("    Vibrates for duration milliseconds; ignored when device is on DND ");
                 pw.println("    (Do Not Disturb) mode.");
+                pw.println("  prebaked effect-id [description]");
+                pw.println("    Vibrates with prebaked effect; ignored when device is on DND ");
+                pw.println("    (Do Not Disturb) mode.");
                 pw.println("");
             }
         }
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 0b836f0..9cc550d 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -528,7 +528,7 @@
             Thread dropboxThread = new Thread("watchdogWriteToDropbox") {
                     public void run() {
                         mActivity.addErrorToDropBox(
-                                "watchdog", null, "system_server", null, null,
+                                "watchdog", null, "system_server", null, null, null,
                                 subject, null, stack, null);
                     }
                 };
diff --git a/services/core/java/com/android/server/WiredAccessoryManager.java b/services/core/java/com/android/server/WiredAccessoryManager.java
index fcda83d..3939bee 100644
--- a/services/core/java/com/android/server/WiredAccessoryManager.java
+++ b/services/core/java/com/android/server/WiredAccessoryManager.java
@@ -339,7 +339,8 @@
                         Slog.w(TAG, uei.getSwitchStatePath() +
                                 " not found while attempting to determine initial switch state");
                     } catch (Exception e) {
-                        Slog.e(TAG, "" , e);
+                        Slog.e(TAG, "Error while attempting to determine initial switch state for "
+                                + uei.getDevName() , e);
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index a392b51..9c60b8c 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -6155,7 +6155,12 @@
 
             final int uid;
             try {
-                uid = mPackageManager.getPackageUidAsUser(packageName, userId);
+                long identityToken = clearCallingIdentity();
+                try {
+                    uid = mPackageManager.getPackageUidAsUser(packageName, userId);
+                } finally {
+                    restoreCallingIdentity(identityToken);
+                }
             } catch (NameNotFoundException e) {
                 Slog.e(TAG, "Unknown package " + packageName);
                 return;
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 461d39d..405a2d0 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -25,7 +25,6 @@
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Comparator;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
@@ -552,7 +551,7 @@
         if (!callerFg && !fgRequired && r.app == null
                 && mAm.mUserController.hasStartedUserState(r.userId)) {
             ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
-            if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
+            if (proc == null || proc.getCurProcState() > ActivityManager.PROCESS_STATE_RECEIVER) {
                 // If this is not coming from a foreground caller, then we may want
                 // to delay the start if there are already other background services
                 // that are starting.  This is to avoid process start spam when lots
@@ -580,7 +579,7 @@
                 }
                 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Not delaying: " + r);
                 addToStarting = true;
-            } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
+            } else if (proc.getCurProcState() >= ActivityManager.PROCESS_STATE_SERVICE) {
                 // We slightly loosen when we will enqueue this new service as a background
                 // starting service we are waiting for, to also include processes that are
                 // currently running other services or receivers.
@@ -589,7 +588,7 @@
                         "Not delaying, but counting as bg: " + r);
             } else if (DEBUG_DELAYED_STARTS) {
                 StringBuilder sb = new StringBuilder(128);
-                sb.append("Not potential delay (state=").append(proc.curProcState)
+                sb.append("Not potential delay (state=").append(proc.getCurProcState())
                         .append(' ').append(proc.adjType);
                 String reason = proc.makeAdjReason();
                 if (reason != null) {
@@ -1139,7 +1138,7 @@
             for (int j = smap.mActiveForegroundApps.size()-1; j >= 0; j--) {
                 ActiveForegroundApp active = smap.mActiveForegroundApps.valueAt(j);
                 if (active.mUid == uidRec.uid) {
-                    if (uidRec.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
+                    if (uidRec.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP) {
                         if (!active.mAppOnTop) {
                             active.mAppOnTop = true;
                             changed = true;
@@ -1258,7 +1257,7 @@
                                 active.mShownWhileScreenOn = mScreenOn;
                                 if (r.app != null) {
                                     active.mAppOnTop = active.mShownWhileTop =
-                                            r.app.uidRecord.curProcState
+                                            r.app.uidRecord.getCurProcState()
                                                     <= ActivityManager.PROCESS_STATE_TOP;
                                 }
                                 active.mStartTime = active.mStartVisibleTime
@@ -1442,8 +1441,8 @@
                 }
             }
         }
-        if (anyClientActivities != proc.hasClientActivities) {
-            proc.hasClientActivities = anyClientActivities;
+        if (anyClientActivities != proc.hasClientActivities()) {
+            proc.setHasClientActivities(anyClientActivities);
             if (updateLru) {
                 mAm.updateLruProcessLocked(proc, anyClientActivities, null);
             }
@@ -1466,9 +1465,9 @@
                     + ") when binding service " + service);
         }
 
-        ActivityRecord activity = null;
+        ActivityServiceConnectionsHolder<ConnectionRecord> activity = null;
         if (token != null) {
-            activity = ActivityRecord.isInStackLocked(token);
+            activity = mAm.mAtmInternal.getServiceConnectionsHolder(token);
             if (activity == null) {
                 Slog.w(TAG, "Binding with unknown activity: " + token);
                 return 0;
@@ -1623,8 +1622,9 @@
                 }
             }
 
-            mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState,
-                    s.appInfo.uid, s.appInfo.longVersionCode, s.name, s.processName);
+            mAm.startAssociationLocked(callerApp.uid, callerApp.processName,
+                    callerApp.getCurProcState(), s.appInfo.uid, s.appInfo.longVersionCode,
+                    s.name, s.processName);
             // Once the apps have become associated, if one of them is caller is ephemeral
             // the target app should now be able to see the calling app
             mAm.grantEphemeralAccessLocked(callerApp.userId, service,
@@ -1644,10 +1644,7 @@
             clist.add(c);
             b.connections.add(c);
             if (activity != null) {
-                if (activity.connections == null) {
-                    activity.connections = new HashSet<ConnectionRecord>();
-                }
-                activity.connections.add(c);
+                activity.addConnection(c);
             }
             b.client.connections.add(c);
             c.startAssociationIfNeeded();
@@ -1683,7 +1680,7 @@
                     s.app.whitelistManager = true;
                 }
                 // This could have made the service more important.
-                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
+                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities()
                         || s.app.treatLikeActivity, b.client);
                 mAm.updateOomAdjLocked(s.app, true);
             }
@@ -1797,7 +1794,7 @@
                     if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
                         r.binding.service.app.treatLikeActivity = true;
                         mAm.updateLruProcessLocked(r.binding.service.app,
-                                r.binding.service.app.hasClientActivities
+                                r.binding.service.app.hasClientActivities()
                                 || r.binding.service.app.treatLikeActivity, null);
                     }
                     mAm.updateOomAdjLocked(r.binding.service.app, false);
@@ -2861,8 +2858,8 @@
         smap.ensureNotStartingBackgroundLocked(r);
     }
 
-    void removeConnectionLocked(
-        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
+    void removeConnectionLocked(ConnectionRecord c, ProcessRecord skipApp,
+            ActivityServiceConnectionsHolder skipAct) {
         IBinder binder = c.conn.asBinder();
         AppBindRecord b = c.binding;
         ServiceRecord s = b.service;
@@ -2876,9 +2873,7 @@
         b.connections.remove(c);
         c.stopAssociation();
         if (c.activity != null && c.activity != skipAct) {
-            if (c.activity.connections != null) {
-                c.activity.connections.remove(c);
-            }
+            c.activity.removeConnection(c);
         }
         if (b.client != skipApp) {
             b.client.connections.remove(c);
@@ -3264,9 +3259,9 @@
         }
     }
 
-    void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
+    void cleanUpServices(int userId, ComponentName component, Intent baseIntent) {
         ArrayList<ServiceRecord> services = new ArrayList<>();
-        ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(tr.userId);
+        ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(userId);
         for (int i = alls.size() - 1; i >= 0; i--) {
             ServiceRecord sr = alls.valueAt(i);
             if (sr.packageName.equals(component.getPackageName())) {
@@ -3625,7 +3620,7 @@
                     nextTime = sr.executingStart;
                 }
             }
-            if (timeout != null && mAm.mLruProcesses.contains(proc)) {
+            if (timeout != null && mAm.mProcessList.mLruProcesses.contains(proc)) {
                 Slog.w(TAG, "Timeout executing service: " + timeout);
                 StringWriter sw = new StringWriter();
                 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
@@ -3646,7 +3641,7 @@
         }
 
         if (anrMessage != null) {
-            mAm.mAppErrors.appNotResponding(proc, null, null, false, anrMessage);
+            proc.appNotResponding(null, null, null, null, false, anrMessage);
         }
     }
 
@@ -3671,7 +3666,7 @@
         }
 
         if (app != null) {
-            mAm.mAppErrors.appNotResponding(app, null, null, false,
+            app.appNotResponding(null, null, null, null, false,
                     "Context.startForegroundService() did not then call Service.startForeground(): "
                         + r);
         }
diff --git a/services/core/java/com/android/server/am/ActiveUids.java b/services/core/java/com/android/server/am/ActiveUids.java
new file mode 100644
index 0000000..4e1435e
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActiveUids.java
@@ -0,0 +1,74 @@
+/*
+ * 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.am;
+
+import android.util.SparseArray;
+
+/** Class for tracking active uids for running processes. */
+final class ActiveUids {
+
+    private ActivityManagerService mService;
+
+    private boolean mPostChangesToAtm;
+    private final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
+
+    ActiveUids(ActivityManagerService service, boolean postChangesToAtm) {
+        mService = service;
+        mPostChangesToAtm = postChangesToAtm;
+    }
+
+    void put(int uid, UidRecord value) {
+        mActiveUids.put(uid, value);
+        if (mPostChangesToAtm) {
+            mService.mAtmInternal.onUidActive(uid, value.getCurProcState());
+        }
+    }
+
+    void remove(int uid) {
+        mActiveUids.remove(uid);
+        if (mPostChangesToAtm) {
+            mService.mAtmInternal.onUidInactive(uid);
+        }
+    }
+
+    void clear() {
+        mActiveUids.clear();
+        if (mPostChangesToAtm) {
+            mService.mAtmInternal.onActiveUidsCleared();
+        }
+    }
+
+    UidRecord get(int uid) {
+        return mActiveUids.get(uid);
+    }
+
+    int size() {
+        return mActiveUids.size();
+    }
+
+    UidRecord valueAt(int index) {
+        return mActiveUids.valueAt(index);
+    }
+
+    int keyAt(int index) {
+        return mActiveUids.keyAt(index);
+    }
+
+    int indexOfKey(int uid) {
+        return mActiveUids.indexOfKey(uid);
+    }
+}
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index fab967c..ede13ef 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -37,20 +37,22 @@
 import static com.android.server.am.ActivityDisplayProto.ID;
 import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY;
 import static com.android.server.am.ActivityDisplayProto.STACKS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
-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.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
 import static com.android.server.am.ActivityStackSupervisor.TAG_STATES;
 import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STATES;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.annotation.Nullable;
 import android.app.ActivityOptions;
 import android.app.WindowConfiguration;
 import android.graphics.Point;
+import android.os.UserHandle;
 import android.util.IntArray;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
@@ -71,7 +73,7 @@
  */
 class ActivityDisplay extends ConfigurationContainer<ActivityStack>
         implements WindowContainerListener {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityDisplay" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityDisplay" : TAG_ATM;
     private static final String TAG_STACK = TAG + POSTFIX_STACK;
 
     static final int POSITION_TOP = Integer.MAX_VALUE;
@@ -112,6 +114,20 @@
      */
     private boolean mRemoved;
 
+    /**
+     * A focusable stack that is purposely to be positioned at the top. Although the stack may not
+     * have the topmost index, it is used as a preferred candidate to prevent being unable to resume
+     * target stack properly when there are other focusable always-on-top stacks.
+     */
+    private ActivityStack mPreferredTopFocusableStack;
+
+    /**
+     * If this is the same as {@link #getFocusedStack} then the activity on the top of the focused
+     * stack has been resumed. If stacks are changing position this will hold the old stack until
+     * the new stack becomes resumed after which it will be set to current focused stack.
+     */
+    private ActivityStack mLastFocusedStack;
+
     // Cached reference to some special stacks we tend to get a lot so we don't need to loop
     // through the list to find them.
     private ActivityStack mHomeStack = null;
@@ -164,6 +180,9 @@
         if (DEBUG_STACK) Slog.v(TAG_STACK, "removeChild: detaching " + stack
                 + " from displayId=" + mDisplayId);
         mStacks.remove(stack);
+        if (mPreferredTopFocusableStack == stack) {
+            mPreferredTopFocusableStack = null;
+        }
         removeStackReferenceIfNeeded(stack);
         releaseSelfIfNeeded();
         mSupervisor.mService.updateSleepIfNeededLocked();
@@ -171,23 +190,59 @@
     }
 
     void positionChildAtTop(ActivityStack stack, boolean includingParents) {
-        positionChildAt(stack, mStacks.size(), includingParents);
+        positionChildAtTop(stack, includingParents, null /* updateLastFocusedStackReason */);
+    }
+
+    void positionChildAtTop(ActivityStack stack, boolean includingParents,
+            String updateLastFocusedStackReason) {
+        positionChildAt(stack, mStacks.size(), includingParents, updateLastFocusedStackReason);
     }
 
     void positionChildAtBottom(ActivityStack stack) {
-        positionChildAt(stack, 0, false /* includingParents */);
+        positionChildAtBottom(stack, null /* updateLastFocusedStackReason */);
+    }
+
+    void positionChildAtBottom(ActivityStack stack, String updateLastFocusedStackReason) {
+        positionChildAt(stack, 0, false /* includingParents */, updateLastFocusedStackReason);
     }
 
     private void positionChildAt(ActivityStack stack, int position) {
-        positionChildAt(stack, position, false /* includingParents */);
+        positionChildAt(stack, position, false /* includingParents */,
+                null /* updateLastFocusedStackReason */);
     }
 
-    private void positionChildAt(ActivityStack stack, int position, boolean includingParents) {
+    private void positionChildAt(ActivityStack stack, int position, boolean includingParents,
+            String updateLastFocusedStackReason) {
         // TODO: Keep in sync with WindowContainer.positionChildAt(), once we change that to adjust
         //       the position internally, also update the logic here
-        mStacks.remove(stack);
+        final ActivityStack prevFocusedStack = updateLastFocusedStackReason != null
+                ? getFocusedStack() : null;
+        final boolean wasContained = mStacks.remove(stack);
         final int insertPosition = getTopInsertPosition(stack, position);
         mStacks.add(insertPosition, stack);
+
+        // The insert position may be adjusted to non-top when there is always-on-top stack. Since
+        // the original position is preferred to be top, the stack should have higher priority when
+        // we are looking for top focusable stack. The condition {@code wasContained} restricts the
+        // preferred stack is set only when moving an existing stack to top instead of adding a new
+        // stack that may be too early (e.g. in the middle of launching or reparenting).
+        if (wasContained && position >= mStacks.size() - 1 && stack.isFocusableAndVisible()) {
+            mPreferredTopFocusableStack = stack;
+        } else if (mPreferredTopFocusableStack == stack) {
+            mPreferredTopFocusableStack = null;
+        }
+
+        if (updateLastFocusedStackReason != null) {
+            final ActivityStack currentFocusedStack = getFocusedStack();
+            if (currentFocusedStack != prevFocusedStack) {
+                mLastFocusedStack = prevFocusedStack;
+                EventLogTags.writeAmFocusedStack(mSupervisor.mCurrentUser, mDisplayId,
+                        currentFocusedStack == null ? -1 : currentFocusedStack.getStackId(),
+                        mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(),
+                        updateLastFocusedStackReason);
+            }
+        }
+
         // Since positionChildAt() is called during the creation process of pinned stacks,
         // ActivityStack#getWindowContainerController() can be null. In this special case,
         // since DisplayContest#positionStackAt() is called in TaskStack#onConfigurationChanged(),
@@ -356,10 +411,18 @@
                         this, stackId, mSupervisor, windowingMode, activityType, onTop);
     }
 
+    /**
+     * Get the preferred focusable stack in priority. If the preferred stack does not exist, find a
+     * focusable and visible stack from the top of stacks in this display.
+     */
     ActivityStack getFocusedStack() {
+        if (mPreferredTopFocusableStack != null) {
+            return mPreferredTopFocusableStack;
+        }
+
         for (int i = mStacks.size() - 1; i >= 0; --i) {
             final ActivityStack stack = mStacks.get(i);
-            if (stack.isFocusable() && stack.shouldBeVisible(null /* starting */)) {
+            if (stack.isFocusableAndVisible()) {
                 return stack;
             }
         }
@@ -381,7 +444,7 @@
             if (ignoreCurrent && stack == currentFocus) {
                 continue;
             }
-            if (!stack.isFocusable() || !stack.shouldBeVisible(null)) {
+            if (!stack.isFocusableAndVisible()) {
                 continue;
             }
 
@@ -427,6 +490,26 @@
         return resumedActivity;
     }
 
+    ActivityStack getLastFocusedStack() {
+        return mLastFocusedStack;
+    }
+
+    boolean allResumedActivitiesComplete() {
+        for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+            final ActivityRecord r = mStacks.get(stackNdx).getResumedActivity();
+            if (r != null && !r.isState(RESUMED)) {
+                return false;
+            }
+        }
+        final ActivityStack currentFocusedStack = getFocusedStack();
+        if (DEBUG_STACK) {
+            Slog.d(TAG_STACK, "allResumedActivitiesComplete: mLastFocusedStack changing from="
+                    + mLastFocusedStack + " to=" + currentFocusedStack);
+        }
+        mLastFocusedStack = currentFocusedStack;
+        return true;
+    }
+
     /**
      * Pause all activities in either all of the stacks or just the back stacks.
      * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving().
@@ -790,6 +873,52 @@
         return null;
     }
 
+    ActivityRecord topRunningActivity() {
+        return topRunningActivity(false /* considerKeyguardState */);
+    }
+
+    /**
+     * Returns the top running activity in the focused stack. In the case the focused stack has no
+     * such activity, the next focusable stack on this display is returned.
+     *
+     * @param considerKeyguardState Indicates whether the locked state should be considered. if
+     *                              {@code true} and the keyguard is locked, only activities that
+     *                              can be shown on top of the keyguard will be considered.
+     * @return The top running activity. {@code null} if none is available.
+     */
+    ActivityRecord topRunningActivity(boolean considerKeyguardState) {
+        ActivityRecord topRunning = null;
+        final ActivityStack focusedStack = getFocusedStack();
+        if (focusedStack != null) {
+            topRunning = focusedStack.topRunningActivityLocked();
+        }
+
+        // Look in other focusable stacks.
+        if (topRunning == null) {
+            for (int i = mStacks.size() - 1; i >= 0; --i) {
+                final ActivityStack stack = mStacks.get(i);
+                // Only consider focusable stacks other than the current focused one.
+                if (stack == focusedStack || !stack.isFocusable()) {
+                    continue;
+                }
+                topRunning = stack.topRunningActivityLocked();
+                if (topRunning != null) {
+                    break;
+                }
+            }
+        }
+
+        // This activity can be considered the top running activity if we are not considering
+        // the locked state, the keyguard isn't locked, or we can show when locked.
+        if (topRunning != null && considerKeyguardState
+                && mSupervisor.getKeyguardController().isKeyguardLocked()
+                && !topRunning.canShowWhenLocked()) {
+            return null;
+        }
+
+        return topRunning;
+    }
+
     int getIndexOf(ActivityStack stack) {
         return mStacks.indexOf(stack);
     }
@@ -911,6 +1040,16 @@
         return mDisplayAccessUIDs;
     }
 
+    /**
+     * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
+     */
+    boolean supportsSystemDecorations() {
+        return mDisplay.supportsSystemDecorations()
+                // TODO (b/111363427): Remove this and set the new FLAG_SHOULD_SHOW_LAUNCHER flag
+                // (b/114338689) whenever vr 2d display id is set.
+                || mDisplayId == mSupervisor.mService.mVr2dDisplayId;
+    }
+
     private boolean shouldDestroyContentOnRemove() {
         return mDisplay.getRemoveMode() == REMOVE_MODE_DESTROY_CONTENT;
     }
@@ -920,6 +1059,10 @@
                 && (mSupervisor.mService.mRunningVoice == null);
     }
 
+    void setFocusedApp(ActivityRecord r, boolean moveFocusNow) {
+        mWindowContainerController.setFocusedApp(r.appToken, moveFocusNow);
+    }
+
     /**
      * @return the stack currently above the {@param stack}.  Can be null if the {@param stack} is
      *         already top-most.
@@ -981,6 +1124,57 @@
         positionChildAt(stack, Math.max(0, insertIndex));
     }
 
+    void moveHomeStackToFront(String reason) {
+        if (mHomeStack != null) {
+            mHomeStack.moveToFront(reason);
+        }
+    }
+
+    /** Returns true if the focus activity was adjusted to the home stack top activity. */
+    boolean moveHomeActivityToTop(String reason) {
+        final ActivityRecord top = getHomeActivity();
+        if (top == null) {
+            return false;
+        }
+        top.moveFocusableActivityToTop(reason);
+        return true;
+    }
+
+    @Nullable
+    ActivityStack getHomeStack() {
+        return mHomeStack;
+    }
+
+    @Nullable
+    ActivityRecord getHomeActivity() {
+        return getHomeActivityForUser(mSupervisor.mCurrentUser);
+    }
+
+    @Nullable
+    ActivityRecord getHomeActivityForUser(int userId) {
+        if (mHomeStack == null) {
+            return null;
+        }
+
+        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
+        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
+            final TaskRecord task = tasks.get(taskNdx);
+            if (!task.isActivityTypeHome()) {
+                continue;
+            }
+
+            final ArrayList<ActivityRecord> activities = task.mActivities;
+            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
+                final ActivityRecord r = activities.get(activityNdx);
+                if (r.isActivityTypeHome()
+                        && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
+                    return r;
+                }
+            }
+        }
+        return null;
+    }
+
     boolean isSleeping() {
         return mSleeping;
     }
@@ -1042,6 +1236,12 @@
         if (mSplitScreenPrimaryStack != null) {
             pw.println(myPrefix + "mSplitScreenPrimaryStack=" + mSplitScreenPrimaryStack);
         }
+        if (mPreferredTopFocusableStack != null) {
+            pw.println(myPrefix + "mPreferredTopFocusableStack=" + mPreferredTopFocusableStack);
+        }
+        if (mLastFocusedStack != null) {
+            pw.println(myPrefix + "mLastFocusedStack=" + mLastFocusedStack);
+        }
     }
 
     public void dumpStacks(PrintWriter pw) {
diff --git a/services/core/java/com/android/server/am/ActivityLaunchParamsModifier.java b/services/core/java/com/android/server/am/ActivityLaunchParamsModifier.java
deleted file mode 100644
index f44ee7a..0000000
--- a/services/core/java/com/android/server/am/ActivityLaunchParamsModifier.java
+++ /dev/null
@@ -1,65 +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.am;
-
-import android.app.ActivityOptions;
-import android.content.pm.ActivityInfo;
-import android.graphics.Rect;
-
-import com.android.server.am.LaunchParamsController.LaunchParams;
-import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
-
-/**
- * An implementation of {@link LaunchParamsModifier}, which applies the launch bounds specified
- * inside {@link ActivityOptions#getLaunchBounds()}.
- */
-public class ActivityLaunchParamsModifier implements LaunchParamsModifier {
-    private final ActivityStackSupervisor mSupervisor;
-
-    ActivityLaunchParamsModifier(ActivityStackSupervisor activityStackSupervisor) {
-        mSupervisor = activityStackSupervisor;
-    }
-
-    @Override
-    public int onCalculate(TaskRecord task, ActivityInfo.WindowLayout layout,
-            ActivityRecord activity, ActivityRecord source, ActivityOptions options,
-            LaunchParams currentParams, LaunchParams outParams) {
-        // We only care about figuring out bounds for activities.
-        if (activity == null) {
-            return RESULT_SKIP;
-        }
-
-        // Activity must be resizeable in the specified task.
-        if (!(mSupervisor.canUseActivityOptionsLaunchBounds(options)
-                && (activity.isResizeable() || (task != null && task.isResizeable())))) {
-            return RESULT_SKIP;
-        }
-
-        final Rect bounds = options.getLaunchBounds();
-
-        // Bounds weren't valid.
-        if (bounds == null || bounds.isEmpty()) {
-            return RESULT_SKIP;
-        }
-
-        outParams.mBounds.set(bounds);
-
-        // When this is the most explicit position specification so we should not allow further
-        // modification of the position.
-        return RESULT_DONE;
-    }
-}
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 3a0289c..5c77f0a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -220,7 +220,7 @@
 
     // Indicates whether the activity starts logging is enabled.
     // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
-    boolean mFlagActivityStartsLoggingEnabled;
+    volatile boolean mFlagActivityStartsLoggingEnabled;
 
     private final ActivityManagerService mService;
     private ContentResolver mResolver;
diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
index 0e63d0c..0aaea2f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
+++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java
@@ -41,97 +41,48 @@
     // Enable all debug log categories.
     static final boolean DEBUG_ALL = false;
 
-    // Enable all debug log categories for activities.
-    static final boolean DEBUG_ALL_ACTIVITIES = DEBUG_ALL || false;
-
     // Available log categories in the activity manager package.
-    static final boolean DEBUG_ADD_REMOVE = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_ANR = true;  // STOPSHIP disable it (b/113252928)
-    static final boolean DEBUG_APP = DEBUG_ALL_ACTIVITIES || 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;
     static final boolean DEBUG_BROADCAST_BACKGROUND = DEBUG_BROADCAST || false;
     static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
-    static final boolean DEBUG_CLEANUP = DEBUG_ALL || false;
-    static final boolean DEBUG_CONFIGURATION = DEBUG_ALL || false;
-    static final boolean DEBUG_CONTAINERS = DEBUG_ALL_ACTIVITIES || false;
-    static final boolean DEBUG_FOCUS = false;
-    static final boolean DEBUG_IDLE = DEBUG_ALL_ACTIVITIES || false;
-    static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
-    static final boolean DEBUG_LOCKTASK = DEBUG_ALL || false;
     static final boolean DEBUG_LRU = DEBUG_ALL || false;
     static final boolean DEBUG_MU = DEBUG_ALL || false;
     static final boolean DEBUG_NETWORK = DEBUG_ALL || false;
     static final boolean DEBUG_OOM_ADJ = DEBUG_ALL || false;
     static final boolean DEBUG_OOM_ADJ_REASON = DEBUG_ALL || false;
-    static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
     static final boolean DEBUG_POWER = DEBUG_ALL || false;
     static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
     static final boolean DEBUG_PROCESS_OBSERVERS = DEBUG_ALL || false;
     static final boolean DEBUG_PROCESSES = DEBUG_ALL || false;
     static final boolean DEBUG_PROVIDER = DEBUG_ALL || false;
     static final boolean DEBUG_PSS = DEBUG_ALL || false;
-    static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
-    static final boolean DEBUG_RECENTS_TRIM_TASKS = DEBUG_RECENTS || false;
-    static final boolean DEBUG_RELEASE = DEBUG_ALL_ACTIVITIES || false;
-    static final boolean DEBUG_RESULTS = DEBUG_ALL || false;
-    static final boolean DEBUG_SAVED_STATE = DEBUG_ALL_ACTIVITIES || false;
     static final boolean DEBUG_SERVICE = DEBUG_ALL || false;
     static final boolean DEBUG_FOREGROUND_SERVICE = DEBUG_ALL || false;
     static final boolean DEBUG_SERVICE_EXECUTING = DEBUG_ALL || false;
-    static final boolean DEBUG_STACK = DEBUG_ALL || false;
-    static final boolean DEBUG_STATES = DEBUG_ALL_ACTIVITIES || false;
-    static final boolean DEBUG_SWITCH = DEBUG_ALL || false;
-    static final boolean DEBUG_TASKS = DEBUG_ALL || false;
-    static final boolean DEBUG_TRANSITION = DEBUG_ALL || false;
     static final boolean DEBUG_UID_OBSERVERS = DEBUG_ALL || false;
-    static final boolean DEBUG_URI_PERMISSION = DEBUG_ALL || false;
-    static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false;
-    static final boolean DEBUG_VISIBILITY = DEBUG_ALL || false;
     static final boolean DEBUG_USAGE_STATS = DEBUG_ALL || false;
     static final boolean DEBUG_PERMISSIONS_REVIEW = DEBUG_ALL || false;
     static final boolean DEBUG_WHITELISTS = DEBUG_ALL || false;
-    static final boolean DEBUG_METRICS = DEBUG_ALL || false;
 
-    static final String POSTFIX_ADD_REMOVE = (APPEND_CATEGORY_NAME) ? "_AddRemove" : "";
-    static final String POSTFIX_APP = (APPEND_CATEGORY_NAME) ? "_App" : "";
     static final String POSTFIX_BACKUP = (APPEND_CATEGORY_NAME) ? "_Backup" : "";
     static final String POSTFIX_BROADCAST = (APPEND_CATEGORY_NAME) ? "_Broadcast" : "";
     static final String POSTFIX_CLEANUP = (APPEND_CATEGORY_NAME) ? "_Cleanup" : "";
-    static final String POSTFIX_CONFIGURATION = (APPEND_CATEGORY_NAME) ? "_Configuration" : "";
-    static final String POSTFIX_CONTAINERS = (APPEND_CATEGORY_NAME) ? "_Containers" : "";
-    static final String POSTFIX_FOCUS = (APPEND_CATEGORY_NAME) ? "_Focus" : "";
-    static final String POSTFIX_IDLE = (APPEND_CATEGORY_NAME) ? "_Idle" : "";
-    static final String POSTFIX_IMMERSIVE = (APPEND_CATEGORY_NAME) ? "_Immersive" : "";
-    static final String POSTFIX_LOCKTASK = (APPEND_CATEGORY_NAME) ? "_LockTask" : "";
     static final String POSTFIX_LRU = (APPEND_CATEGORY_NAME) ? "_LRU" : "";
     static final String POSTFIX_MU = "_MU";
     static final String POSTFIX_NETWORK = "_Network";
     static final String POSTFIX_OOM_ADJ = (APPEND_CATEGORY_NAME) ? "_OomAdj" : "";
-    static final String POSTFIX_PAUSE = (APPEND_CATEGORY_NAME) ? "_Pause" : "";
     static final String POSTFIX_POWER = (APPEND_CATEGORY_NAME) ? "_Power" : "";
     static final String POSTFIX_PROCESS_OBSERVERS = (APPEND_CATEGORY_NAME)
             ? "_ProcessObservers" : "";
     static final String POSTFIX_PROCESSES = (APPEND_CATEGORY_NAME) ? "_Processes" : "";
     static final String POSTFIX_PROVIDER = (APPEND_CATEGORY_NAME) ? "_Provider" : "";
     static final String POSTFIX_PSS = (APPEND_CATEGORY_NAME) ? "_Pss" : "";
-    static final String POSTFIX_RECENTS = (APPEND_CATEGORY_NAME) ? "_Recents" : "";
-    static final String POSTFIX_RELEASE = (APPEND_CATEGORY_NAME) ? "_Release" : "";
-    static final String POSTFIX_RESULTS = (APPEND_CATEGORY_NAME) ? "_Results" : "";
-    static final String POSTFIX_SAVED_STATE = (APPEND_CATEGORY_NAME) ? "_SavedState" : "";
     static final String POSTFIX_SERVICE = (APPEND_CATEGORY_NAME) ? "_Service" : "";
     static final String POSTFIX_SERVICE_EXECUTING =
             (APPEND_CATEGORY_NAME) ? "_ServiceExecuting" : "";
-    static final String POSTFIX_STACK = (APPEND_CATEGORY_NAME) ? "_Stack" : "";
-    static final String POSTFIX_STATES = (APPEND_CATEGORY_NAME) ? "_States" : "";
-    static final String POSTFIX_SWITCH = (APPEND_CATEGORY_NAME) ? "_Switch" : "";
-    static final String POSTFIX_TASKS = (APPEND_CATEGORY_NAME) ? "_Tasks" : "";
-    static final String POSTFIX_TRANSITION = (APPEND_CATEGORY_NAME) ? "_Transition" : "";
     static final String POSTFIX_UID_OBSERVERS = (APPEND_CATEGORY_NAME)
             ? "_UidObservers" : "";
-    static final String POSTFIX_URI_PERMISSION = (APPEND_CATEGORY_NAME) ? "_UriPermission" : "";
-    static final String POSTFIX_USER_LEAVING = (APPEND_CATEGORY_NAME) ? "_UserLeaving" : "";
-    static final String POSTFIX_VISIBILITY = (APPEND_CATEGORY_NAME) ? "_Visibility" : "";
-
 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index aa14da0..1b74ed0 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18,19 +18,19 @@
 
 import static android.Manifest.permission.CHANGE_CONFIGURATION;
 import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
+import static android.Manifest.permission.FILTER_EVENTS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
-import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.REMOVE_TASKS;
+import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS;
+import static android.app.ActivityManager.INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL;
 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
 import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
 import static android.app.ActivityManagerInternal.ALLOW_NON_FULL;
-import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
 import static android.app.AppOpsManager.OP_NONE;
-import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
 import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
 import static android.content.pm.PackageManager.GET_PROVIDERS;
 import static android.content.pm.PackageManager.MATCH_ANY_USER;
@@ -42,14 +42,13 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
+import static android.os.FactoryTest.FACTORY_TEST_OFF;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
 import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
 import static android.os.IServiceManager.DUMP_FLAG_PROTO;
 import static android.os.Process.BLUETOOTH_UID;
 import static android.os.Process.FIRST_APPLICATION_UID;
-import static android.os.Process.FIRST_ISOLATED_UID;
-import static android.os.Process.LAST_ISOLATED_UID;
 import static android.os.Process.NFC_UID;
 import static android.os.Process.PHONE_UID;
 import static android.os.Process.PROC_CHAR;
@@ -68,10 +67,10 @@
 import static android.os.Process.THREAD_GROUP_DEFAULT;
 import static android.os.Process.THREAD_GROUP_RESTRICTED;
 import static android.os.Process.THREAD_GROUP_TOP_APP;
-import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
-import static android.os.Process.getFreeMemory;
+import static android.os.Process.getPidsForCommands;
 import static android.os.Process.getTotalMemory;
+import static android.os.Process.getUidForPid;
 import static android.os.Process.isThreadInProcess;
 import static android.os.Process.killProcess;
 import static android.os.Process.killProcessQuiet;
@@ -83,7 +82,6 @@
 import static android.os.Process.setProcessGroup;
 import static android.os.Process.setThreadPriority;
 import static android.os.Process.setThreadScheduler;
-import static android.os.Process.startWebView;
 import static android.os.Process.zygoteProcess;
 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
 import static android.provider.Settings.Global.DEBUG_APP;
@@ -98,9 +96,6 @@
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
@@ -113,15 +108,12 @@
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
@@ -132,13 +124,32 @@
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
 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.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityTaskManagerService.DUMP_ACTIVITIES_CMD;
+import static com.android.server.am.ActivityTaskManagerService.DUMP_ACTIVITIES_SHORT_CMD;
+import static com.android.server.am.ActivityTaskManagerService.DUMP_CONTAINERS_CMD;
+import static com.android.server.am.ActivityTaskManagerService.DUMP_LASTANR_CMD;
+import static com.android.server.am.ActivityTaskManagerService.DUMP_LASTANR_TRACES_CMD;
+import static com.android.server.am.ActivityTaskManagerService.DUMP_RECENTS_CMD;
+import static com.android.server.am.ActivityTaskManagerService.DUMP_RECENTS_SHORT_CMD;
+import static com.android.server.am.ActivityTaskManagerService.DUMP_STARTER_CMD;
+import static com.android.server.am.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
+import static com.android.server.am.ActivityTaskManagerService.relaunchReasonToString;
+import static com.android.server.am.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES;
 import static com.android.server.am.MemoryStatUtil.hasMemcg;
+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 android.Manifest;
 import android.Manifest.permission;
@@ -151,7 +162,6 @@
 import android.app.ActivityManager.StackInfo;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerProto;
-import android.app.ActivityOptions;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
 import android.app.AppOpsManager;
@@ -180,6 +190,7 @@
 import android.app.PendingIntent;
 import android.app.ProcessMemoryState;
 import android.app.ProfilerInfo;
+import android.app.WaitResult;
 import android.app.WindowConfiguration.ActivityType;
 import android.app.WindowConfiguration.WindowingMode;
 import android.app.backup.IBackupManager;
@@ -200,7 +211,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy;
-import android.content.pm.ConfigurationInfo;
 import android.content.pm.IPackageDataObserver;
 import android.content.pm.IPackageManager;
 import android.content.pm.InstrumentationInfo;
@@ -250,7 +260,6 @@
 import android.os.PowerManager.ServiceType;
 import android.os.PowerManagerInternal;
 import android.os.Process;
-import android.os.Process.ProcessStartResult;
 import android.os.RemoteCallback;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -265,9 +274,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.WorkSource;
-import android.os.storage.IStorageManager;
 import android.os.storage.StorageManager;
-import android.os.storage.StorageManagerInternal;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
@@ -277,7 +284,6 @@
 import android.util.DebugUtils;
 import android.util.EventLog;
 import android.util.Log;
-import android.util.LongSparseArray;
 import android.util.Pair;
 import android.util.PrintWriterPrinter;
 import android.util.Slog;
@@ -313,7 +319,6 @@
 import com.android.internal.os.IResultReceiver;
 import com.android.internal.os.ProcessCpuTracker;
 import com.android.internal.os.TransferPipe;
-import com.android.internal.os.Zygote;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.DumpUtils;
@@ -339,13 +344,11 @@
 import com.android.server.ThreadPriorityBooster;
 import com.android.server.Watchdog;
 import com.android.server.am.ActivityManagerServiceDumpProcessesProto.UidObserverRegistrationProto;
-import com.android.server.am.ActivityStack.ActivityState;
 import com.android.server.am.MemoryStatUtil.MemoryStat;
 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.dex.DexManager;
 import com.android.server.uri.GrantUri;
 import com.android.server.uri.UriGrantsManagerInternal;
 import com.android.server.utils.PriorityDump;
@@ -357,18 +360,15 @@
 
 import libcore.util.EmptyArray;
 
-import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
-import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -397,24 +397,24 @@
      */
     public static final int TOP_APP_PRIORITY_BOOST = -10;
 
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
+    static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
-    private static final String TAG_LRU = TAG + POSTFIX_LRU;
+    static final String TAG_LRU = TAG + POSTFIX_LRU;
     private static final String TAG_MU = TAG + POSTFIX_MU;
     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
     private static final String TAG_POWER = TAG + POSTFIX_POWER;
     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
-    private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
+    static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
-    private static final String TAG_PSS = TAG + POSTFIX_PSS;
+    static final String TAG_PSS = TAG + POSTFIX_PSS;
     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
-    private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
+    static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
 
     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
     // here so that while the job scheduler can depend on AMS, the other way around
@@ -432,11 +432,11 @@
     static final boolean MONITOR_THREAD_CPU_USAGE = false;
 
     // The flags that are set for all calls we make to the package manager.
-    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
+    public static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
 
     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
 
-    private static final String ANR_TRACE_DIR = "/data/anr";
+    public static final String ANR_TRACE_DIR = "/data/anr";
 
     // Maximum number of receivers an app can register.
     private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
@@ -448,6 +448,12 @@
     // before we decide it must be hung.
     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
 
+    /**
+     * How long we wait for an provider to be published. Should be longer than
+     * {@link #CONTENT_PROVIDER_PUBLISH_TIMEOUT}.
+     */
+    static final int CONTENT_PROVIDER_WAIT_TIMEOUT = 20 * 1000;
+
     // How long we wait for a launched process to attach to the activity manager
     // before we decide it's never going to come up for real, when the process was
     // started with a wrapper for instrumentation (such as Valgrind) because it
@@ -458,11 +464,7 @@
     static final int BROADCAST_FG_TIMEOUT = 10*1000;
     static final int BROADCAST_BG_TIMEOUT = 60*1000;
 
-    // Disable hidden API checks for the newly started instrumentation.
-    // Must be kept in sync with Am.
-    private static final int INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS = 1 << 0;
-
-    static final int MY_PID = myPid();
+    public static final int MY_PID = myPid();
 
     static final String[] EMPTY_STRING_ARRAY = new String[0];
 
@@ -476,16 +478,13 @@
     private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20;
 
     // Necessary ApplicationInfo flags to mark an app as persistent
-    private static final int PERSISTENT_MASK =
+    static final int PERSISTENT_MASK =
             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
 
     // Intent sent when remote bugreport collection has been completed
     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
 
-    // Used to indicate that an app transition should be animated.
-    static final boolean ANIMATE = true;
-
     // If set, we will push process association information in to procstats.
     static final boolean TRACK_PROCSTATS_ASSOCIATIONS = true;
 
@@ -494,6 +493,9 @@
      */
     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
 
+    // The minimum memory growth threshold (in KB) for low RAM devices.
+    private static final int MINIMUM_MEMORY_GROWTH_THRESHOLD = 10 * 1000; // 10 MB
+
     /**
      * State indicating that there is no need for any blocking for network.
      */
@@ -523,9 +525,6 @@
 
     private Installer mInstaller;
 
-    /** Run all ActivityStacks through this */
-    ActivityStackSupervisor mStackSupervisor;
-
     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
 
     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
@@ -565,12 +564,6 @@
     final AppErrors mAppErrors;
 
     /**
-     * Dump of the activity state at the time of the last ANR. Cleared after
-     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
-     */
-    String mLastANRState;
-
-    /**
      * Indicates the maximum time spent waiting for the network rules to get updated.
      */
     @VisibleForTesting
@@ -623,46 +616,12 @@
     final ProcessList mProcessList = new ProcessList();
 
     /**
-     * All of the applications we currently have running organized by name.
-     * The keys are strings of the application package name (as
-     * returned by the package manager), and the keys are ApplicationRecord
-     * objects.
-     */
-    final MyProcessMap mProcessNames = new MyProcessMap();
-    final class MyProcessMap extends ProcessMap<ProcessRecord> {
-        @Override
-        public ProcessRecord put(String name, int uid, ProcessRecord value) {
-            final ProcessRecord r = super.put(name, uid, value);
-            mAtmInternal.onProcessAdded(r.getWindowProcessController());
-            return r;
-        }
-
-        @Override
-        public ProcessRecord remove(String name, int uid) {
-            final ProcessRecord r = super.remove(name, uid);
-            mAtmInternal.onProcessRemoved(name, uid);
-            return r;
-        }
-    }
-
-    /**
      * Tracking long-term execution of processes to look for abuse and other
      * bad app behavior.
      */
     final ProcessStatsService mProcessStats;
 
     /**
-     * The currently running isolated processes.
-     */
-    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
-
-    /**
-     * Counter for assigning isolated process uids, to avoid frequently reusing the
-     * same ones.
-     */
-    int mNextIsolatedProcessUid = 0;
-
-    /**
      * Non-persistent appId whitelist for background restrictions
      */
     int[] mBackgroundAppIdWhitelist = new int[] {
@@ -763,28 +722,6 @@
     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
 
     /**
-     * Processes that are being forcibly torn down.
-     */
-    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
-
-    /**
-     * List of running applications, sorted by recent usage.
-     * The first entry in the list is the least recently used.
-     */
-    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
-
-    /**
-     * Where in mLruProcesses that the processes hosting activities start.
-     */
-    int mLruProcessActivityStart = 0;
-
-    /**
-     * Where in mLruProcesses that the processes hosting services start.
-     * This is after (lower index) than mLruProcessesActivityStart.
-     */
-    int mLruProcessServiceStart = 0;
-
-    /**
      * List of processes that should gc as soon as things are idle.
      */
     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
@@ -807,16 +744,14 @@
      */
     boolean mFullPssPending = false;
 
-    /**
-     * Track all uids that have actively running processes.
-     */
-    final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
+    /** Track all uids that have actively running processes. */
+    final ActiveUids mActiveUids;
 
     /**
      * This is for verifying the UID report flow.
      */
     static final boolean VALIDATE_UID_STATES = true;
-    final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
+    final ActiveUids mValidateUids = new ActiveUids(this, false /* postChangesToAtm */);
 
     /**
      * Fingerprints (hashCode()) of stack traces that we've
@@ -1043,7 +978,7 @@
         }
     }
 
-    final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
+    final PendingTempWhitelists mPendingTempWhitelist = new PendingTempWhitelists(this);
 
     /**
      * Information about and control over application operations
@@ -1051,11 +986,6 @@
     final AppOpsService mAppOpsService;
 
     /**
-     * Hardware-reported OpenGLES version.
-     */
-    final int GL_ES_VERSION;
-
-    /**
      * List of initialization arguments to pass to all processes when binding applications to them.
      * For example, references to the commonly used services.
      */
@@ -1067,22 +997,14 @@
      */
     final StringBuilder mStringBuilder = new StringBuilder(256);
 
-    /**
-     * Used to control how we initialize the service.
-     */
-    ComponentName mTopComponent;
-    String mTopAction = Intent.ACTION_MAIN;
-    String mTopData;
-
     volatile boolean mProcessesReady = false;
     volatile boolean mSystemReady = false;
     volatile boolean mOnBattery = false;
-    volatile int mFactoryTest;
+    final int mFactoryTest;
     volatile boolean mBooting = false;
 
     @GuardedBy("this") boolean mCallFinishBooting = false;
     @GuardedBy("this") boolean mBootAnimationComplete = false;
-    private @GuardedBy("this") boolean mCheckedForSetup = false;
 
     final Context mContext;
 
@@ -1113,11 +1035,6 @@
     int mAdjSeq = 0;
 
     /**
-     * Current sequence id for process LRU updating.
-     */
-    int mLruSeq = 0;
-
-    /**
      * Keep track of the non-cached/empty process we last found, to help
      * determine how to distribute cached/empty processes next time.
      */
@@ -1229,31 +1146,6 @@
 
     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
 
-    /**
-     * A global counter for generating sequence numbers.
-     * This value will be used when incrementing sequence numbers in individual uidRecords.
-     *
-     * Having a global counter ensures that seq numbers are monotonically increasing for a
-     * particular uid even when the uidRecord is re-created.
-     */
-    @GuardedBy("this")
-    @VisibleForTesting
-    long mProcStateSeqCounter = 0;
-
-    /**
-     * A global counter for generating sequence numbers to uniquely identify pending process starts.
-     */
-    @GuardedBy("this")
-    private long mProcStartSeqCounter = 0;
-
-    /**
-     * Contains {@link ProcessRecord} objects for pending process starts.
-     *
-     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
-     */
-    @GuardedBy("this")
-    private final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
-
     private final Injector mInjector;
 
     static final class ProcessChangeItem {
@@ -1410,8 +1302,6 @@
 
     static final int SHOW_ERROR_UI_MSG = 1;
     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
-    static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
-    static final int UPDATE_CONFIGURATION_MSG = 4;
     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
     static final int SERVICE_TIMEOUT_MSG = 12;
@@ -1426,7 +1316,6 @@
     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
     static final int REPORT_MEM_USAGE_MSG = 33;
     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
-    static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
     static final int DELETE_DUMPHEAP_MSG = 51;
@@ -1440,16 +1329,10 @@
     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
 
-    static final int FIRST_ACTIVITY_STACK_MSG = 100;
     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
-    static final int FIRST_COMPAT_MODE_MSG = 300;
-    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
 
     static final String SERVICE_RECORD_KEY = "servicerecord";
 
-    static ServiceThread sKillThread = null;
-    static KillHandler sKillHandler = null;
-
     long mLastMemUsageReportTime = 0;
 
     /**
@@ -1471,8 +1354,6 @@
 
     PackageManagerInternal mPackageManagerInt;
 
-    boolean mHasHeavyWeightFeature;
-
     /**
      * Whether to force background check on all apps (for battery saver) or not.
      */
@@ -1485,31 +1366,7 @@
      * also corresponds to the merged configuration of the default display.
      */
     Configuration getGlobalConfiguration() {
-        return mStackSupervisor.getConfiguration();
-    }
-
-    final class KillHandler extends Handler {
-        static final int KILL_PROCESS_GROUP_MSG = 4000;
-
-        public KillHandler(Looper looper) {
-            super(looper, null, true);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case KILL_PROCESS_GROUP_MSG:
-                {
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
-                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
-                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-                }
-                break;
-
-                default:
-                    super.handleMessage(msg);
-            }
-        }
+        return mActivityTaskManager.getGlobalConfiguration();
     }
 
     final class UiHandler extends Handler {
@@ -1554,12 +1411,6 @@
                 }
                 ensureBootCompleted();
             } break;
-            case SHOW_FACTORY_ERROR_UI_MSG: {
-                Dialog d = new FactoryErrorDialog(
-                        mUiContext, msg.getData().getCharSequence("msg"));
-                d.show();
-                ensureBootCompleted();
-            } break;
             case WAIT_FOR_DEBUGGER_UI_MSG: {
                 synchronized (ActivityManagerService.this) {
                     ProcessRecord app = (ProcessRecord)msg.obj;
@@ -1614,11 +1465,6 @@
         @Override
         public void handleMessage(Message msg) {
             switch (msg.what) {
-            case UPDATE_CONFIGURATION_MSG: {
-                final ContentResolver resolver = mContext.getContentResolver();
-                Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
-                        msg.arg1);
-            } break;
             case GC_BACKGROUND_PROCESSES_MSG: {
                 synchronized (ActivityManagerService.this) {
                     performAppGcsIfAppropriateLocked();
@@ -1636,8 +1482,8 @@
             } break;
             case UPDATE_TIME_ZONE: {
                 synchronized (ActivityManagerService.this) {
-                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
-                        ProcessRecord r = mLruProcesses.get(i);
+                    for (int i = mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
+                        ProcessRecord r = mProcessList.mLruProcesses.get(i);
                         if (r.thread != null) {
                             try {
                                 r.thread.updateTimeZone();
@@ -1650,16 +1496,7 @@
             } break;
             case CLEAR_DNS_CACHE_MSG: {
                 synchronized (ActivityManagerService.this) {
-                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
-                        ProcessRecord r = mLruProcesses.get(i);
-                        if (r.thread != null) {
-                            try {
-                                r.thread.clearDnsCache();
-                            } catch (RemoteException ex) {
-                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
-                            }
-                        }
-                    }
+                    mProcessList.clearAllDnsCacheLocked();
                 }
             } break;
             case UPDATE_HTTP_PROXY_MSG: {
@@ -1675,19 +1512,7 @@
                     pacFileUrl = proxy.getPacFileUrl();
                 }
                 synchronized (ActivityManagerService.this) {
-                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
-                        ProcessRecord r = mLruProcesses.get(i);
-                        // Don't dispatch to isolated processes as they can't access
-                        // ConnectivityManager and don't have network privileges anyway.
-                        if (r.thread != null && !r.isolated) {
-                            try {
-                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
-                            } catch (RemoteException ex) {
-                                Slog.w(TAG, "Failed to update http proxy for: " +
-                                        r.info.processName);
-                            }
-                        }
-                    }
+                    mProcessList.setAllHttpProxyLocked(host, port, exclList, pacFileUrl);
                 }
             } break;
             case PROC_START_TIMEOUT_MSG: {
@@ -1735,29 +1560,7 @@
                 // The user's time format preference might have changed.
                 // For convenience we re-use the Intent extra values.
                 synchronized (ActivityManagerService.this) {
-                    for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
-                        ProcessRecord r = mLruProcesses.get(i);
-                        if (r.thread != null) {
-                            try {
-                                r.thread.updateTimePrefs(msg.arg1);
-                            } catch (RemoteException ex) {
-                                Slog.w(TAG, "Failed to update preferences for: "
-                                        + r.info.processName);
-                            }
-                        }
-                    }
-                }
-                break;
-            }
-            case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
-                try {
-                    Locale l = (Locale) msg.obj;
-                    IBinder service = ServiceManager.getService("mount");
-                    IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
-                    Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
-                    storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Error storing locale for decryption UI", e);
+                    mProcessList.updateAllTimePrefsLocked(msg.arg1);
                 }
                 break;
             }
@@ -1881,17 +1684,7 @@
             } break;
             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
                 synchronized (ActivityManagerService.this) {
-                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
-                        ProcessRecord r = mLruProcesses.get(i);
-                        if (r.thread != null) {
-                            try {
-                                r.thread.handleTrustStorageUpdate();
-                            } catch (RemoteException ex) {
-                                Slog.w(TAG, "Failed to handle trust storage update for: " +
-                                        r.info.processName);
-                            }
-                        }
-                    }
+                    mProcessList.handleAllTrustStorageUpdateLocked();
                 }
             } break;
             }
@@ -2031,7 +1824,9 @@
             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
 
             synchronized (this) {
-                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
+                ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
+                        false,
+                        0);
                 app.setPersistent(true);
                 app.pid = MY_PID;
                 app.getWindowProcessController().setPid(MY_PID);
@@ -2040,7 +1835,7 @@
                 synchronized (mPidsSelfLocked) {
                     mPidsSelfLocked.put(app.pid, app);
                 }
-                updateLruProcessLocked(app, false, null);
+                mProcessList.updateLruProcessLocked(app, false, null);
                 updateOomAdjLocked();
             }
         } catch (PackageManager.NameNotFoundException e) {
@@ -2066,12 +1861,12 @@
         synchronized (this) {
             mWindowManager = wm;
             mActivityTaskManager.setWindowManager(wm);
-            mStackSupervisor.setWindowManager(wm);
         }
     }
 
     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
         mUsageStatsService = usageStatsManager;
+        mActivityTaskManager.setUsageStatsManager(usageStatsManager);
     }
 
     public void startObservingNativeCrashes() {
@@ -2308,28 +2103,43 @@
 
     @VisibleForTesting
     public ActivityManagerService(Injector injector) {
+        this(injector, null /* handlerThread */);
+    }
+
+    /**
+     * Provides the basic functionality for activity task related tests when a handler thread is
+     * given to initialize the dependency members.
+     */
+    @VisibleForTesting
+    ActivityManagerService(Injector injector, ServiceThread handlerThread) {
+        final boolean hasHandlerThread = handlerThread != null;
         mInjector = injector;
         mContext = mInjector.getContext();
         mUiContext = null;
-        GL_ES_VERSION = 0;
         mAppErrors = null;
-        mAppOpsService = mInjector.getAppOpsService(null, null);
+        mActiveUids = new ActiveUids(this, false /* postChangesToAtm */);
+        mAppOpsService = mInjector.getAppOpsService(null /* file */, null /* handler */);
         mBatteryStatsService = null;
-        mConstants = null;
-        mHandler = null;
-        mHandlerThread = null;
-        mIntentFirewall = null;
+        mHandler = hasHandlerThread ? new MainHandler(handlerThread.getLooper()) : null;
+        mHandlerThread = handlerThread;
+        mConstants = hasHandlerThread ? new ActivityManagerConstants(this, mHandler) : null;
+        mIntentFirewall = hasHandlerThread
+                ? new IntentFirewall(new IntentFirewallInterface(), mHandler) : null;
         mProcessCpuThread = null;
         mProcessStats = null;
         mProviderMap = null;
-        mServices = null;
+        // For the usage of {@link ActiveServices#cleanUpServices} that may be invoked from
+        // {@link ActivityStackSupervisor#cleanUpRemovedTaskLocked}.
+        mServices = hasHandlerThread ? new ActiveServices(this) : null;
         mSystemThread = null;
-        mUiHandler = injector.getUiHandler(null);
-        mUserController = null;
-        mPendingIntentController = null;
+        mUiHandler = injector.getUiHandler(null /* service */);
+        mUserController = hasHandlerThread ? new UserController(this) : null;
+        mPendingIntentController = hasHandlerThread
+                ? new PendingIntentController(handlerThread.getLooper(), mUserController) : null;
         mProcStartHandlerThread = null;
         mProcStartHandler = null;
         mHiddenApiBlacklist = null;
+        mFactoryTest = FACTORY_TEST_OFF;
     }
 
     // Note: This method is invoked on the main thread but may need to attach various
@@ -2358,13 +2168,7 @@
 
         mConstants = new ActivityManagerConstants(this, mHandler);
 
-        /* static; one-time init here */
-        if (sKillHandler == null) {
-            sKillThread = new ServiceThread(TAG + ":kill",
-                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
-            sKillThread.start();
-            sKillHandler = new KillHandler(sKillThread.getLooper());
-        }
+        mProcessList.init(this);
 
         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                 "foreground", BROADCAST_FG_TIMEOUT, false);
@@ -2376,6 +2180,7 @@
         mServices = new ActiveServices(this);
         mProviderMap = new ProviderMap(this);
         mAppErrors = new AppErrors(mUiContext, this);
+        mActiveUids = new ActiveUids(this, true /* postChangesToAtm */);
 
         final File systemDir = SystemServiceManager.ensureSystemDir();
 
@@ -2400,9 +2205,6 @@
         mPendingIntentController = new PendingIntentController(
                 mHandlerThread.getLooper(), mUserController);
 
-        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
-            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
-
         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
             mUseFifoUiScheduling = true;
         }
@@ -2411,9 +2213,9 @@
         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
 
         mActivityTaskManager = atm;
-        mActivityTaskManager.setActivityManagerService(this);
+        mActivityTaskManager.setActivityManagerService(this, mHandlerThread.getLooper(),
+                mIntentFirewall, mPendingIntentController);
         mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
-        mStackSupervisor = mActivityTaskManager.mStackSupervisor;
 
         mProcessCpuThread = new Thread("CpuTracker") {
             @Override
@@ -2517,12 +2319,13 @@
         if (code == SYSPROPS_TRANSACTION) {
             // We need to tell all apps about the system property change.
             ArrayList<IBinder> procs = new ArrayList<IBinder>();
-            synchronized(this) {
-                final int NP = mProcessNames.getMap().size();
-                for (int ip=0; ip<NP; ip++) {
-                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
+            synchronized (this) {
+                final int NP = mProcessList.mProcessNames.getMap().size();
+                for (int ip = 0; ip < NP; ip++) {
+                    SparseArray<ProcessRecord> apps =
+                            mProcessList.mProcessNames.getMap().valueAt(ip);
                     final int NA = apps.size();
-                    for (int ia=0; ia<NA; ia++) {
+                    for (int ia = 0; ia < NA; ia++) {
                         ProcessRecord app = apps.valueAt(ia);
                         if (app.thread != null) {
                             procs.add(app.thread.asBinder());
@@ -2772,329 +2575,21 @@
         mActivityTaskManager.unregisterTaskStackListener(listener);
     }
 
-    private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
-            String what, Object obj, ProcessRecord srcApp) {
-        app.lastActivityTime = now;
-
-        if (app.hasActivitiesOrRecentTasks()) {
-            // Don't want to touch dependent processes that are hosting activities.
-            return index;
-        }
-
-        int lrui = mLruProcesses.lastIndexOf(app);
-        if (lrui < 0) {
-            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
-                    + what + " " + obj + " from " + srcApp);
-            return index;
-        }
-
-        if (lrui >= index) {
-            // Don't want to cause this to move dependent processes *back* in the
-            // list as if they were less frequently used.
-            return index;
-        }
-
-        if (lrui >= mLruProcessActivityStart) {
-            // Don't want to touch dependent processes that are hosting activities.
-            return index;
-        }
-
-        mLruProcesses.remove(lrui);
-        if (index > 0) {
-            index--;
-        }
-        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
-                + " in LRU list: " + app);
-        mLruProcesses.add(index, app);
-        return index;
-    }
-
-    static void killProcessGroup(int uid, int pid) {
-        if (sKillHandler != null) {
-            sKillHandler.sendMessage(
-                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
-        } else {
-            Slog.w(TAG, "Asked to kill process group before system bringup!");
-            Process.killProcessGroup(uid, pid);
-        }
+    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
+            ProcessRecord client) {
+        mProcessList.updateLruProcessLocked(app, activityChange, client);
     }
 
     final void removeLruProcessLocked(ProcessRecord app) {
-        int lrui = mLruProcesses.lastIndexOf(app);
-        if (lrui >= 0) {
-            if (!app.killed) {
-                if (app.isPersistent()) {
-                    Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
-                } else {
-                    Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
-                    if (app.pid > 0) {
-                        killProcessQuiet(app.pid);
-                        killProcessGroup(app.uid, app.pid);
-                    } else {
-                        app.pendingStart = false;
-                    }
-                }
-            }
-            if (lrui <= mLruProcessActivityStart) {
-                mLruProcessActivityStart--;
-            }
-            if (lrui <= mLruProcessServiceStart) {
-                mLruProcessServiceStart--;
-            }
-            mLruProcesses.remove(lrui);
-        }
-    }
-
-    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
-            ProcessRecord client) {
-        final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities
-                || app.treatLikeActivity;
-        final boolean hasService = false; // not impl yet. app.services.size() > 0;
-        if (!activityChange && hasActivity) {
-            // The process has activities, so we are only allowing activity-based adjustments
-            // to move it.  It should be kept in the front of the list with other
-            // processes that have activities, and we don't want those to change their
-            // order except due to activity operations.
-            return;
-        }
-
-        mLruSeq++;
-        final long now = SystemClock.uptimeMillis();
-        app.lastActivityTime = now;
-
-        // First a quick reject: if the app is already at the position we will
-        // put it, then there is nothing to do.
-        if (hasActivity) {
-            final int N = mLruProcesses.size();
-            if (N > 0 && mLruProcesses.get(N-1) == app) {
-                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
-                return;
-            }
-        } else {
-            if (mLruProcessServiceStart > 0
-                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
-                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
-                return;
-            }
-        }
-
-        int lrui = mLruProcesses.lastIndexOf(app);
-
-        if (app.isPersistent() && lrui >= 0) {
-            // We don't care about the position of persistent processes, as long as
-            // they are in the list.
-            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
-            return;
-        }
-
-        /* In progress: compute new position first, so we can avoid doing work
-           if the process is not actually going to move.  Not yet working.
-        int addIndex;
-        int nextIndex;
-        boolean inActivity = false, inService = false;
-        if (hasActivity) {
-            // Process has activities, put it at the very tipsy-top.
-            addIndex = mLruProcesses.size();
-            nextIndex = mLruProcessServiceStart;
-            inActivity = true;
-        } else if (hasService) {
-            // Process has services, put it at the top of the service list.
-            addIndex = mLruProcessActivityStart;
-            nextIndex = mLruProcessServiceStart;
-            inActivity = true;
-            inService = true;
-        } else  {
-            // Process not otherwise of interest, it goes to the top of the non-service area.
-            addIndex = mLruProcessServiceStart;
-            if (client != null) {
-                int clientIndex = mLruProcesses.lastIndexOf(client);
-                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
-                        + app);
-                if (clientIndex >= 0 && addIndex > clientIndex) {
-                    addIndex = clientIndex;
-                }
-            }
-            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
-        }
-
-        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
-                + mLruProcessActivityStart + "): " + app);
-        */
-
-        if (lrui >= 0) {
-            if (lrui < mLruProcessActivityStart) {
-                mLruProcessActivityStart--;
-            }
-            if (lrui < mLruProcessServiceStart) {
-                mLruProcessServiceStart--;
-            }
-            /*
-            if (addIndex > lrui) {
-                addIndex--;
-            }
-            if (nextIndex > lrui) {
-                nextIndex--;
-            }
-            */
-            mLruProcesses.remove(lrui);
-        }
-
-        /*
-        mLruProcesses.add(addIndex, app);
-        if (inActivity) {
-            mLruProcessActivityStart++;
-        }
-        if (inService) {
-            mLruProcessActivityStart++;
-        }
-        */
-
-        int nextIndex;
-        if (hasActivity) {
-            final int N = mLruProcesses.size();
-            if ((!app.hasActivities() || app.hasRecentTasks())
-                    && mLruProcessActivityStart < (N - 1)) {
-                // Process doesn't have activities, but has clients with
-                // activities...  move it up, but one below the top (the top
-                // should always have a real activity).
-                if (DEBUG_LRU) Slog.d(TAG_LRU,
-                        "Adding to second-top of LRU activity list: " + app);
-                mLruProcesses.add(N - 1, app);
-                // To keep it from spamming the LRU list (by making a bunch of clients),
-                // we will push down any other entries owned by the app.
-                final int uid = app.info.uid;
-                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
-                    ProcessRecord subProc = mLruProcesses.get(i);
-                    if (subProc.info.uid == uid) {
-                        // We want to push this one down the list.  If the process after
-                        // it is for the same uid, however, don't do so, because we don't
-                        // want them internally to be re-ordered.
-                        if (mLruProcesses.get(i - 1).info.uid != uid) {
-                            if (DEBUG_LRU) Slog.d(TAG_LRU,
-                                    "Pushing uid " + uid + " swapping at " + i + ": "
-                                    + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
-                            ProcessRecord tmp = mLruProcesses.get(i);
-                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
-                            mLruProcesses.set(i - 1, tmp);
-                            i--;
-                        }
-                    } else {
-                        // A gap, we can stop here.
-                        break;
-                    }
-                }
-            } else {
-                // Process has activities, put it at the very tipsy-top.
-                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
-                mLruProcesses.add(app);
-            }
-            nextIndex = mLruProcessServiceStart;
-        } else if (hasService) {
-            // Process has services, put it at the top of the service list.
-            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
-            mLruProcesses.add(mLruProcessActivityStart, app);
-            nextIndex = mLruProcessServiceStart;
-            mLruProcessActivityStart++;
-        } else  {
-            // Process not otherwise of interest, it goes to the top of the non-service area.
-            int index = mLruProcessServiceStart;
-            if (client != null) {
-                // If there is a client, don't allow the process to be moved up higher
-                // in the list than that client.
-                int clientIndex = mLruProcesses.lastIndexOf(client);
-                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
-                        + " when updating " + app);
-                if (clientIndex <= lrui) {
-                    // Don't allow the client index restriction to push it down farther in the
-                    // list than it already is.
-                    clientIndex = lrui;
-                }
-                if (clientIndex >= 0 && index > clientIndex) {
-                    index = clientIndex;
-                }
-            }
-            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
-            mLruProcesses.add(index, app);
-            nextIndex = index-1;
-            mLruProcessActivityStart++;
-            mLruProcessServiceStart++;
-        }
-
-        // If the app is currently using a content provider or service,
-        // bump those processes as well.
-        for (int j=app.connections.size()-1; j>=0; j--) {
-            ConnectionRecord cr = app.connections.valueAt(j);
-            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
-                    && cr.binding.service.app != null
-                    && cr.binding.service.app.lruSeq != mLruSeq
-                    && !cr.binding.service.app.isPersistent()) {
-                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
-                        "service connection", cr, app);
-            }
-        }
-        for (int j=app.conProviders.size()-1; j>=0; j--) {
-            ContentProviderRecord cpr = app.conProviders.get(j).provider;
-            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
-                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
-                        "provider reference", cpr, app);
-            }
-        }
+        mProcessList.removeLruProcessLocked(app);
     }
 
     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
-        if (uid == SYSTEM_UID) {
-            // The system gets to run in any process.  If there are multiple
-            // processes with the same uid, just pick the first (this
-            // should never happen).
-            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
-            if (procs == null) return null;
-            final int procCount = procs.size();
-            for (int i = 0; i < procCount; i++) {
-                final int procUid = procs.keyAt(i);
-                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
-                    // Don't use an app process or different user process for system component.
-                    continue;
-                }
-                return procs.valueAt(i);
-            }
-        }
-        ProcessRecord proc = mProcessNames.get(processName, uid);
-        if (false && proc != null && !keepIfLarge
-                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
-                && proc.lastCachedPss >= 4000) {
-            // Turn this condition on to cause killing to happen regularly, for testing.
-            if (proc.baseProcessTracker != null) {
-                proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
-                for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
-                    ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
-                    StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
-                            proc.info.uid,
-                            holder.state.getName(),
-                            holder.state.getPackage(),
-                            proc.lastCachedPss, holder.appVersion);
-                }
-            }
-            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
-        } else if (proc != null && !keepIfLarge
-                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
-                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
-            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
-            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
-                if (proc.baseProcessTracker != null) {
-                    proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
-                    for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
-                        ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
-                        StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
-                                proc.info.uid,
-                                holder.state.getName(),
-                                holder.state.getPackage(),
-                                proc.lastCachedPss, holder.appVersion);
-                    }
-                }
-                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
-            }
-        }
-        return proc;
+        return mProcessList.getProcessRecordLocked(processName, uid, keepIfLarge);
+    }
+
+    final ProcessMap<ProcessRecord> getProcessNames() {
+        return mProcessList.mProcessNames;
     }
 
     void notifyPackageUse(String packageName, int reason) {
@@ -3121,7 +2616,7 @@
             info.packageName = "android";
             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
             info.targetSdkVersion = Build.VERSION.SDK_INT;
-            ProcessRecord proc = startProcessLocked(processName, info /* info */,
+            ProcessRecord proc = mProcessList.startProcessLocked(processName, info /* info */,
                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
@@ -3135,556 +2630,17 @@
             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
             boolean isolated, boolean keepIfLarge) {
-        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
+        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
+                hostingType,
                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                 null /* crashHandler */);
     }
 
-    @GuardedBy("this")
-    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
-            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
-            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
-            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
-        long startTime = SystemClock.elapsedRealtime();
-        ProcessRecord app;
-        if (!isolated) {
-            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
-            checkTime(startTime, "startProcess: after getProcessRecord");
-
-            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
-                // If we are in the background, then check to see if this process
-                // is bad.  If so, we will just silently fail.
-                if (mAppErrors.isBadProcessLocked(info)) {
-                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
-                            + "/" + info.processName);
-                    return null;
-                }
-            } else {
-                // When the user is explicitly starting a process, then clear its
-                // crash count so that we won't make it bad until they see at
-                // least one crash dialog again, and make the process good again
-                // if it had been bad.
-                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
-                        + "/" + info.processName);
-                mAppErrors.resetProcessCrashTimeLocked(info);
-                if (mAppErrors.isBadProcessLocked(info)) {
-                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
-                            UserHandle.getUserId(info.uid), info.uid,
-                            info.processName);
-                    mAppErrors.clearBadProcessLocked(info);
-                    if (app != null) {
-                        app.bad = false;
-                    }
-                }
-            }
-        } else {
-            // If this is an isolated process, it can't re-use an existing process.
-            app = null;
-        }
-
-        // We don't have to do anything more if:
-        // (1) There is an existing application record; and
-        // (2) The caller doesn't think it is dead, OR there is no thread
-        //     object attached to it so we know it couldn't have crashed; and
-        // (3) There is a pid assigned to it, so it is either starting or
-        //     already running.
-        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
-                + " app=" + app + " knownToBeDead=" + knownToBeDead
-                + " thread=" + (app != null ? app.thread : null)
-                + " pid=" + (app != null ? app.pid : -1));
-        if (app != null && app.pid > 0) {
-            if ((!knownToBeDead && !app.killed) || app.thread == null) {
-                // We already have the app running, or are waiting for it to
-                // come up (we have a pid but not yet its thread), so keep it.
-                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
-                // If this is a new package in the process, add the package to the list
-                app.addPackage(info.packageName, info.versionCode, mProcessStats);
-                checkTime(startTime, "startProcess: done, added package to proc");
-                return app;
-            }
-
-            // An application record is attached to a previous process,
-            // clean it up now.
-            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
-            checkTime(startTime, "startProcess: bad proc running, killing");
-            killProcessGroup(app.uid, app.pid);
-            handleAppDiedLocked(app, true, true);
-            checkTime(startTime, "startProcess: done killing old proc");
-        }
-
-        String hostingNameStr = hostingName != null
-                ? hostingName.flattenToShortString() : null;
-
-        if (app == null) {
-            checkTime(startTime, "startProcess: creating new process record");
-            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
-            if (app == null) {
-                Slog.w(TAG, "Failed making new process record for "
-                        + processName + "/" + info.uid + " isolated=" + isolated);
-                return null;
-            }
-            app.crashHandler = crashHandler;
-            app.isolatedEntryPoint = entryPoint;
-            app.isolatedEntryPointArgs = entryPointArgs;
-            checkTime(startTime, "startProcess: done creating new process record");
-        } else {
-            // If this is a new package in the process, add the package to the list
-            app.addPackage(info.packageName, info.versionCode, mProcessStats);
-            checkTime(startTime, "startProcess: added package to existing proc");
-        }
-
-        // If the system is not ready yet, then hold off on starting this
-        // process until it is.
-        if (!mProcessesReady
-                && !isAllowedWhileBooting(info)
-                && !allowWhileBooting) {
-            if (!mProcessesOnHold.contains(app)) {
-                mProcessesOnHold.add(app);
-            }
-            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
-                    "System not ready, putting on hold: " + app);
-            checkTime(startTime, "startProcess: returning with proc on hold");
-            return app;
-        }
-
-        checkTime(startTime, "startProcess: stepping in to startProcess");
-        final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
-        checkTime(startTime, "startProcess: done starting proc!");
-        return success ? app : null;
-    }
-
     boolean isAllowedWhileBooting(ApplicationInfo ai) {
         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
     }
 
-    @GuardedBy("this")
-    private final void startProcessLocked(ProcessRecord app,
-            String hostingType, String hostingNameStr) {
-        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
-    }
-
-    @GuardedBy("this")
-    private final boolean startProcessLocked(ProcessRecord app,
-            String hostingType, String hostingNameStr, String abiOverride) {
-        return startProcessLocked(app, hostingType, hostingNameStr,
-                false /* disableHiddenApiChecks */, abiOverride);
-    }
-
-    /**
-     * @return {@code true} if process start is successful, false otherwise.
-     */
-    @GuardedBy("this")
-    private final boolean startProcessLocked(ProcessRecord app, String hostingType,
-            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
-        if (app.pendingStart) {
-            return true;
-        }
-        long startTime = SystemClock.elapsedRealtime();
-        if (app.pid > 0 && app.pid != MY_PID) {
-            checkTime(startTime, "startProcess: removing from pids map");
-            synchronized (mPidsSelfLocked) {
-                mPidsSelfLocked.remove(app.pid);
-                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-            }
-            checkTime(startTime, "startProcess: done removing from pids map");
-            app.setPid(0);
-        }
-
-        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
-                "startProcessLocked removing on hold: " + app);
-        mProcessesOnHold.remove(app);
-
-        checkTime(startTime, "startProcess: starting to update cpu stats");
-        updateCpuStats();
-        checkTime(startTime, "startProcess: done updating cpu stats");
-
-        try {
-            try {
-                final int userId = UserHandle.getUserId(app.uid);
-                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
-            } catch (RemoteException e) {
-                throw e.rethrowAsRuntimeException();
-            }
-
-            int uid = app.uid;
-            int[] gids = null;
-            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
-            if (!app.isolated) {
-                int[] permGids = null;
-                try {
-                    checkTime(startTime, "startProcess: getting gids from package manager");
-                    final IPackageManager pm = AppGlobals.getPackageManager();
-                    permGids = pm.getPackageGids(app.info.packageName,
-                            MATCH_DEBUG_TRIAGED_MISSING, app.userId);
-                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
-                            StorageManagerInternal.class);
-                    mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
-                            app.info.packageName);
-                } catch (RemoteException e) {
-                    throw e.rethrowAsRuntimeException();
-                }
-
-                /*
-                 * Add shared application and profile GIDs so applications can share some
-                 * resources like shared libraries and access user-wide resources
-                 */
-                if (ArrayUtils.isEmpty(permGids)) {
-                    gids = new int[3];
-                } else {
-                    gids = new int[permGids.length + 3];
-                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
-                }
-                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
-                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
-                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
-
-                // Replace any invalid GIDs
-                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
-                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
-            }
-            checkTime(startTime, "startProcess: building args");
-            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
-                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
-                        && mTopComponent != null
-                        && app.processName.equals(mTopComponent.getPackageName())) {
-                    uid = 0;
-                }
-                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
-                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
-                    uid = 0;
-                }
-            }
-            int runtimeFlags = 0;
-            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
-                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
-                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
-                // Also turn on CheckJNI for debuggable apps. It's quite
-                // awkward to turn on otherwise.
-                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
-            }
-            // Run the app in safe mode if its manifest requests so or the
-            // system is booted in safe mode.
-            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
-                mSafeMode == true) {
-                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
-            }
-            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
-                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
-            }
-            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
-            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
-                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
-            }
-            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
-            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
-                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
-            }
-            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
-                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
-            }
-            if ("1".equals(SystemProperties.get("debug.assert"))) {
-                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
-            }
-            if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
-                // Enable all debug flags required by the native debugger.
-                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
-                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
-                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
-                mNativeDebuggingApp = null;
-            }
-
-            if (app.info.isPrivilegedApp() &&
-                    DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet())) {
-                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
-            }
-
-            if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
-                app.info.maybeUpdateHiddenApiEnforcementPolicy(
-                        mHiddenApiBlacklist.getPolicyForPrePApps(),
-                        mHiddenApiBlacklist.getPolicyForPApps());
-                @HiddenApiEnforcementPolicy int policy =
-                        app.info.getHiddenApiEnforcementPolicy();
-                int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
-                if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
-                    throw new IllegalStateException("Invalid API policy: " + policy);
-                }
-                runtimeFlags |= policyBits;
-            }
-
-            String invokeWith = null;
-            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
-                // Debuggable apps may include a wrapper script with their library directory.
-                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
-                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
-                try {
-                    if (new File(wrapperFileName).exists()) {
-                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
-                    }
-                } finally {
-                    StrictMode.setThreadPolicy(oldPolicy);
-                }
-            }
-
-            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
-            if (requiredAbi == null) {
-                requiredAbi = Build.SUPPORTED_ABIS[0];
-            }
-
-            String instructionSet = null;
-            if (app.info.primaryCpuAbi != null) {
-                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
-            }
-
-            app.gids = gids;
-            app.setRequiredAbi(requiredAbi);
-            app.instructionSet = instructionSet;
-
-            // the per-user SELinux context must be set
-            if (TextUtils.isEmpty(app.info.seInfoUser)) {
-                Slog.wtf(TAG, "SELinux tag not defined",
-                        new IllegalStateException("SELinux tag not defined for "
-                        + app.info.packageName + " (uid " + app.uid + ")"));
-            }
-            final String seInfo = app.info.seInfo
-                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
-            // Start the process.  It will either succeed and return a result containing
-            // the PID of the new process, or else throw a RuntimeException.
-            final String entryPoint = "android.app.ActivityThread";
-
-            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
-                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
-                    startTime);
-        } catch (RuntimeException e) {
-            Slog.e(TAG, "Failure starting process " + app.processName, e);
-
-            // Something went very wrong while trying to start this process; one
-            // common case is when the package is frozen due to an active
-            // upgrade. To recover, clean up any active bookkeeping related to
-            // starting this process. (We already invoked this method once when
-            // the package was initially frozen through KILL_APPLICATION_MSG, so
-            // it doesn't hurt to use it again.)
-            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
-                    false, true, false, false, app.userId, "start failure");
-            return false;
-        }
-    }
-
-    @GuardedBy("this")
-    private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
-            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
-            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
-            long startTime) {
-        app.pendingStart = true;
-        app.killedByAm = false;
-        app.removed = false;
-        app.killed = false;
-        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
-        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
-        if (mConstants.FLAG_PROCESS_START_ASYNC) {
-            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
-                    "Posting procStart msg for " + app.toShortString());
-            mProcStartHandler.post(() -> {
-                try {
-                    synchronized (ActivityManagerService.this) {
-                        final String reason = isProcStartValidLocked(app, startSeq);
-                        if (reason != null) {
-                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
-                                    + " don't start process, " + reason);
-                            app.pendingStart = false;
-                            return;
-                        }
-                        app.setUsingWrapper(invokeWith != null
-                                || SystemProperties.get("wrap." + app.processName) != null);
-                        mPendingStarts.put(startSeq, app);
-                    }
-                    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
-                            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
-                            requiredAbi, instructionSet, invokeWith, app.startTime);
-                    synchronized (ActivityManagerService.this) {
-                        handleProcessStartedLocked(app, startResult, startSeq);
-                    }
-                } catch (RuntimeException e) {
-                    synchronized (ActivityManagerService.this) {
-                        Slog.e(TAG, "Failure starting process " + app.processName, e);
-                        mPendingStarts.remove(startSeq);
-                        app.pendingStart = false;
-                        forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
-                                false, false, true, false, false, app.userId, "start failure");
-                    }
-                }
-            });
-            return true;
-        } else {
-            try {
-                final ProcessStartResult startResult = startProcess(hostingType, entryPoint, app,
-                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
-                        invokeWith, startTime);
-                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
-                        startSeq, false);
-            } catch (RuntimeException e) {
-                Slog.e(TAG, "Failure starting process " + app.processName, e);
-                app.pendingStart = false;
-                forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
-                        false, false, true, false, false, app.userId, "start failure");
-            }
-            return app.pid > 0;
-        }
-    }
-
-    private ProcessStartResult startProcess(String hostingType, String entryPoint,
-            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
-            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
-            long startTime) {
-        try {
-            final String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
-            final String[] visibleVolIds = LocalServices.getService(StorageManagerInternal.class)
-                    .getVisibleVolumesForUser(UserHandle.getUserId(uid));
-            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
-                    app.processName);
-            checkTime(startTime, "startProcess: asking zygote to start proc");
-            final ProcessStartResult startResult;
-            if (hostingType.equals("webview_service")) {
-                startResult = startWebView(entryPoint,
-                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
-                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
-                        app.info.dataDir, null, app.info.packageName,
-                        packageNames, visibleVolIds,
-                        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,
-                        packageNames, visibleVolIds,
-                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
-            }
-            checkTime(startTime, "startProcess: returned from zygote!");
-            return startResult;
-        } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
-        }
-    }
-
-    @GuardedBy("this")
-    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
-        StringBuilder sb = null;
-        if (app.killedByAm) {
-            if (sb == null) sb = new StringBuilder();
-            sb.append("killedByAm=true;");
-        }
-        if (mProcessNames.get(app.processName, app.uid) != app) {
-            if (sb == null) sb = new StringBuilder();
-            sb.append("No entry in mProcessNames;");
-        }
-        if (!app.pendingStart) {
-            if (sb == null) sb = new StringBuilder();
-            sb.append("pendingStart=false;");
-        }
-        if (app.startSeq > expectedStartSeq) {
-            if (sb == null) sb = new StringBuilder();
-            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
-        }
-        return sb == null ? null : sb.toString();
-    }
-
-    @GuardedBy("this")
-    private boolean handleProcessStartedLocked(ProcessRecord pending,
-            ProcessStartResult startResult, long expectedStartSeq) {
-        // Indicates that this process start has been taken care of.
-        if (mPendingStarts.get(expectedStartSeq) == null) {
-            if (pending.pid == startResult.pid) {
-                pending.setUsingWrapper(startResult.usingWrapper);
-                // TODO: Update already existing clients of usingWrapper
-            }
-            return false;
-        }
-        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
-                expectedStartSeq, false);
-    }
-
-    @GuardedBy("this")
-    private boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
-            long expectedStartSeq, boolean procAttached) {
-        mPendingStarts.remove(expectedStartSeq);
-        final String reason = isProcStartValidLocked(app, expectedStartSeq);
-        if (reason != null) {
-            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + pid
-                    + ", " + reason);
-            app.pendingStart = false;
-            Process.killProcessQuiet(pid);
-            Process.killProcessGroup(app.uid, app.pid);
-            return false;
-        }
-        mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
-        checkTime(app.startTime, "startProcess: done updating battery stats");
-
-        EventLog.writeEvent(EventLogTags.AM_PROC_START,
-                UserHandle.getUserId(app.startUid), pid, app.startUid,
-                app.processName, app.hostingType,
-                app.hostingNameStr != null ? app.hostingNameStr : "");
-
-        try {
-            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
-                    app.seInfo, app.info.sourceDir, pid);
-        } catch (RemoteException ex) {
-            // Ignore
-        }
-
-        if (app.isPersistent()) {
-            Watchdog.getInstance().processStarted(app.processName, pid);
-        }
-
-        checkTime(app.startTime, "startProcess: building log message");
-        StringBuilder buf = mStringBuilder;
-        buf.setLength(0);
-        buf.append("Start proc ");
-        buf.append(pid);
-        buf.append(':');
-        buf.append(app.processName);
-        buf.append('/');
-        UserHandle.formatUid(buf, app.startUid);
-        if (app.isolatedEntryPoint != null) {
-            buf.append(" [");
-            buf.append(app.isolatedEntryPoint);
-            buf.append("]");
-        }
-        buf.append(" for ");
-        buf.append(app.hostingType);
-        if (app.hostingNameStr != null) {
-            buf.append(" ");
-            buf.append(app.hostingNameStr);
-        }
-        reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
-        app.setPid(pid);
-        app.setUsingWrapper(usingWrapper);
-        app.pendingStart = false;
-        checkTime(app.startTime, "startProcess: starting to update pids map");
-        ProcessRecord oldApp;
-        synchronized (mPidsSelfLocked) {
-            oldApp = mPidsSelfLocked.get(pid);
-        }
-        // If there is already an app occupying that pid that hasn't been cleaned up
-        if (oldApp != null && !app.isolated) {
-            // Clean up anything relating to this pid first
-            Slog.w(TAG, "Reusing pid " + pid
-                    + " while app is still mapped to it");
-            cleanUpApplicationRecordLocked(oldApp, false, false, -1,
-                    true /*replacingPid*/);
-        }
-        synchronized (mPidsSelfLocked) {
-            this.mPidsSelfLocked.put(pid, app);
-            if (!procAttached) {
-                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
-                msg.obj = app;
-                mHandler.sendMessageDelayed(msg, usingWrapper
-                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
-            }
-        }
-        checkTime(app.startTime, "startProcess: done updating pids map");
-        return true;
-    }
-
     void updateUsageStats(ComponentName activity, int uid, int userId, boolean resumed) {
         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
                 "updateUsageStats: comp=" + activity + "res=" + resumed);
@@ -3714,81 +2670,6 @@
         }
     }
 
-    Intent getHomeIntent() {
-        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
-        intent.setComponent(mTopComponent);
-        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
-        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
-            intent.addCategory(Intent.CATEGORY_HOME);
-        }
-        return intent;
-    }
-
-    boolean startHomeActivityLocked(int userId, String reason) {
-        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
-                && mTopAction == null) {
-            // We are running in factory test mode, but unable to find
-            // the factory test app, so just sit around displaying the
-            // error message and don't try to start anything.
-            return false;
-        }
-        Intent intent = getHomeIntent();
-        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
-        if (aInfo != null) {
-            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
-            // Don't do this if the home app is currently being
-            // instrumented.
-            aInfo = new ActivityInfo(aInfo);
-            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
-            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
-                    aInfo.applicationInfo.uid, true);
-            if (app == null || app.getActiveInstrumentation() == null) {
-                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
-                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
-                // For ANR debugging to verify if the user activity is the one that actually
-                // launched.
-                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
-                mActivityTaskManager.getActivityStartController().startHomeActivity(intent, aInfo, myReason);
-            }
-        } else {
-            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
-        }
-
-        return true;
-    }
-
-    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
-        ActivityInfo ai = null;
-        ComponentName comp = intent.getComponent();
-        try {
-            if (comp != null) {
-                // Factory test.
-                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
-            } else {
-                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
-                        intent,
-                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                        flags, userId);
-
-                if (info != null) {
-                    ai = info.activityInfo;
-                }
-            }
-        } catch (RemoteException e) {
-            // ignore
-        }
-
-        return ai;
-    }
-
-    boolean getCheckedForSetup() {
-        return mCheckedForSetup;
-    }
-
-    void setCheckedForSetup(boolean checked) {
-        mCheckedForSetup = checked;
-    }
-
     CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
         return mAtmInternal.compatibilityInfoForPackage(ai);
     }
@@ -3821,10 +2702,10 @@
                     "getPackageProcessState");
         }
 
-        int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
+        int procState = PROCESS_STATE_NONEXISTENT;
         synchronized (this) {
-            for (int i=mLruProcesses.size()-1; i>=0; i--) {
-                final ProcessRecord proc = mLruProcesses.get(i);
+            for (int i=mProcessList.mLruProcesses.size()-1; i>=0; i--) {
+                final ProcessRecord proc = mProcessList.mLruProcesses.get(i);
                 if (procState > proc.setProcState) {
                     if (proc.pkgList.containsKey(packageName) ||
                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
@@ -3852,7 +2733,7 @@
                         "Unable to set a higher trim level than current level");
             }
             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
-                    app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
+                    app.getCurProcState() > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
                 throw new IllegalArgumentException("Unable to set a background trim level "
                     + "on a foreground process");
             }
@@ -3957,7 +2838,7 @@
                 } else {
                     UidRecord validateUid = mValidateUids.get(item.uid);
                     if (validateUid == null) {
-                        validateUid = new UidRecord(item.uid);
+                        validateUid = new UidRecord(item.uid, mAtmInternal);
                         mValidateUids.put(item.uid, validateUid);
                     }
                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
@@ -3965,7 +2846,7 @@
                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
                         validateUid.idle = false;
                     }
-                    validateUid.curProcState = validateUid.setProcState = item.processState;
+                    validateUid.setCurProcState(validateUid.setProcState = item.processState);
                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
                 }
             }
@@ -4041,8 +2922,7 @@
                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
                                 doReport = lastAboveCut != newAboveCut;
                             } else {
-                                doReport = item.processState
-                                        != ActivityManager.PROCESS_STATE_NONEXISTENT;
+                                doReport = item.processState != PROCESS_STATE_NONEXISTENT;
                             }
                         }
                         if (doReport) {
@@ -4118,9 +2998,35 @@
     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
-        return mActivityTaskManager.startActivityAsUser(caller, callingPackage, intent,
-                resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
-                userId);
+        synchronized (this) {
+            /**
+             * Flags like {@link android.app.ActivityManager#START_FLAG_DEBUG} maybe be set on this
+             * call when called/invoked from the shell command. To avoid deadlock, we go ahead and
+             * acquire the AMS lock now since ATMS will need to synchronously call back into AMS
+             * later to modify process settings due to the flags.
+             * TODO(b/80414790): Investigate a better way of untangling this.
+             */
+            return mActivityTaskManager.startActivityAsUser(caller, callingPackage, intent,
+                    resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,
+                    bOptions, userId);
+        }
+    }
+
+    WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
+            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
+            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
+        synchronized (this) {
+            /**
+             * Flags like {@link android.app.ActivityManager#START_FLAG_DEBUG} maybe be set on this
+             * call when called/invoked from the shell command. To avoid deadlock, we go ahead and
+             * acquire the AMS lock now since ATMS will need to synchronously call back into AMS
+             * later to modify process settings due to the flags.
+             * TODO(b/80414790): Investigate a better way of untangling this.
+             */
+            return mActivityTaskManager.startActivityAndWait(caller, callingPackage, intent,
+                    resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo,
+                    bOptions, userId);
+        }
     }
 
     @Override
@@ -4199,7 +3105,7 @@
      * to the process.
      */
     @GuardedBy("this")
-    private final void handleAppDiedLocked(ProcessRecord app,
+    final void handleAppDiedLocked(ProcessRecord app,
             boolean restarting, boolean allowRestart) {
         int pid = app.pid;
         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
@@ -4215,45 +3121,13 @@
             clearProfilerLocked();
         }
 
-        // Remove this application's activities from active lists.
-        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app.getWindowProcessController());
-
-        app.clearRecentTasks();
-        app.clearActivities();
-
-        if (app.getActiveInstrumentation() != null) {
+        mAtmInternal.handleAppDied(app.getWindowProcessController(), restarting, () -> {
             Slog.w(TAG, "Crash of app " + app.processName
-                  + " running instrumentation " + app.getActiveInstrumentation().mClass);
+                    + " running instrumentation " + app.getActiveInstrumentation().mClass);
             Bundle info = new Bundle();
             info.putString("shortMsg", "Process crashed.");
             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
-        }
-
-        mWindowManager.deferSurfaceLayout();
-        try {
-            if (!restarting && hasVisibleActivities
-                    && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
-                // If there was nothing to resume, and we are not already restarting this process, but
-                // there is a visible activity that is hosted by the process...  then make sure all
-                // visible activities are running, taking care of restarting this process.
-                mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
-            }
-        } finally {
-            mWindowManager.continueSurfaceLayout();
-        }
-
-    }
-
-    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
-        final IBinder threadBinder = thread.asBinder();
-        // Find the application record.
-        for (int i=mLruProcesses.size()-1; i>=0; i--) {
-            final ProcessRecord rec = mLruProcesses.get(i);
-            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
-                return i;
-            }
-        }
-        return -1;
+        });
     }
 
     ProcessRecord getRecordForAppLocked(IApplicationThread thread) {
@@ -4261,15 +3135,14 @@
             return null;
         }
 
-        int appIndex = getLRURecordIndexForAppLocked(thread);
-        if (appIndex >= 0) {
-            return mLruProcesses.get(appIndex);
-        }
+        ProcessRecord record = mProcessList.getLRURecordForAppLocked(thread);
+        if (record != null) return record;
 
         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
         // double-check that.
         final IBinder threadBinder = thread.asBinder();
-        final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
+        final ArrayMap<String, SparseArray<ProcessRecord>> pmap =
+                mProcessList.mProcessNames.getMap();
         for (int i = pmap.size()-1; i >= 0; i--) {
             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
             for (int j = procs.size()-1; j >= 0; j--) {
@@ -4289,17 +3162,7 @@
         // If there are no longer any background processes running,
         // and the app that died was not running instrumentation,
         // then tell everyone we are now low on memory.
-        boolean haveBg = false;
-        for (int i=mLruProcesses.size()-1; i>=0; i--) {
-            ProcessRecord rec = mLruProcesses.get(i);
-            if (rec.thread != null
-                    && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
-                haveBg = true;
-                break;
-            }
-        }
-
-        if (!haveBg) {
+        if (!mProcessList.haveBackgroundProcessLocked()) {
             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
             if (doReport) {
                 long now = SystemClock.uptimeMillis();
@@ -4310,11 +3173,12 @@
                 }
             }
             final ArrayList<ProcessMemInfo> memInfos
-                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
-            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
+                    = doReport ? new ArrayList<ProcessMemInfo>(mProcessList.getLruSizeLocked())
+                    : null;
+            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mProcessList.getLruSizeLocked());
             long now = SystemClock.uptimeMillis();
-            for (int i=mLruProcesses.size()-1; i>=0; i--) {
-                ProcessRecord rec = mLruProcesses.get(i);
+            for (int i = mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
+                ProcessRecord rec = mProcessList.mLruProcesses.get(i);
                 if (rec == dyingProc || rec.thread == null) {
                     continue;
                 }
@@ -4371,7 +3235,7 @@
             if (!fromBinderDied) {
                 killProcessQuiet(pid);
             }
-            killProcessGroup(app.uid, pid);
+            ProcessList.killProcessGroup(app.uid, pid);
             app.killed = true;
         }
 
@@ -4790,7 +3654,7 @@
                     return;
                 }
                 synchronized (this) {
-                    killPackageProcessesLocked(packageName, appId, targetUserId,
+                    mProcessList.killPackageProcessesLocked(packageName, appId, targetUserId,
                             ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
                 }
             }
@@ -4813,30 +3677,7 @@
         final long callingId = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                final ArrayList<ProcessRecord> procs = new ArrayList<>();
-                final int NP = mProcessNames.getMap().size();
-                for (int ip = 0; ip < NP; ip++) {
-                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
-                    final int NA = apps.size();
-                    for (int ia = 0; ia < NA; ia++) {
-                        final ProcessRecord app = apps.valueAt(ia);
-                        if (app.isPersistent()) {
-                            // We don't kill persistent processes.
-                            continue;
-                        }
-                        if (app.removed) {
-                            procs.add(app);
-                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
-                            app.removed = true;
-                            procs.add(app);
-                        }
-                    }
-                }
-
-                final int N = procs.size();
-                for (int i = 0; i < N; i++) {
-                    removeProcessLocked(procs.get(i), false, true, "kill all background");
-                }
+                mProcessList.killAllBackgroundProcessesLocked();
 
                 mAllowLowerMemLevel = true;
 
@@ -4870,27 +3711,7 @@
         final long callingId = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                final ArrayList<ProcessRecord> procs = new ArrayList<>();
-                final int NP = mProcessNames.getMap().size();
-                for (int ip = 0; ip < NP; ip++) {
-                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
-                    final int NA = apps.size();
-                    for (int ia = 0; ia < NA; ia++) {
-                        final ProcessRecord app = apps.valueAt(ia);
-                        if (app.removed) {
-                            procs.add(app);
-                        } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
-                                && (maxProcState < 0 || app.setProcState > maxProcState)) {
-                            app.removed = true;
-                            procs.add(app);
-                        }
-                    }
-                }
-
-                final int N = procs.size();
-                for (int i = 0; i < N; i++) {
-                    removeProcessLocked(procs.get(i), false, true, "kill all background except");
-                }
+                mProcessList.killAllBackgroundProcessesExceptLocked(minTargetSdk, maxProcState);
             }
         } finally {
             Binder.restoreCallingIdentity(callingId);
@@ -5007,48 +3828,7 @@
 
     @Override
     public void closeSystemDialogs(String reason) {
-        enforceNotIsolatedCaller("closeSystemDialogs");
-
-        final int pid = Binder.getCallingPid();
-        final int uid = Binder.getCallingUid();
-        final long origId = Binder.clearCallingIdentity();
-        try {
-            synchronized (this) {
-                // Only allow this from foreground processes, so that background
-                // applications can't abuse it to prevent system UI from being shown.
-                if (uid >= FIRST_APPLICATION_UID) {
-                    ProcessRecord proc;
-                    synchronized (mPidsSelfLocked) {
-                        proc = mPidsSelfLocked.get(pid);
-                    }
-                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
-                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
-                                + " from background process " + proc);
-                        return;
-                    }
-                }
-                closeSystemDialogsLocked(reason);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(origId);
-        }
-    }
-
-    @GuardedBy("this")
-    void closeSystemDialogsLocked(String reason) {
-        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
-                | Intent.FLAG_RECEIVER_FOREGROUND);
-        if (reason != null) {
-            intent.putExtra("reason", reason);
-        }
-        mWindowManager.closeSystemDialogs(reason);
-
-        mStackSupervisor.closeSystemDialogsLocked();
-
-        broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
-                OP_NONE, null, false, false,
-                -1, SYSTEM_UID, UserHandle.USER_ALL);
+        mAtmInternal.closeSystemDialogs(reason);
     }
 
     @Override
@@ -5229,81 +4009,6 @@
                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
     }
 
-
-    @GuardedBy("this")
-    private final boolean killPackageProcessesLocked(String packageName, int appId,
-            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
-            boolean doit, boolean evenPersistent, String reason) {
-        ArrayList<ProcessRecord> procs = new ArrayList<>();
-
-        // Remove all processes this package may have touched: all with the
-        // same UID (except for the system or root user), and all whose name
-        // matches the package name.
-        final int NP = mProcessNames.getMap().size();
-        for (int ip=0; ip<NP; ip++) {
-            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
-            final int NA = apps.size();
-            for (int ia=0; ia<NA; ia++) {
-                ProcessRecord app = apps.valueAt(ia);
-                if (app.isPersistent() && !evenPersistent) {
-                    // we don't kill persistent processes
-                    continue;
-                }
-                if (app.removed) {
-                    if (doit) {
-                        procs.add(app);
-                    }
-                    continue;
-                }
-
-                // Skip process if it doesn't meet our oom adj requirement.
-                if (app.setAdj < minOomAdj) {
-                    continue;
-                }
-
-                // If no package is specified, we call all processes under the
-                // give user id.
-                if (packageName == null) {
-                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
-                        continue;
-                    }
-                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
-                        continue;
-                    }
-                // Package has been specified, we want to hit all processes
-                // that match it.  We need to qualify this by the processes
-                // that are running under the specified app and user ID.
-                } else {
-                    final boolean isDep = app.pkgDeps != null
-                            && app.pkgDeps.contains(packageName);
-                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
-                        continue;
-                    }
-                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
-                        continue;
-                    }
-                    if (!app.pkgList.containsKey(packageName) && !isDep) {
-                        continue;
-                    }
-                }
-
-                // Process has passed all conditions, kill it!
-                if (!doit) {
-                    return true;
-                }
-                app.removed = true;
-                procs.add(app);
-            }
-        }
-
-        int N = procs.size();
-        for (int i=0; i<N; i++) {
-            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
-        }
-        updateOomAdjLocked();
-        return N > 0;
-    }
-
     private void cleanupDisabledPackageComponentsLocked(
             String packageName, int userId, boolean killProcess, String[] changedClasses) {
 
@@ -5363,15 +4068,8 @@
             return;
         }
 
-        // Clean-up disabled activities.
-        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
-                packageName, disabledClasses, true, false, userId) && mBooted) {
-            mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
-            mStackSupervisor.scheduleIdleLocked();
-        }
-
-        // Clean-up disabled tasks
-        mActivityTaskManager.getRecentTasks().cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
+        mAtmInternal.cleanupDisabledPackageComponents(
+                packageName, disabledClasses, userId, mBooted);
 
         // Clean-up disabled services.
         mServices.bringDownDisabledPackageServicesLocked(
@@ -5431,19 +4129,12 @@
             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
         }
 
-        boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
+        boolean didSomething = mProcessList.killPackageProcessesLocked(packageName, appId, userId,
                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
 
-        didSomething |= mActivityTaskManager.getActivityStartController().clearPendingActivityLaunches(packageName);
-
-        if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
-                packageName, null, doit, evenPersistent, userId)) {
-            if (!doit) {
-                return true;
-            }
-            didSomething = true;
-        }
+        didSomething |=
+                mAtmInternal.onForceStopPackage(packageName, doit, evenPersistent, userId);
 
         if (mServices.bringDownDisabledPackageServicesLocked(
                 packageName, null, userId, evenPersistent, true, doit)) {
@@ -5493,136 +4184,17 @@
                 }
             }
             if (mBooted) {
-                mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
-                mStackSupervisor.scheduleIdleLocked();
+                mAtmInternal.resumeTopActivities(true /* scheduleIdle */);
             }
         }
 
         return didSomething;
     }
 
-    private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
-        return removeProcessNameLocked(name, uid, null);
-    }
-
-    private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
-            final ProcessRecord expecting) {
-        ProcessRecord old = mProcessNames.get(name, uid);
-        // Only actually remove when the currently recorded value matches the
-        // record that we expected; if it doesn't match then we raced with a
-        // newly created process and we don't want to destroy the new one.
-        if ((expecting == null) || (old == expecting)) {
-            mProcessNames.remove(name, uid);
-        }
-        if (old != null && old.uidRecord != null) {
-            old.uidRecord.numProcs--;
-            if (old.uidRecord.numProcs == 0) {
-                // No more processes using this uid, tell clients it is gone.
-                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
-                        "No more processes in " + old.uidRecord);
-                enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
-                EventLogTags.writeAmUidStopped(uid);
-                mActiveUids.remove(uid);
-                noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
-            }
-            old.uidRecord = null;
-        }
-        mIsolatedProcesses.remove(uid);
-        return old;
-    }
-
-    private final void addProcessNameLocked(ProcessRecord proc) {
-        // We shouldn't already have a process under this name, but just in case we
-        // need to clean up whatever may be there now.
-        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
-        if (old == proc && proc.isPersistent()) {
-            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
-            Slog.w(TAG, "Re-adding persistent process " + proc);
-        } else if (old != null) {
-            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
-        }
-        UidRecord uidRec = mActiveUids.get(proc.uid);
-        if (uidRec == null) {
-            uidRec = new UidRecord(proc.uid);
-            // This is the first appearance of the uid, report it now!
-            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
-                    "Creating new process uid: " + uidRec);
-            if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
-                    || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
-                uidRec.setWhitelist = uidRec.curWhitelist = true;
-            }
-            uidRec.updateHasInternetPermission();
-            mActiveUids.put(proc.uid, uidRec);
-            EventLogTags.writeAmUidRunning(uidRec.uid);
-            noteUidProcessState(uidRec.uid, uidRec.curProcState);
-        }
-        proc.uidRecord = uidRec;
-
-        // Reset render thread tid if it was already set, so new process can set it again.
-        proc.renderThreadTid = 0;
-        uidRec.numProcs++;
-        mProcessNames.put(proc.processName, proc.uid, proc);
-        if (proc.isolated) {
-            mIsolatedProcesses.put(proc.uid, proc);
-        }
-    }
-
-    @GuardedBy("this")
-    boolean removeProcessLocked(ProcessRecord app,
-            boolean callerWillRestart, boolean allowRestart, String reason) {
-        final String name = app.processName;
-        final int uid = app.uid;
-        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
-            "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
-
-        ProcessRecord old = mProcessNames.get(name, uid);
-        if (old != app) {
-            // This process is no longer active, so nothing to do.
-            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
-            return false;
-        }
-        removeProcessNameLocked(name, uid);
-        mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
-
-        boolean needRestart = false;
-        if ((app.pid > 0 && app.pid != MY_PID) || (app.pid == 0 && app.pendingStart)) {
-            int pid = app.pid;
-            if (pid > 0) {
-                synchronized (mPidsSelfLocked) {
-                    mPidsSelfLocked.remove(pid);
-                    mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
-                }
-                mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
-                if (app.isolated) {
-                    mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
-                    getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
-                }
-            }
-            boolean willRestart = false;
-            if (app.isPersistent() && !app.isolated) {
-                if (!callerWillRestart) {
-                    willRestart = true;
-                } else {
-                    needRestart = true;
-                }
-            }
-            app.kill(reason, true);
-            handleAppDiedLocked(app, willRestart, allowRestart);
-            if (willRestart) {
-                removeLruProcessLocked(app);
-                addAppLocked(app.info, null, false, null /* ABI override */);
-            }
-        } else {
-            mRemovedProcesses.add(app);
-        }
-
-        return needRestart;
-    }
-
     @GuardedBy("this")
     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
         cleanupAppInLaunchingProvidersLocked(app, true);
-        removeProcessLocked(app, false, true, "timeout publishing content providers");
+        mProcessList.removeProcessLocked(app, false, true, "timeout publishing content providers");
     }
 
     private final void processStartTimedOutLocked(ProcessRecord app) {
@@ -5640,7 +4212,7 @@
             Slog.w(TAG, "Process " + app + " failed to attach");
             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
                     pid, app.uid, app.processName);
-            removeProcessNameLocked(app.processName, app.uid);
+            mProcessList.removeProcessNameLocked(app.processName, app.uid);
             mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
             // Take care of any launching providers waiting for this process.
@@ -5696,9 +4268,10 @@
         // It's possible that process called attachApplication before we got a chance to
         // update the internal state.
         if (app == null && startSeq > 0) {
-            final ProcessRecord pending = mPendingStarts.get(startSeq);
+            final ProcessRecord pending = mProcessList.mPendingStarts.get(startSeq);
             if (pending != null && pending.startUid == callingUid
-                    && handleProcessStartedLocked(pending, pid, pending.isUsingWrapper(),
+                    && mProcessList.handleProcessStartedLocked(pending, pid, pending
+                            .isUsingWrapper(),
                             startSeq, true)) {
                 app = pending;
             }
@@ -5740,7 +4313,7 @@
             app.deathRecipient = adr;
         } catch (RemoteException e) {
             app.resetPackageList(mProcessStats);
-            startProcessLocked(app, "link fail", processName);
+            mProcessList.startProcessLocked(app, "link fail", processName);
             return false;
         }
 
@@ -5918,7 +4491,7 @@
             }
 
             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
-            mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(app);
+            mAtmInternal.preBindApplication(app.getWindowProcessController());
             final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
             if (app.isolatedEntryPoint != null) {
                 // This is an isolated process which should just call an entry point instead of
@@ -5951,7 +4524,7 @@
                 profilerInfo = null;
             }
             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
-            updateLruProcessLocked(app, false, null);
+            mProcessList.updateLruProcessLocked(app, false, null);
             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
         } catch (Exception e) {
@@ -5962,7 +4535,7 @@
 
             app.resetPackageList(mProcessStats);
             app.unlinkDeathRecipient();
-            startProcessLocked(app, "bind fail", processName);
+            mProcessList.startProcessLocked(app, "bind fail", processName);
             return false;
         }
 
@@ -5978,9 +4551,7 @@
         // See if the top visible activity is waiting to run in this process...
         if (normalMode) {
             try {
-                if (mStackSupervisor.attachApplicationLocked(app)) {
-                    didSomething = true;
-                }
+                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
             } catch (Exception e) {
                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                 badApp = true;
@@ -6137,7 +4708,7 @@
                 for (int ip=0; ip<NP; ip++) {
                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
                             + procs.get(ip));
-                    startProcessLocked(procs.get(ip), "on-hold", null);
+                    mProcessList.startProcessLocked(procs.get(ip), "on-hold", null);
                 }
             }
             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
@@ -6569,7 +5140,7 @@
             if (uidRec == null || uidRec.idle) {
                 return false;
             }
-            return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+            return uidRec.getCurProcState() <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
         }
     }
 
@@ -6583,7 +5154,7 @@
 
     int getUidStateLocked(int uid) {
         UidRecord uidRec = mActiveUids.get(uid);
-        return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
+        return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState();
     }
 
     // =========================================================
@@ -6637,8 +5208,7 @@
         synchronized (mPidsSelfLocked) {
             for (int i = 0; i < pids.length; i++) {
                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
-                states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
-                        pr.curProcState;
+                states[i] = (pr == null) ? PROCESS_STATE_NONEXISTENT : pr.getCurProcState();
                 if (scores != null) {
                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
                 }
@@ -6712,7 +5282,7 @@
         }
     }
 
-    static int checkComponentPermission(String permission, int pid, int uid,
+    public static int checkComponentPermission(String permission, int pid, int uid,
             int owningUid, boolean exported) {
         if (pid == MY_PID) {
             return PackageManager.PERMISSION_GRANTED;
@@ -6922,7 +5492,7 @@
                             proc = mPidsSelfLocked.get(callingPid);
                         }
                         if (proc != null &&
-                                !ActivityManager.isProcStateBackground(proc.curProcState)) {
+                                !ActivityManager.isProcStateBackground(proc.getCurProcState())) {
                             // Whoever is instigating this is in the foreground, so we will allow it
                             // to go through.
                             return ActivityManager.APP_START_MODE_NORMAL;
@@ -6959,11 +5529,6 @@
         return ptw != null ? ptw.tag : null;
     }
 
-    @VisibleForTesting
-    boolean isActivityStartsLoggingEnabled() {
-        return mConstants.mFlagActivityStartsLoggingEnabled;
-    }
-
     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
         ProviderInfo pi = null;
         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
@@ -7099,19 +5664,7 @@
 
     @Override
     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
-        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
-        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
-        outInfo.availMem = getFreeMemory();
-        outInfo.totalMem = getTotalMemory();
-        outInfo.threshold = homeAppMem;
-        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
-        outInfo.hiddenAppThreshold = cachedAppMem;
-        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
-                ProcessList.SERVICE_ADJ);
-        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
-                ProcessList.VISIBLE_APP_ADJ);
-        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
-                ProcessList.FOREGROUND_APP_ADJ);
+        mProcessList.getMemoryInfo(outInfo);
     }
 
     // =========================================================
@@ -7503,7 +6056,7 @@
             }
             cpr.connections.add(conn);
             r.conProviders.add(conn);
-            startAssociationLocked(r.uid, r.processName, r.curProcState,
+            startAssociationLocked(r.uid, r.processName, r.getCurProcState(),
                     cpr.uid, cpr.appInfo.longVersionCode, cpr.name, cpr.info.processName);
             return conn;
         }
@@ -7547,7 +6100,7 @@
         return false;
     }
 
-    private void checkTime(long startTime, String where) {
+    void checkTime(long startTime, String where) {
         long now = SystemClock.uptimeMillis();
         if ((now-startTime) > 50) {
             // If we are taking more than 50ms, log about it.
@@ -7589,6 +6142,7 @@
         ContentProviderRecord cpr;
         ContentProviderConnection conn = null;
         ProviderInfo cpi = null;
+        boolean providerRunning = false;
 
         synchronized(this) {
             long startTime = SystemClock.uptimeMillis();
@@ -7628,8 +6182,6 @@
                 }
             }
 
-            boolean providerRunning = false;
-
             if (cpr != null && cpr.proc != null) {
                 providerRunning = !cpr.proc.killed;
 
@@ -7640,7 +6192,12 @@
                 // how to test this case.)
                 if (cpr.proc.killed && cpr.proc.killedByAm) {
                     checkTime(startTime, "getContentProviderImpl: before appDied (killedByAm)");
-                    appDiedLocked(cpr.proc);
+                    final long iden = Binder.clearCallingIdentity();
+                    try {
+                        appDiedLocked(cpr.proc);
+                    } finally {
+                        Binder.restoreCallingIdentity(iden);
+                    }
                     checkTime(startTime, "getContentProviderImpl: after appDied (killedByAm)");
                 }
             }
@@ -7702,7 +6259,7 @@
                         // back up on the LRU list.  This is good because
                         // content providers are often expensive to start.
                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
-                        updateLruProcessLocked(cpr.proc, false, null);
+                        mProcessList.updateLruProcessLocked(cpr.proc, false, null);
                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
                     }
                 }
@@ -7949,6 +6506,7 @@
         }
 
         // Wait for the provider to be published...
+        final long timeout = SystemClock.uptimeMillis() + CONTENT_PROVIDER_WAIT_TIMEOUT;
         synchronized (cpr) {
             while (cpr.provider == null) {
                 if (cpr.launchingApp == null) {
@@ -7963,13 +6521,22 @@
                     return null;
                 }
                 try {
+                    final long wait = Math.max(0L, timeout - SystemClock.uptimeMillis());
                     if (DEBUG_MU) Slog.v(TAG_MU,
                             "Waiting to start provider " + cpr
-                            + " launchingApp=" + cpr.launchingApp);
+                            + " launchingApp=" + cpr.launchingApp + " for " + wait + " ms");
                     if (conn != null) {
                         conn.waiting = true;
                     }
-                    cpr.wait();
+                    cpr.wait(wait);
+                    if (cpr.provider == null) {
+                        Slog.wtf(TAG, "Timeout waiting for provider "
+                                + cpi.applicationInfo.packageName + "/"
+                                + cpi.applicationInfo.uid + " for provider "
+                                + name
+                                + " providerRunning=" + providerRunning);
+                        return null;
+                    }
                 } catch (InterruptedException ex) {
                 } finally {
                     if (conn != null) {
@@ -8329,8 +6896,8 @@
         mHandler.post(new Runnable() {
             @Override
             public void run() {
-                mAppErrors.appNotResponding(host, null, null, false,
-                        "ContentProvider not responding");
+                host.appNotResponding(
+                        null, null, null, null, false, "ContentProvider not responding");
             }
         });
     }
@@ -8338,7 +6905,7 @@
     public final void installSystemProviders() {
         List<ProviderInfo> providers;
         synchronized (this) {
-            ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
+            ProcessRecord app = mProcessList.mProcessNames.get("system", SYSTEM_UID);
             providers = generateApplicationProvidersLocked(app);
             if (providers != null) {
                 for (int i=providers.size()-1; i>=0; i--) {
@@ -8400,9 +6967,10 @@
         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
 
         synchronized (this) {
-            final int NP = mProcessNames.getMap().size();
+            final int NP = mProcessList.mProcessNames.getMap().size();
             for (int ip = 0; ip < NP; ip++) {
-                final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
+                final SparseArray<ProcessRecord> apps = mProcessList.mProcessNames.getMap().valueAt
+                        (ip);
                 final int NA = apps.size();
                 for (int ia = 0; ia < NA; ia++) {
                     final ProcessRecord app = apps.valueAt(ia);
@@ -8508,67 +7076,6 @@
     // GLOBAL MANAGEMENT
     // =========================================================
 
-    @GuardedBy("this")
-    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
-            boolean isolated, int isolatedUid) {
-        String proc = customProcess != null ? customProcess : info.processName;
-        final int userId = UserHandle.getUserId(info.uid);
-        int uid = info.uid;
-        if (isolated) {
-            if (isolatedUid == 0) {
-                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
-                while (true) {
-                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
-                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
-                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
-                    }
-                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
-                    mNextIsolatedProcessUid++;
-                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
-                        // No process for this uid, use it.
-                        break;
-                    }
-                    stepsLeft--;
-                    if (stepsLeft <= 0) {
-                        return null;
-                    }
-                }
-            } else {
-                // Special case for startIsolatedProcess (internal only), where
-                // the uid of the isolated process is specified by the caller.
-                uid = isolatedUid;
-            }
-            getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
-
-            // Register the isolated UID with this application so BatteryStats knows to
-            // attribute resource usage to the application.
-            //
-            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
-            // about the process state of the isolated UID *before* it is registered with the
-            // owning application.
-            mBatteryStatsService.addIsolatedUid(uid, info.uid);
-            StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
-                    StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
-        }
-        final ProcessRecord r = new ProcessRecord(this, info, proc, uid, getGlobalConfiguration());
-        if (!mBooted && !mBooting
-                && userId == UserHandle.USER_SYSTEM
-                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
-            // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
-            r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
-            r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
-            r.setPersistent(true);
-            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
-        }
-        if (isolated && isolatedUid != 0) {
-            // Special case for startIsolatedProcess (internal only) - assume the process
-            // is required by the system server to prevent it being killed.
-            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
-        }
-        addProcessNameLocked(r);
-        return r;
-    }
-
     private boolean uidOnBackgroundWhitelist(final int uid) {
         final int appId = UserHandle.getAppId(uid);
         final int[] whitelist = mBackgroundAppIdWhitelist;
@@ -8626,12 +7133,13 @@
     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
             String abiOverride) {
         return addAppLocked(info, customProcess, isolated, false /* disableHiddenApiChecks */,
-                abiOverride);
+                false /* mountExtStorageFull */, abiOverride);
     }
 
+    // TODO: Move to ProcessList?
     @GuardedBy("this")
     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
-            boolean disableHiddenApiChecks, String abiOverride) {
+            boolean disableHiddenApiChecks, boolean mountExtStorageFull, String abiOverride) {
         ProcessRecord app;
         if (!isolated) {
             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
@@ -8641,8 +7149,8 @@
         }
 
         if (app == null) {
-            app = newProcessRecordLocked(info, customProcess, isolated, 0);
-            updateLruProcessLocked(app, false, null);
+            app = mProcessList.newProcessRecordLocked(info, customProcess, isolated, 0);
+            mProcessList.updateLruProcessLocked(app, false, null);
             updateOomAdjLocked();
         }
 
@@ -8662,9 +7170,9 @@
         }
         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
             mPersistentStartingProcesses.add(app);
-            startProcessLocked(app, "added application",
+            mProcessList.startProcessLocked(app, "added application",
                     customProcess != null ? customProcess : app.processName, disableHiddenApiChecks,
-                    abiOverride);
+                    mountExtStorageFull, abiOverride);
         }
 
         return app;
@@ -8779,51 +7287,12 @@
 
     @Override
     public void notifyLockedProfile(@UserIdInt int userId) {
-        try {
-            if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
-                throw new SecurityException("Only privileged app can call notifyLockedProfile");
-            }
-        } catch (RemoteException ex) {
-            throw new SecurityException("Fail to check is caller a privileged app", ex);
-        }
-
-        synchronized (this) {
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                if (mUserController.shouldConfirmCredentials(userId)) {
-                    if (mActivityTaskManager.mKeyguardController.isKeyguardLocked()) {
-                        // Showing launcher to avoid user entering credential twice.
-                        final int currentUserId = mUserController.getCurrentUserId();
-                        startHomeActivityLocked(currentUserId, "notifyLockedProfile");
-                    }
-                    mStackSupervisor.lockAllProfileTasks(userId);
-                }
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
+        mAtmInternal.notifyLockedProfile(userId, mUserController.getCurrentUserId());
     }
 
     @Override
     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
-        enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
-        synchronized (this) {
-            final long ident = Binder.clearCallingIdentity();
-            try {
-                intent.addFlags(FLAG_ACTIVITY_NEW_TASK |
-                        FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
-                        FLAG_ACTIVITY_TASK_ON_HOME);
-                ActivityOptions activityOptions = options != null
-                        ? new ActivityOptions(options)
-                        : ActivityOptions.makeBasic();
-                activityOptions.setLaunchTaskId(
-                        mStackSupervisor.getHomeActivity().getTask().taskId);
-                mContext.startActivityAsUser(intent, activityOptions.toBundle(),
-                        UserHandle.CURRENT);
-            } finally {
-                Binder.restoreCallingIdentity(ident);
-            }
-        }
+        mAtmInternal.startConfirmDeviceCredentialIntent(intent, options);
     }
 
     @Override
@@ -9147,7 +7616,7 @@
 
         synchronized (this) {
             UidRecord uidRec = mActiveUids.get(uid);
-            return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
+            return uidRec != null ? uidRec.getCurProcState() : PROCESS_STATE_NONEXISTENT;
         }
     }
 
@@ -9333,11 +7802,11 @@
                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
                         return;
                     }
-                    if (pr.hasTopUi != hasTopUi) {
+                    if (pr.hasTopUi() != hasTopUi) {
                         if (DEBUG_OOM_ADJ) {
                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
                         }
-                        pr.hasTopUi = hasTopUi;
+                        pr.setHasTopUi(hasTopUi);
                         changed = true;
                     }
                 }
@@ -9565,7 +8034,7 @@
         synchronized (this) {
             final long identity = Binder.clearCallingIdentity();
             try {
-                killPackageProcessesLocked(null, appId, userId,
+                mProcessList.killPackageProcessesLocked(null, appId, userId,
                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
                         reason != null ? reason : "kill uid");
             } finally {
@@ -9709,14 +8178,20 @@
             // If at least 1/3 of our time since the last idle period has been spent
             // with RAM low, then we want to kill processes.
             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
+            // If the processes' memory has increased by more than 1% of the total memory,
+            // or 10 MB, whichever is greater, then the processes' are eligible to be killed.
+            final long totalMemoryInKb = getTotalMemory() / 1000;
+            final long memoryGrowthThreshold =
+                    Math.max(totalMemoryInKb / 100, MINIMUM_MEMORY_GROWTH_THRESHOLD);
 
-            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
-                ProcessRecord proc = mLruProcesses.get(i);
+            for (int i = mProcessList.mLruProcesses.size() - 1 ; i >= 0 ; i--) {
+                ProcessRecord proc = mProcessList.mLruProcesses.get(i);
                 if (proc.notCachedSinceIdle) {
                     if (proc.setProcState >= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
                         if (doKilling && proc.initialIdlePss != 0
-                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
+                                && proc.lastPss > ((proc.initialIdlePss * 3) / 2)
+                                && proc.lastPss > (proc.initialIdlePss + memoryGrowthThreshold)) {
                             sb = new StringBuilder(128);
                             sb.append("Kill");
                             sb.append(proc.processName);
@@ -9807,8 +8282,6 @@
                 return;
             }
 
-            mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
-                    PackageManager.FEATURE_CANT_SAVE_STATE);
             mLocalDeviceIdleController
                     = LocalServices.getService(DeviceIdleController.LocalService.class);
             mActivityTaskManager.onSystemReady();
@@ -9842,7 +8315,7 @@
                 for (int i=procsToKill.size()-1; i>=0; i--) {
                     ProcessRecord proc = procsToKill.get(i);
                     Slog.i(TAG, "Removing system update proc: " + proc);
-                    removeProcessLocked(proc, true, false, "system update done");
+                    mProcessList.removeProcessLocked(proc, true, false, "system update done");
                 }
             }
 
@@ -9853,44 +8326,9 @@
         }
 
         Slog.i(TAG, "System now ready");
-        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
-            SystemClock.uptimeMillis());
+        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, SystemClock.uptimeMillis());
 
-        synchronized(this) {
-            // Make sure we have no pre-ready processes sitting around.
-
-            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
-                ResolveInfo ri = mContext.getPackageManager()
-                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
-                                STOCK_PM_FLAGS);
-                CharSequence errorMsg = null;
-                if (ri != null) {
-                    ActivityInfo ai = ri.activityInfo;
-                    ApplicationInfo app = ai.applicationInfo;
-                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
-                        mTopAction = Intent.ACTION_FACTORY_TEST;
-                        mTopData = null;
-                        mTopComponent = new ComponentName(app.packageName,
-                                ai.name);
-                    } else {
-                        errorMsg = mContext.getResources().getText(
-                                com.android.internal.R.string.factorytest_not_system);
-                    }
-                } else {
-                    errorMsg = mContext.getResources().getText(
-                            com.android.internal.R.string.factorytest_no_action);
-                }
-                if (errorMsg != null) {
-                    mTopAction = null;
-                    mTopData = null;
-                    mTopComponent = null;
-                    Message msg = Message.obtain();
-                    msg.what = SHOW_FACTORY_ERROR_UI_MSG;
-                    msg.getData().putCharSequence("msg", errorMsg);
-                    mUiHandler.sendMessage(msg);
-                }
-            }
-        }
+        mAtmInternal.updateTopComponentForFactoryTest();
 
         retrieveSettings();
         final int currentUserId = mUserController.getCurrentUserId();
@@ -9936,7 +8374,7 @@
                     throw e.rethrowAsRuntimeException();
                 }
             }
-            startHomeActivityLocked(currentUserId, "systemReady");
+            mAtmInternal.startHomeActivity(currentUserId, "systemReady");
 
             mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
 
@@ -9968,7 +8406,7 @@
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
-            mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
+            mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
             mUserController.sendUserSwitchBroadcasts(-1, currentUserId);
 
             BinderInternal.nSetBinderProxyCountWatermarks(6000,5500);
@@ -10067,16 +8505,17 @@
                         : StatsLog.APP_CRASH_OCCURRED__FOREGROUND_STATE__UNKNOWN
         );
 
-        final int relaunchReason = r == null ? ActivityRecord.RELAUNCH_REASON_NONE
+        final int relaunchReason = r == null ? RELAUNCH_REASON_NONE
                         : r.getWindowProcessController().computeRelaunchReason();
-        final String relaunchReasonString = ActivityRecord.relaunchReasonToString(relaunchReason);
+        final String relaunchReasonString = relaunchReasonToString(relaunchReason);
         if (crashInfo.crashTag == null) {
             crashInfo.crashTag = relaunchReasonString;
         } else {
             crashInfo.crashTag = crashInfo.crashTag + " " + relaunchReasonString;
         }
 
-        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
+        addErrorToDropBox(
+                eventType, r, processName, null, null, null, null, null, null, crashInfo);
 
         mAppErrors.crashApplication(r, crashInfo);
     }
@@ -10248,7 +8687,7 @@
         StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
                 callingPid);
 
-        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
+        addErrorToDropBox("wtf", r, processName, null, null, null, tag, null, null, crashInfo);
 
         return r;
     }
@@ -10263,22 +8702,7 @@
         }
 
         synchronized (this) {
-            final int NP = mProcessNames.getMap().size();
-            for (int ip=0; ip<NP; ip++) {
-                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
-                final int NA = apps.size();
-                for (int ia=0; ia<NA; ia++) {
-                    ProcessRecord p = apps.valueAt(ia);
-                    if (p.thread != null && p.thread.asBinder() == app) {
-                        return p;
-                    }
-                }
-            }
-
-            Slog.w(TAG, "Can't find mystery application for " + reason
-                    + " from pid=" + Binder.getCallingPid()
-                    + " uid=" + Binder.getCallingUid() + ": " + app);
-            return null;
+            return mProcessList.findAppProcessLocked(app, reason);
         }
     }
 
@@ -10304,6 +8728,7 @@
         synchronized (this) {
             sb.append("Process: ").append(processName).append("\n");
             sb.append("PID: ").append(process.pid).append("\n");
+            sb.append("UID: ").append(process.uid).append("\n");
             int flags = process.info.flags;
             IPackageManager pm = AppGlobals.getPackageManager();
             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
@@ -10346,17 +8771,18 @@
      * Write a description of an error (crash, WTF, ANR) to the drop box.
      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
      * @param process which caused the error, null means the system server
-     * @param activity which triggered the error, null if unknown
-     * @param parent activity related to the error, null if unknown
+     * @param activityShortComponentName which triggered the error, null if unknown
+     * @param parentShortComponentName activity related to the error, null if unknown
+     * @param parentProcess parent process
      * @param subject line related to the error, null if absent
      * @param report in long form describing the error, null if absent
      * @param dataFile text file to include in the report, null if none
      * @param crashInfo giving an application stack trace, null if absent
      */
     public void addErrorToDropBox(String eventType,
-            ProcessRecord process, String processName, ActivityRecord activity,
-            ActivityRecord parent, String subject,
-            final String report, final File dataFile,
+            ProcessRecord process, String processName, String activityShortComponentName,
+            String parentShortComponentName, ProcessRecord parentProcess,
+            String subject, final String report, final File dataFile,
             final ApplicationErrorReport.CrashInfo crashInfo) {
         // NOTE -- this must never acquire the ActivityManagerService lock,
         // otherwise the watchdog may be prevented from resetting the system.
@@ -10386,14 +8812,16 @@
                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
                     .append("\n");
         }
-        if (activity != null) {
-            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
+        if (activityShortComponentName != null) {
+            sb.append("Activity: ").append(activityShortComponentName).append("\n");
         }
-        if (parent != null && parent.app != null && parent.app.getPid() != process.pid) {
-            sb.append("Parent-Process: ").append(parent.app.mName).append("\n");
-        }
-        if (parent != null && parent != activity) {
-            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
+        if (parentShortComponentName != null) {
+            if (parentProcess != null && parentProcess.pid != process.pid) {
+                sb.append("Parent-Process: ").append(parentProcess.processName).append("\n");
+            }
+            if (!parentShortComponentName.equals(activityShortComponentName)) {
+                sb.append("Parent-Activity: ").append(parentShortComponentName).append("\n");
+            }
         }
         if (subject != null) {
             sb.append("Subject: ").append(subject).append("\n");
@@ -10490,8 +8918,8 @@
         synchronized (this) {
 
             // iterate across all processes
-            for (int i=mLruProcesses.size()-1; i>=0; i--) {
-                ProcessRecord app = mLruProcesses.get(i);
+            for (int i=mProcessList.mLruProcesses.size()-1; i>=0; i--) {
+                ProcessRecord app = mProcessList.mLruProcesses.get(i);
                 if (!allUsers && app.userId != userId) {
                     continue;
                 }
@@ -10524,44 +8952,6 @@
         return errList;
     }
 
-    static int procStateToImportance(int procState, int memAdj,
-            ActivityManager.RunningAppProcessInfo currApp,
-            int clientTargetSdk) {
-        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
-                procState, clientTargetSdk);
-        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
-            currApp.lru = memAdj;
-        } else {
-            currApp.lru = 0;
-        }
-        return imp;
-    }
-
-    @GuardedBy("this")
-    private void fillInProcMemInfoLocked(ProcessRecord app,
-            ActivityManager.RunningAppProcessInfo outInfo,
-            int clientTargetSdk) {
-        outInfo.pid = app.pid;
-        outInfo.uid = app.info.uid;
-        if (mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
-            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
-        }
-        if (app.isPersistent()) {
-            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
-        }
-        if (app.hasActivities()) {
-            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
-        }
-        outInfo.lastTrimLevel = app.trimMemoryLevel;
-        int adj = app.curAdj;
-        int procState = app.curProcState;
-        outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
-        outInfo.importanceReasonCode = app.adjTypeCode;
-        outInfo.processState = app.curProcState;
-        outInfo.isFocused = (app == getTopAppLocked());
-        outInfo.lastActivityTime = app.lastActivityTime;
-    }
-
     @Override
     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
         enforceNotIsolatedCaller("getRunningAppProcesses");
@@ -10569,8 +8959,6 @@
         final int callingUid = Binder.getCallingUid();
         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
 
-        // Lazy instantiation of list
-        List<ActivityManager.RunningAppProcessInfo> runList = null;
         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
                 callingUid) == PackageManager.PERMISSION_GRANTED;
         final int userId = UserHandle.getUserId(callingUid);
@@ -10579,40 +8967,9 @@
 
         synchronized (this) {
             // Iterate across all processes
-            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
-                ProcessRecord app = mLruProcesses.get(i);
-                if ((!allUsers && app.userId != userId)
-                        || (!allUids && app.uid != callingUid)) {
-                    continue;
-                }
-                if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
-                    // Generate process state info for running application
-                    ActivityManager.RunningAppProcessInfo currApp =
-                        new ActivityManager.RunningAppProcessInfo(app.processName,
-                                app.pid, app.getPackageList());
-                    fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
-                    if (app.adjSource instanceof ProcessRecord) {
-                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
-                        currApp.importanceReasonImportance =
-                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
-                                        app.adjSourceProcState);
-                    } else if (app.adjSource instanceof ActivityRecord) {
-                        ActivityRecord r = (ActivityRecord)app.adjSource;
-                        if (r.app != null) currApp.importanceReasonPid = r.app.getPid();
-                    }
-                    if (app.adjTarget instanceof ComponentName) {
-                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
-                    }
-                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
-                    //        + " lru=" + currApp.lru);
-                    if (runList == null) {
-                        runList = new ArrayList<>();
-                    }
-                    runList.add(currApp);
-                }
-            }
+            return mProcessList.getRunningAppProcessesLocked(allUsers, userId, allUids,
+                    callingUid, clientTargetSdk);
         }
-        return runList;
     }
 
     @Override
@@ -10659,7 +9016,7 @@
                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
             }
             if (proc != null) {
-                fillInProcMemInfoLocked(proc, outState, clientTargetSdk);
+                mProcessList.fillInProcMemInfoLocked(proc, outState, clientTargetSdk);
             }
         }
     }
@@ -10744,24 +9101,26 @@
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            if (mActivityTaskManager.getRecentTasks() != null) {
-                mActivityTaskManager.getRecentTasks().dump(pw, dumpAll, dumpPackage);
-            }
+            mAtmInternal.dump(
+                    DUMP_RECENTS_CMD, fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
             pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            dumpLastANRLocked(pw);
+            mAtmInternal.dump(
+                    DUMP_LASTANR_CMD, fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
             pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            dumpActivityStarterLocked(pw, dumpPackage);
+            mAtmInternal.dump(
+                    DUMP_STARTER_CMD, fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
             pw.println();
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            dumpActivityContainersLocked(pw);
+            mAtmInternal.dump(
+                    DUMP_CONTAINERS_CMD, fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
             // Activities section is dumped as part of the Critical priority dump. Exclude the
             // section if priority is Normal.
             if (!dumpNormalPriority) {
@@ -10769,7 +9128,8 @@
                 if (dumpAll) {
                     pw.println("-------------------------------------------------------------------------------");
                 }
-                dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
+                mAtmInternal.dump(
+                        DUMP_ACTIVITIES_CMD, fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
             }
             if (mAssociations.size() > 0) {
                 pw.println();
@@ -10858,9 +9218,7 @@
 
             if ("activities".equals(cmd) || "a".equals(cmd)) {
                 // output proto is ActivityManagerServiceDumpActivitiesProto
-                synchronized (this) {
-                    writeActivitiesToProtoLocked(proto);
-                }
+                mAtmInternal.writeActivitiesToProto(proto);
             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
                 // output proto is ActivityManagerServiceDumpBroadcastsProto
                 synchronized (this) {
@@ -10899,7 +9257,7 @@
                 // default option, dump everything, output is ActivityManagerServiceProto
                 synchronized (this) {
                     long activityToken = proto.start(ActivityManagerServiceProto.ACTIVITIES);
-                    writeActivitiesToProtoLocked(proto);
+                    mAtmInternal.writeActivitiesToProto(proto);
                     proto.end(activityToken);
 
                     long broadcastToken = proto.start(ActivityManagerServiceProto.BROADCASTS);
@@ -10926,32 +9284,12 @@
         if (opti < args.length) {
             String cmd = args[opti];
             opti++;
-            if ("activities".equals(cmd) || "a".equals(cmd)) {
-                synchronized (this) {
-                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
-                }
-            } else if ("lastanr".equals(cmd)) {
-                synchronized (this) {
-                    dumpLastANRLocked(pw);
-                }
-            } else if ("lastanr-traces".equals(cmd)) {
-                synchronized (this) {
-                    dumpLastANRTracesLocked(pw);
-                }
-            } else if ("starter".equals(cmd)) {
-                synchronized (this) {
-                    dumpActivityStarterLocked(pw, dumpPackage);
-                }
-            } else if ("containers".equals(cmd)) {
-                synchronized (this) {
-                    dumpActivityContainersLocked(pw);
-                }
-            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
-                synchronized (this) {
-                    if (mActivityTaskManager.getRecentTasks() != null) {
-                        mActivityTaskManager.getRecentTasks().dump(pw, true /* dumpAll */, dumpPackage);
-                    }
-                }
+            if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)
+                    || DUMP_LASTANR_CMD.equals(cmd) || DUMP_LASTANR_TRACES_CMD.equals(cmd)
+                    || DUMP_STARTER_CMD.equals(cmd) || DUMP_CONTAINERS_CMD.equals(cmd)
+                    || DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
+                mAtmInternal.dump(
+                        cmd, fd, pw, args, opti, true /* dumpAll */, dumpClient, dumpPackage);
             } else if ("binder-proxies".equals(cmd)) {
                 if (opti >= args.length) {
                     dumpBinderProxies(pw);
@@ -11087,8 +9425,8 @@
                 LockGuard.dump(fd, pw, args);
             } else {
                 // Dumping a single activity?
-                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
-                        dumpFocusedStackOnly)) {
+                if (!mAtmInternal.dumpActivity(fd, pw, cmd, args, opti, dumpAll,
+                        dumpVisibleStacksOnly, dumpFocusedStackOnly)) {
                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
                     int res = shell.exec(this, null, fd, null, args, null,
                             new ResultReceiver(null));
@@ -11125,96 +9463,6 @@
         Binder.restoreCallingIdentity(origId);
     }
 
-    private void writeActivitiesToProtoLocked(ProtoOutputStream proto) {
-        // The output proto of "activity --proto activities" is ActivityManagerServiceDumpActivitiesProto
-        mStackSupervisor.writeToProto(proto, ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
-    }
-
-    private void dumpLastANRLocked(PrintWriter pw) {
-        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
-        if (mLastANRState == null) {
-            pw.println("  <no ANR has occurred since boot>");
-        } else {
-            pw.println(mLastANRState);
-        }
-    }
-
-    private void dumpLastANRTracesLocked(PrintWriter pw) {
-        pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
-
-        final File[] files = new File(ANR_TRACE_DIR).listFiles();
-        if (ArrayUtils.isEmpty(files)) {
-            pw.println("  <no ANR has occurred since boot>");
-            return;
-        }
-        // Find the latest file.
-        File latest = null;
-        for (File f : files) {
-            if ((latest == null) || (latest.lastModified() < f.lastModified())) {
-                latest = f;
-            }
-        }
-        pw.print("File: ");
-        pw.print(latest.getName());
-        pw.println();
-        try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
-            String line;
-            while ((line = in.readLine()) != null) {
-                pw.println(line);
-            }
-        } catch (IOException e) {
-            pw.print("Unable to read: ");
-            pw.print(e);
-            pw.println();
-        }
-    }
-
-    private void dumpActivityContainersLocked(PrintWriter pw) {
-        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
-        mStackSupervisor.dumpChildrenNames(pw, " ");
-        pw.println(" ");
-    }
-
-    private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
-        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
-        mActivityTaskManager.getActivityStartController().dump(pw, "", dumpPackage);
-    }
-
-    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
-        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
-                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
-    }
-
-    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
-        pw.println(header);
-
-        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
-                dumpPackage);
-        boolean needSep = printedAnything;
-
-        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
-                mStackSupervisor.getTopResumedActivity(),  dumpPackage, needSep,
-                "  ResumedActivity: ");
-        if (printed) {
-            printedAnything = true;
-            needSep = false;
-        }
-
-        if (dumpPackage == null) {
-            if (needSep) {
-                pw.println();
-            }
-            printedAnything = true;
-            mStackSupervisor.dump(pw, "  ");
-        }
-
-        if (!printedAnything) {
-            pw.println("  (nothing)");
-        }
-    }
-
     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
@@ -11317,7 +9565,7 @@
         return -1;
     }
 
-    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, SparseArray<UidRecord> uids,
+    boolean dumpUids(PrintWriter pw, String dumpPackage, int dumpAppId, ActiveUids uids,
                 String header, boolean needSep) {
         boolean printed = false;
         for (int i=0; i<uids.size(); i++) {
@@ -11385,6 +9633,7 @@
                 "Counts of Binder Proxies held by SYSTEM");
     }
 
+    // TODO: Move to ProcessList?
     @GuardedBy("this")
     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage, int dumpAppId) {
@@ -11394,9 +9643,9 @@
         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
 
         if (dumpAll) {
-            final int NP = mProcessNames.getMap().size();
+            final int NP = mProcessList.mProcessNames.getMap().size();
             for (int ip=0; ip<NP; ip++) {
-                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
+                SparseArray<ProcessRecord> procs = mProcessList.mProcessNames.getMap().valueAt(ip);
                 final int NA = procs.size();
                 for (int ia=0; ia<NA; ia++) {
                     ProcessRecord r = procs.valueAt(ia);
@@ -11418,10 +9667,10 @@
             }
         }
 
-        if (mIsolatedProcesses.size() > 0) {
+        if (mProcessList.mIsolatedProcesses.size() > 0) {
             boolean printed = false;
-            for (int i=0; i<mIsolatedProcesses.size(); i++) {
-                ProcessRecord r = mIsolatedProcesses.valueAt(i);
+            for (int i=0; i<mProcessList.mIsolatedProcesses.size(); i++) {
+                ProcessRecord r = mProcessList.mIsolatedProcesses.valueAt(i);
                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
                     continue;
                 }
@@ -11474,17 +9723,13 @@
             }
         }
 
-        if (mLruProcesses.size() > 0) {
+        if (mProcessList.getLruSizeLocked() > 0) {
             if (needSep) {
                 pw.println();
             }
-            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
-                    pw.print(" total, non-act at ");
-                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
-                    pw.print(", non-svc at ");
-                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
-                    pw.println("):");
-            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
+            mProcessList.dumpLruListHeaderLocked(pw);
+            dumpProcessOomList(pw, this, mProcessList.mLruProcesses, "    ", "Proc", "PERS", false,
+                    dumpPackage);
             needSep = true;
         }
 
@@ -11538,11 +9783,11 @@
                     "Starting Norm", "Restarting PERS", dumpPackage);
         }
 
-        if (mRemovedProcesses.size() > 0) {
+        if (mProcessList.mRemovedProcesses.size() > 0) {
             if (needSep) pw.println();
             needSep = true;
             pw.println("  Processes that are being removed:");
-            dumpProcessList(pw, this, mRemovedProcesses, "    ",
+            dumpProcessList(pw, this, mProcessList.mRemovedProcesses, "    ",
                     "Removed Norm", "Removed PERS", dumpPackage);
         }
 
@@ -11563,71 +9808,20 @@
             needSep = false;
             mUserController.dump(pw, dumpAll);
         }
-        if (mActivityTaskManager.mHomeProcess != null && (dumpPackage == null
-                || mActivityTaskManager.mHomeProcess.mPkgList.contains(dumpPackage))) {
-            if (needSep) {
-                pw.println();
-                needSep = false;
-            }
-            pw.println("  mHomeProcess: " + mActivityTaskManager.mHomeProcess);
-        }
-        if (mActivityTaskManager.mPreviousProcess != null && (dumpPackage == null
-                || mActivityTaskManager.mPreviousProcess.mPkgList.contains(dumpPackage))) {
-            if (needSep) {
-                pw.println();
-                needSep = false;
-            }
-            pw.println("  mPreviousProcess: " + mActivityTaskManager.mPreviousProcess);
-        }
-        if (dumpAll && (mActivityTaskManager.mPreviousProcess == null || dumpPackage == null
-                || mActivityTaskManager.mPreviousProcess.mPkgList.contains(dumpPackage))) {
-            StringBuilder sb = new StringBuilder(128);
-            sb.append("  mPreviousProcessVisibleTime: ");
-            TimeUtils.formatDuration(mActivityTaskManager.mPreviousProcessVisibleTime, sb);
-            pw.println(sb);
-        }
-        if (mActivityTaskManager.mHeavyWeightProcess != null && (dumpPackage == null
-                || mActivityTaskManager.mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
-            if (needSep) {
-                pw.println();
-                needSep = false;
-            }
-            pw.println("  mHeavyWeightProcess: " + mActivityTaskManager.mHeavyWeightProcess);
-        }
-        if (dumpAll && mPendingStarts.size() > 0) {
+
+        needSep = mAtmInternal.dumpForProcesses(fd, pw, dumpAll, dumpPackage, dumpAppId, needSep,
+                mTestPssMode, mWakefulness);
+
+        if (dumpAll && mProcessList.mPendingStarts.size() > 0) {
             if (needSep) pw.println();
             needSep = true;
             pw.println("  mPendingStarts: ");
-            for (int i = 0, len = mPendingStarts.size(); i < len; ++i ) {
-                pw.println("    " + mPendingStarts.keyAt(i) + ": " + mPendingStarts.valueAt(i));
+            for (int i = 0, len = mProcessList.mPendingStarts.size(); i < len; ++i ) {
+                pw.println("    " + mProcessList.mPendingStarts.keyAt(i) + ": "
+                        + mProcessList.mPendingStarts.valueAt(i));
             }
         }
-        if (dumpPackage == null) {
-            pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
-            mStackSupervisor.dumpDisplayConfigs(pw, "  ");
-        }
         if (dumpAll) {
-            if (dumpPackage == null) {
-                pw.println("  mConfigWillChange: "
-                        + mActivityTaskManager.getTopDisplayFocusedStack().mConfigWillChange);
-            }
-            if (mActivityTaskManager.mCompatModePackages.getPackages().size() > 0) {
-                boolean printed = false;
-                for (Map.Entry<String, Integer> entry
-                        : mActivityTaskManager.mCompatModePackages.getPackages().entrySet()) {
-                    String pkg = entry.getKey();
-                    int mode = entry.getValue();
-                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
-                        continue;
-                    }
-                    if (!printed) {
-                        pw.println("  mScreenCompatPackages:");
-                        printed = true;
-                    }
-                    pw.print("    "); pw.print(pkg); pw.print(": ");
-                            pw.print(mode); pw.println();
-                }
-            }
             final int NI = mUidObservers.getRegisteredCallbackCount();
             boolean printed = false;
             for (int i=0; i<NI; i++) {
@@ -11684,11 +9878,6 @@
                 }
             }
         }
-        if (dumpPackage == null) {
-            pw.println("  mWakefulness="
-                    + PowerManagerInternal.wakefulnessToString(mWakefulness));
-            mActivityTaskManager.dumpSleepStates(pw, mTestPssMode);
-        }
         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
                 || mOrigWaitForDebugger) {
             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
@@ -11702,9 +9891,6 @@
                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
             }
         }
-        if (mActivityTaskManager.mCurAppTimeTracker != null) {
-            mActivityTaskManager.mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
-        }
         if (mMemWatchProcesses.getMap().size() > 0) {
             pw.println("  Mem watch processes:");
             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
@@ -11769,40 +9955,10 @@
                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
             }
         }
-        if (mActivityTaskManager.mAllowAppSwitchUids.size() > 0) {
-            boolean printed = false;
-            for (int i = 0; i < mActivityTaskManager.mAllowAppSwitchUids.size(); i++) {
-                ArrayMap<String, Integer> types = mActivityTaskManager.mAllowAppSwitchUids.valueAt(i);
-                for (int j = 0; j < types.size(); j++) {
-                    if (dumpPackage == null ||
-                            UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
-                        if (needSep) {
-                            pw.println();
-                            needSep = false;
-                        }
-                        if (!printed) {
-                            pw.println("  mAllowAppSwitchUids:");
-                            printed = true;
-                        }
-                        pw.print("    User ");
-                        pw.print(mActivityTaskManager.mAllowAppSwitchUids.keyAt(i));
-                        pw.print(": Type ");
-                        pw.print(types.keyAt(j));
-                        pw.print(" = ");
-                        UserHandle.formatUid(pw, types.valueAt(j).intValue());
-                        pw.println();
-                    }
-                }
-            }
-        }
         if (dumpPackage == null) {
             if (mAlwaysFinishActivities) {
                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
             }
-            if (mActivityTaskManager.mController != null) {
-                pw.println("  mController=" + mActivityTaskManager.mController
-                        + " mControllerIsAMonkey=" + mActivityTaskManager.mControllerIsAMonkey);
-            }
             if (dumpAll) {
                 pw.println("  Total persistent processes: " + numPers);
                 pw.println("  mProcessesReady=" + mProcessesReady
@@ -11815,11 +9971,9 @@
                 pw.print("  mLastPowerCheckUptime=");
                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
                         pw.println("");
-                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
-                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
-                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
+                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mProcessList.mLruSeq);
                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
-                        + " (" + mLruProcesses.size() + " total)"
+                        + " (" + mProcessList.getLruSizeLocked() + " total)"
                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
                         + " mNumServiceProcs=" + mNumServiceProcs
                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
@@ -11865,9 +10019,9 @@
     void writeProcessesToProtoLocked(ProtoOutputStream proto, String dumpPackage) {
         int numPers = 0;
 
-        final int NP = mProcessNames.getMap().size();
+        final int NP = mProcessList.mProcessNames.getMap().size();
         for (int ip=0; ip<NP; ip++) {
-            SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
+            SparseArray<ProcessRecord> procs = mProcessList.mProcessNames.getMap().valueAt(ip);
             final int NA = procs.size();
             for (int ia = 0; ia<NA; ia++) {
                 ProcessRecord r = procs.valueAt(ia);
@@ -11881,8 +10035,8 @@
             }
         }
 
-        for (int i=0; i<mIsolatedProcesses.size(); i++) {
-            ProcessRecord r = mIsolatedProcesses.valueAt(i);
+        for (int i=0; i<mProcessList.mIsolatedProcesses.size(); i++) {
+            ProcessRecord r = mProcessList.mIsolatedProcesses.valueAt(i);
             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
                 continue;
             }
@@ -11915,14 +10069,17 @@
             uidRec.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VALIDATE_UIDS);
         }
 
-        if (mLruProcesses.size() > 0) {
+        if (mProcessList.getLruSizeLocked() > 0) {
             long lruToken = proto.start(ActivityManagerServiceDumpProcessesProto.LRU_PROCS);
-            int total = mLruProcesses.size();
+            int total = mProcessList.getLruSizeLocked();
             proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.SIZE, total);
-            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT, total-mLruProcessActivityStart);
-            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT, total-mLruProcessServiceStart);
-            writeProcessOomListToProto(proto, ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
-                    mLruProcesses,false, dumpPackage);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_ACT_AT,
+                    total - mProcessList.mLruProcessActivityStart);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LruProcesses.NON_SVC_AT,
+                    total - mProcessList.mLruProcessServiceStart);
+            writeProcessOomListToProto(proto,
+                    ActivityManagerServiceDumpProcessesProto.LruProcesses.LIST, this,
+                    mProcessList.mLruProcesses,false, dumpPackage);
             proto.end(lruToken);
         }
 
@@ -11933,7 +10090,8 @@
                     if (!r.pkgList.containsKey(dumpPackage)) {
                         continue;
                     }
-                    r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
+                    r.writeToProto(proto,
+                            ActivityManagerServiceDumpProcessesProto.PIDS_SELF_LOCKED);
                 }
             }
         }
@@ -11947,7 +10105,8 @@
                             || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
                     }
-                    it.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
+                    it.writeToProto(proto,
+                            ActivityManagerServiceDumpProcessesProto.IMPORTANT_PROCS);
                 }
             }
         }
@@ -11957,11 +10116,12 @@
             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
                 continue;
             }
-            r.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
+            r.writeToProto(proto,
+                    ActivityManagerServiceDumpProcessesProto.PERSISTENT_STARTING_PROCS);
         }
 
-        for (int i=0; i<mRemovedProcesses.size(); i++) {
-            ProcessRecord r = mRemovedProcesses.get(i);
+        for (int i = 0; i < mProcessList.mRemovedProcesses.size(); i++) {
+            ProcessRecord r = mProcessList.mRemovedProcesses.get(i);
             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
                 continue;
             }
@@ -11978,39 +10138,10 @@
 
         writeProcessesToGcToProto(proto, ActivityManagerServiceDumpProcessesProto.GC_PROCS, dumpPackage);
         mAppErrors.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.APP_ERRORS, dumpPackage);
+        mAtmInternal.writeProcessesToProto(proto, dumpPackage);
 
         if (dumpPackage == null) {
             mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER);
-            getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION);
-            proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, mActivityTaskManager.getTopDisplayFocusedStack().mConfigWillChange);
-        }
-
-        if (mActivityTaskManager.mHomeProcess != null && (dumpPackage == null
-                || mActivityTaskManager.mHomeProcess.mPkgList.contains(dumpPackage))) {
-            ((ProcessRecord) mActivityTaskManager.mHomeProcess.mOwner).writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HOME_PROC);
-        }
-
-        if (mActivityTaskManager.mPreviousProcess != null && (dumpPackage == null
-                || mActivityTaskManager.mPreviousProcess.mPkgList.contains(dumpPackage))) {
-            ((ProcessRecord) mActivityTaskManager.mPreviousProcess.mOwner).writeToProto(proto, ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC);
-            proto.write(ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS, mActivityTaskManager.mPreviousProcessVisibleTime);
-        }
-
-        if (mActivityTaskManager.mHeavyWeightProcess != null && (dumpPackage == null
-                || mActivityTaskManager.mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
-            ((ProcessRecord) mActivityTaskManager.mHeavyWeightProcess.mOwner).writeToProto(proto, ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC);
-        }
-
-        for (Map.Entry<String, Integer> entry
-                : mActivityTaskManager.mCompatModePackages.getPackages().entrySet()) {
-            String pkg = entry.getKey();
-            int mode = entry.getValue();
-            if (dumpPackage == null || dumpPackage.equals(pkg)) {
-                long compatToken = proto.start(ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES);
-                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE, pkg);
-                proto.write(ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE, mode);
-                proto.end(compatToken);
-            }
         }
 
         final int NI = mUidObservers.getRegisteredCallbackCount();
@@ -12043,8 +10174,6 @@
                     PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
             proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
             proto.end(sleepToken);
-
-            mActivityTaskManager.writeSleepStateToProto(proto);
         }
 
         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
@@ -12060,11 +10189,6 @@
             }
         }
 
-        if (mActivityTaskManager.mCurAppTimeTracker != null) {
-            mActivityTaskManager.mCurAppTimeTracker.writeToProto(
-                    proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
-        }
-
         if (mMemWatchProcesses.getMap().size() > 0) {
             final long token = proto.start(ActivityManagerServiceDumpProcessesProto.MEM_WATCH_PROCESSES);
             ArrayMap<String, SparseArray<Pair<Long, String>>> procs = mMemWatchProcesses.getMap();
@@ -12121,12 +10245,6 @@
 
         if (dumpPackage == null) {
             proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities);
-            if (mActivityTaskManager.mController != null) {
-                final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER);
-                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mActivityTaskManager.mController.toString());
-                proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mActivityTaskManager.mControllerIsAMonkey);
-                proto.end(token);
-            }
             proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers);
             proto.write(ActivityManagerServiceDumpProcessesProto.PROCESSES_READY, mProcessesReady);
             proto.write(ActivityManagerServiceDumpProcessesProto.SYSTEM_READY, mSystemReady);
@@ -12136,10 +10254,8 @@
             proto.write(ActivityManagerServiceDumpProcessesProto.CALL_FINISH_BOOTING, mCallFinishBooting);
             proto.write(ActivityManagerServiceDumpProcessesProto.BOOT_ANIMATION_COMPLETE, mBootAnimationComplete);
             proto.write(ActivityManagerServiceDumpProcessesProto.LAST_POWER_CHECK_UPTIME_MS, mLastPowerCheckUptime);
-            mStackSupervisor.mGoingToSleep.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP);
-            mStackSupervisor.mLaunchingActivity.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY);
             proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq);
-            proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mLruSeq);
+            proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mProcessList.mLruSeq);
             proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, mNumNonCachedProcs);
             proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs);
             proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, mNewNumServiceProcs);
@@ -12220,7 +10336,7 @@
             int opti, boolean dumpAll) {
         boolean needSep = false;
 
-        if (mLruProcesses.size() > 0) {
+        if (mProcessList.getLruSizeLocked() > 0) {
             if (needSep) pw.println();
             needSep = true;
             pw.println("  OOM levels:");
@@ -12240,13 +10356,16 @@
             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
 
             if (needSep) pw.println();
-            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
+            pw.print("  Process OOM control ("); pw.print(mProcessList.getLruSizeLocked());
                     pw.print(" total, non-act at ");
-                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
+                    pw.print(mProcessList.getLruSizeLocked()
+                            - mProcessList.mLruProcessActivityStart);
                     pw.print(", non-svc at ");
-                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
+                    pw.print(mProcessList.getLruSizeLocked()
+                            - mProcessList.mLruProcessServiceStart);
                     pw.println("):");
-            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
+            dumpProcessOomList(pw, this, mProcessList.mLruProcesses, "    ", "Proc", "PERS", true,
+                    null);
             needSep = true;
         }
 
@@ -12364,95 +10483,6 @@
         }
     }
 
-    /**
-     * There are three things that cmd can be:
-     *  - a flattened component name that matches an existing activity
-     *  - 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.
-     *
-     *  @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
-     */
-    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
-            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
-        ArrayList<ActivityRecord> activities;
-
-        synchronized (this) {
-            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
-                    dumpFocusedStackOnly);
-        }
-
-        if (activities.size() <= 0) {
-            return false;
-        }
-
-        String[] newArgs = new String[args.length - opti];
-        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
-
-        TaskRecord lastTask = null;
-        boolean needSep = false;
-        for (int i=activities.size()-1; i>=0; i--) {
-            ActivityRecord r = activities.get(i);
-            if (needSep) {
-                pw.println();
-            }
-            needSep = true;
-            synchronized (this) {
-                final TaskRecord task = r.getTask();
-                if (lastTask != task) {
-                    lastTask = task;
-                    pw.print("TASK "); pw.print(lastTask.affinity);
-                            pw.print(" id="); pw.print(lastTask.taskId);
-                            pw.print(" userId="); pw.println(lastTask.userId);
-                    if (dumpAll) {
-                        lastTask.dump(pw, "  ");
-                    }
-                }
-            }
-            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
-        }
-        return true;
-    }
-
-    /**
-     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
-     * there is a thread associated with the activity.
-     */
-    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
-            final ActivityRecord r, String[] args, boolean dumpAll) {
-        String innerPrefix = prefix + "  ";
-        synchronized (this) {
-            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 (dumpAll) {
-                r.dump(pw, innerPrefix);
-            }
-        }
-        if (r.attachedToProcess()) {
-            // 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();
-                }
-            } catch (IOException e) {
-                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
-            } catch (RemoteException e) {
-                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
-            }
-        }
-    }
-
     void writeBroadcastsToProtoLocked(ProtoOutputStream proto) {
         if (mRegisteredReceivers.size() > 0) {
             Iterator it = mRegisteredReceivers.values().iterator();
@@ -12777,12 +10807,13 @@
             if (schedGroup != ProcessOomProto.SCHED_GROUP_UNKNOWN) {
                 proto.write(ProcessOomProto.SCHED_GROUP, schedGroup);
             }
-            if (r.foregroundActivities) {
+            if (r.hasForegroundActivities()) {
                 proto.write(ProcessOomProto.ACTIVITIES, true);
             } else if (r.hasForegroundServices()) {
                 proto.write(ProcessOomProto.SERVICES, true);
             }
-            proto.write(ProcessOomProto.STATE, ProcessList.makeProcStateProtoEnum(r.curProcState));
+            proto.write(ProcessOomProto.STATE,
+                    ProcessList.makeProcStateProtoEnum(r.getCurProcState()));
             proto.write(ProcessOomProto.TRIM_MEMORY_LEVEL, r.trimMemoryLevel);
             r.writeToProto(proto, ProcessOomProto.PROC);
             proto.write(ProcessOomProto.ADJ_TYPE, r.adjType);
@@ -12803,12 +10834,12 @@
             if (inclDetails) {
                 long detailToken = proto.start(ProcessOomProto.DETAIL);
                 proto.write(ProcessOomProto.Detail.MAX_ADJ, r.maxAdj);
-                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.curRawAdj);
+                proto.write(ProcessOomProto.Detail.CUR_RAW_ADJ, r.getCurRawAdj());
                 proto.write(ProcessOomProto.Detail.SET_RAW_ADJ, r.setRawAdj);
                 proto.write(ProcessOomProto.Detail.CUR_ADJ, r.curAdj);
                 proto.write(ProcessOomProto.Detail.SET_ADJ, r.setAdj);
                 proto.write(ProcessOomProto.Detail.CURRENT_STATE,
-                        ProcessList.makeProcStateProtoEnum(r.curProcState));
+                        ProcessList.makeProcStateProtoEnum(r.getCurProcState()));
                 proto.write(ProcessOomProto.Detail.SET_STATE,
                         ProcessList.makeProcStateProtoEnum(r.setProcState));
                 proto.write(ProcessOomProto.Detail.LAST_PSS, DebugUtils.sizeValueToString(
@@ -12874,14 +10905,14 @@
                     break;
             }
             char foreground;
-            if (r.foregroundActivities) {
+            if (r.hasForegroundActivities()) {
                 foreground = 'A';
             } else if (r.hasForegroundServices()) {
                 foreground = 'S';
             } else {
                 foreground = ' ';
             }
-            String procState = ProcessList.makeProcStateString(r.curProcState);
+            String procState = ProcessList.makeProcStateString(r.getCurProcState());
             pw.print(prefix);
             pw.print(r.isPersistent() ? persistentLabel : normalLabel);
             pw.print(" #");
@@ -12929,13 +10960,14 @@
                 pw.print(prefix);
                 pw.print("    ");
                 pw.print("oom: max="); pw.print(r.maxAdj);
-                pw.print(" curRaw="); pw.print(r.curRawAdj);
+                pw.print(" curRaw="); pw.print(r.getCurRawAdj());
                 pw.print(" setRaw="); pw.print(r.setRawAdj);
                 pw.print(" cur="); pw.print(r.curAdj);
                 pw.print(" set="); pw.println(r.setAdj);
                 pw.print(prefix);
                 pw.print("    ");
-                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
+                pw.print("state: cur="); pw.print(
+                        ProcessList.makeProcStateString(r.getCurProcState()));
                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
@@ -12968,35 +11000,9 @@
 
     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
             String[] args) {
-        ArrayList<ProcessRecord> procs;
         synchronized (this) {
-            if (args != null && args.length > start
-                    && args[start].charAt(0) != '-') {
-                procs = new ArrayList<ProcessRecord>();
-                int pid = -1;
-                try {
-                    pid = Integer.parseInt(args[start]);
-                } catch (NumberFormatException e) {
-                }
-                for (int i=mLruProcesses.size()-1; i>=0; i--) {
-                    ProcessRecord proc = mLruProcesses.get(i);
-                    if (proc.pid > 0 && proc.pid == pid) {
-                        procs.add(proc);
-                    } else if (allPkgs && proc.pkgList != null
-                            && proc.pkgList.containsKey(args[start])) {
-                        procs.add(proc);
-                    } else if (proc.processName.equals(args[start])) {
-                        procs.add(proc);
-                    }
-                }
-                if (procs.size() <= 0) {
-                    return null;
-                }
-            } else {
-                procs = new ArrayList<ProcessRecord>(mLruProcesses);
-            }
+            return mProcessList.collectProcessesLocked(start, allPkgs, args);
         }
-        return procs;
     }
 
     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
@@ -14590,13 +12596,13 @@
             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
                     false, null).dumpLocked();
             catPw.println();
-            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
+            mAtmInternal.dump(DUMP_ACTIVITIES_CMD, null, catPw, emptyArgs, 0, false, false, null);
             catPw.flush();
         }
         dropBuilder.append(catSw.toString());
         StatsLog.write(StatsLog.LOW_MEM_REPORTED);
         addErrorToDropBox("lowmem", null, "system_server", null,
-                null, tag.toString(), dropBuilder.toString(), null, null);
+                null, null, tag.toString(), dropBuilder.toString(), null, null);
         //Slog.i(TAG, "Sent to dropbox:");
         //Slog.i(TAG, dropBuilder.toString());
         synchronized (ActivityManagerService.this) {
@@ -14691,7 +12697,7 @@
      * app that was passed in must remain on the process lists.
      */
     @GuardedBy("this")
-    private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
+    final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
         if (index >= 0) {
             removeLruProcessLocked(app);
@@ -14725,11 +12731,11 @@
         app.waitingToKill = null;
         app.forcingToImportant = null;
         updateProcessForegroundLocked(app, false, false);
-        app.foregroundActivities = false;
+        app.setHasForegroundActivities(false);
         app.hasShownUi = false;
         app.treatLikeActivity = false;
         app.hasAboveClient = false;
-        app.hasClientActivities = false;
+        app.setHasClientActivities(false);
 
         mServices.killServicesLocked(app, allowRestart);
 
@@ -14831,7 +12837,7 @@
             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
                     "Removing non-persistent process during cleanup: " + app);
             if (!replacingPid) {
-                removeProcessNameLocked(app.processName, app.uid, app);
+                mProcessList.removeProcessNameLocked(app.processName, app.uid, app);
             }
             mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
         } else if (!app.removed) {
@@ -14855,9 +12861,9 @@
             if (index < 0) {
                 ProcessList.remove(app.pid);
             }
-            addProcessNameLocked(app);
+            mProcessList.addProcessNameLocked(app);
             app.pendingStart = false;
-            startProcessLocked(app, "restart", app.processName);
+            mProcessList.startProcessLocked(app, "restart", app.processName);
             return true;
         } else if (app.pid > 0 && app.pid != MY_PID) {
             // Goodbye!
@@ -15594,15 +13600,7 @@
     }
 
     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
-        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
-            ProcessRecord r = mLruProcesses.get(i);
-            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
-                try {
-                    r.thread.dispatchPackageBroadcast(cmd, packages);
-                } catch (RemoteException ex) {
-                }
-            }
-        }
+        mProcessList.sendPackageBroadcastLocked(cmd, packages, userId);
     }
 
     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
@@ -16011,8 +14009,10 @@
                                     }
                                 } else {
                                     if (killProcess) {
-                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
-                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
+                                        final int extraUid = intent.getIntExtra(Intent.EXTRA_UID,
+                                                -1);
+                                        mProcessList.killPackageProcessesLocked(ssp,
+                                                UserHandle.getAppId(extraUid),
                                                 userId, ProcessList.INVALID_ADJ,
                                                 false, true, true, false, "change " + ssp);
                                     }
@@ -16053,7 +14053,7 @@
                                     + " ssp=" + ssp + " data=" + data);
                             return ActivityManager.BROADCAST_SUCCESS;
                         }
-                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
+                        mAtmInternal.onPackageReplaced(aInfo);
                         mServices.updateServiceApplicationInfoLocked(aInfo);
                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
                                 new String[] {ssp}, userId);
@@ -16698,11 +14698,13 @@
             activeInstr.mResultClass = className;
 
             boolean disableHiddenApiChecks = ai.usesNonSdkApi()
-                    || (flags & INSTRUMENTATION_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
+                    || (flags & INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS) != 0;
             if (disableHiddenApiChecks) {
                 enforceCallingPermission(android.Manifest.permission.DISABLE_HIDDEN_API_CHECKS,
                         "disable hidden API checks");
             }
+            final boolean mountExtStorageFull = isCallerShell()
+                    && (flags & INSTR_FLAG_MOUNT_EXTERNAL_STORAGE_FULL) != 0;
 
             final long origId = Binder.clearCallingIdentity();
             // Instrumentation can kill and relaunch even persistent processes
@@ -16715,7 +14717,7 @@
             }
 
             ProcessRecord app = addAppLocked(ai, defProcess, false, disableHiddenApiChecks,
-                    abiOverride);
+                    mountExtStorageFull, abiOverride);
             app.setActiveInstrumentation(activeInstr);
             activeInstr.mFinished = false;
             activeInstr.mRunningProcesses.add(app);
@@ -16728,6 +14730,11 @@
         return true;
     }
 
+    private boolean isCallerShell() {
+        final int callingUid = Binder.getCallingUid();
+        return callingUid == SHELL_UID || callingUid == ROOT_UID;
+    }
+
     /**
      * Report errors that occur while attempting to start Instrumentation.  Always writes the
      * error to the logs, but if somebody is watching, send the report there too.  This enables
@@ -17001,7 +15008,7 @@
         }
     }
 
-    private void noteUidProcessState(final int uid, final int state) {
+    void noteUidProcessState(final int uid, final int state) {
         mBatteryStatsService.noteUidProcessState(uid, state);
         mAppOpsService.updateUidProcState(uid, state);
         if (mTrackingAssociations) {
@@ -17033,6 +15040,7 @@
     private final ComputeOomAdjWindowCallback mTmpComputeOomAdjWindowCallback =
             new ComputeOomAdjWindowCallback();
 
+    /** These methods are called inline during computeOomAdjLocked(), on the same thread */
     private final class ComputeOomAdjWindowCallback
             implements WindowProcessController.ComputeOomAdjCallback {
 
@@ -17171,8 +15179,9 @@
         if (app.thread == null) {
             app.adjSeq = mAdjSeq;
             app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_BACKGROUND);
-            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
-            app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ;
+            app.setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+            app.curAdj = ProcessList.CACHED_APP_MAX_ADJ;
+            app.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ);
             app.completedAdjSeq = app.adjSeq;
             return false;
         }
@@ -17188,7 +15197,7 @@
         final int logUid = mCurOomAdjUid;
 
         int prevAppAdj = app.curAdj;
-        int prevProcState = app.curProcState;
+        int prevProcState = app.getCurProcState();
 
         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
             // The max adjustment doesn't allow this app to be anything
@@ -17198,10 +15207,10 @@
             }
             app.adjType = "fixed";
             app.adjSeq = mAdjSeq;
-            app.curRawAdj = app.maxAdj;
-            app.foregroundActivities = false;
+            app.setCurRawAdj(app.maxAdj);
+            app.setHasForegroundActivities(false);
             app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
-            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
+            app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
             // System processes can do UI, and when they do we want to have
             // them trim their memory after the user leaves the UI.  To
             // facilitate this, here we need to determine whether or not it
@@ -17211,7 +15220,7 @@
                 app.systemNoUi = false;
                 app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP);
                 app.adjType = "pers-top-activity";
-            } else if (app.hasTopUi) {
+            } else if (app.hasTopUi()) {
                 // sched group/proc state adjustment is below
                 app.systemNoUi = false;
                 app.adjType = "pers-top-ui";
@@ -17221,11 +15230,11 @@
             if (!app.systemNoUi) {
               if (mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE) {
                   // screen on, promote UI
-                  app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
+                  app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI);
                   app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP);
               } else {
                   // screen off, restrict UI scheduling
-                  app.curProcState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+                  app.setCurProcState(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
                   app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_RESTRICTED);
               }
             }
@@ -17361,7 +15370,7 @@
                 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
                     reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to fg service: " + app);
                 }
-            } else if (app.hasOverlayUi) {
+            } else if (app.hasOverlayUi()) {
                 // The process is display an overlay UI.
                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
@@ -17475,7 +15484,7 @@
         // there are applications dependent on our services or providers, but
         // this gives us a baseline and makes sure we don't get into an
         // infinite recursion.
-        app.curRawAdj = adj;
+        app.setCurRawAdj(adj);
         app.hasStartedServices = false;
         app.adjSeq = mAdjSeq;
 
@@ -17590,8 +15599,8 @@
                                 continue;
                             }
                         }
-                        int clientAdj = client.curRawAdj;
-                        int clientProcState = client.curProcState;
+                        int clientAdj = client.getCurRawAdj();
+                        int clientProcState = client.getCurProcState();
                         if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
                             // If the other app is cached for any reason, for purposes here
                             // we are going to consider it empty.  The specific cached state
@@ -17752,8 +15761,8 @@
                             }
                         }
                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
-                            app.pendingUiClean = true;
+                                && (cr.flags & Context.BIND_SHOWING_UI) != 0) {
+                            app.setPendingUiClean(true);
                         }
                         if (adjType != null) {
                             app.adjType = adjType;
@@ -17773,10 +15782,10 @@
                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
                         app.treatLikeActivity = true;
                     }
-                    final ActivityRecord a = cr.activity;
+                    final ActivityServiceConnectionsHolder a = cr.activity;
                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
-                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && (a.visible
-                                || a.isState(ActivityState.RESUMED, ActivityState.PAUSING))) {
+                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ
+                                && a.isActivityVisible()) {
                             adj = ProcessList.FOREGROUND_APP_ADJ;
                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
@@ -17832,8 +15841,8 @@
                         continue;
                     }
                 }
-                int clientAdj = client.curRawAdj;
-                int clientProcState = client.curProcState;
+                int clientAdj = client.getCurRawAdj();
+                int clientProcState = client.getCurProcState();
                 if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
                     // If the other app is cached for any reason, for purposes here
                     // we are going to consider it empty.
@@ -17994,7 +16003,7 @@
         }
 
         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
-            if (app.hasClientActivities) {
+            if (app.hasClientActivities()) {
                 // This is a cached process, but with client activities.  Mark it so.
                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
                 app.adjType = "cch-client-act";
@@ -18034,7 +16043,7 @@
             }
         }
 
-        app.curRawAdj = adj;
+        app.setCurRawAdj(adj);
 
         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
@@ -18061,12 +16070,12 @@
         // keep it out of the cached vaues.
         app.curAdj = app.modifyRawOomAdj(adj);
         app.setCurrentSchedulingGroup(schedGroup);
-        app.curProcState = procState;
-        app.foregroundActivities = foregroundActivities;
+        app.setCurProcState(procState);
+        app.setHasForegroundActivities(foregroundActivities);
         app.completedAdjSeq = mAdjSeq;
 
         // if curAdj or curProcState improved, then this process was promoted
-        return app.curAdj < prevAppAdj || app.curProcState < prevProcState;
+        return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState;
     }
 
     /**
@@ -18213,12 +16222,11 @@
         for (int i = mPendingPssProcesses.size() - 1; i >= 0; i--) {
             ProcessList.abortNextPssTime(mPendingPssProcesses.get(i).procStateMemTracker);;
         }
-        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
+        mPendingPssProcesses.ensureCapacity(mProcessList.getLruSizeLocked());
         mPendingPssProcesses.clear();
-        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
-            ProcessRecord app = mLruProcesses.get(i);
-            if (app.thread == null
-                    || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
+        for (int i = mProcessList.getLruSizeLocked() - 1; i >= 0; i--) {
+            ProcessRecord app = mProcessList.mLruProcesses.get(i);
+            if (app.thread == null || app.getCurProcState() == PROCESS_STATE_NONEXISTENT) {
                 continue;
             }
             if (memLowered || (always && now >
@@ -18227,7 +16235,7 @@
                 app.pssProcState = app.setProcState;
                 app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
                         : ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
-                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
+                app.nextPssTime = ProcessList.computeNextPssTime(app.getCurProcState(),
                         app.procStateMemTracker, mTestPssMode, mAtmInternal.isSleeping(), now);
                 mPendingPssProcesses.add(app);
             }
@@ -18277,8 +16285,7 @@
                 processingBroadcasts = true;
             }
         }
-        return !processingBroadcasts
-                && (mAtmInternal.isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
+        return !processingBroadcasts && mAtmInternal.canGcNow();
     }
 
     /**
@@ -18293,7 +16300,7 @@
         if (canGcNowLocked()) {
             while (mProcessesToGc.size() > 0) {
                 ProcessRecord proc = mProcessesToGc.remove(0);
-                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
+                if (proc.getCurRawAdj() > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
                             <= SystemClock.uptimeMillis()) {
                         // To avoid spamming the system, we will GC processes one
@@ -18393,10 +16400,10 @@
         final long curUptime = SystemClock.uptimeMillis();
         final long uptimeSince = curUptime - mLastPowerCheckUptime;
         mLastPowerCheckUptime = curUptime;
-        int i = mLruProcesses.size();
+        int i = mProcessList.mLruProcesses.size();
         while (i > 0) {
             i--;
-            ProcessRecord app = mLruProcesses.get(i);
+            ProcessRecord app = mProcessList.mLruProcesses.get(i);
             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
                 if (app.lastCpuTime <= 0) {
                     continue;
@@ -18420,7 +16427,7 @@
                 if (doCpuKills && uptimeSince > 0) {
                     // What is the limit for this process?
                     int cpuLimit;
-                    long checkDur = curUptime - app.whenUnimportant;
+                    long checkDur = curUptime - app.getWhenUnimportant();
                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
@@ -18458,8 +16465,8 @@
             long nowElapsed) {
         boolean success = true;
 
-        if (app.curRawAdj != app.setRawAdj) {
-            app.setRawAdj = app.curRawAdj;
+        if (app.getCurRawAdj() != app.setRawAdj) {
+            app.setRawAdj = app.getCurRawAdj();
         }
 
         int changes = 0;
@@ -18582,12 +16589,12 @@
                 }
             }
         }
-        if (app.repForegroundActivities != app.foregroundActivities) {
-            app.repForegroundActivities = app.foregroundActivities;
+        if (app.repForegroundActivities != app.hasForegroundActivities()) {
+            app.repForegroundActivities = app.hasForegroundActivities();
             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
         }
-        if (app.getReportedProcState() != app.curProcState) {
-            app.setReportedProcState(app.curProcState);
+        if (app.getReportedProcState() != app.getCurProcState()) {
+            app.setReportedProcState(app.getCurProcState());
             if (app.thread != null) {
                 try {
                     if (false) {
@@ -18600,8 +16607,8 @@
                 }
             }
         }
-        if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
-                || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
+        if (app.setProcState == PROCESS_STATE_NONEXISTENT
+                || ProcessList.procStatesDifferForMem(app.getCurProcState(), app.setProcState)) {
             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
                 // Experimental code to more aggressively collect pss while
                 // running test...  the problem is that this tends to collect
@@ -18611,46 +16618,45 @@
                 long startTime = SystemClock.currentThreadTimeMillis();
                 long pss = Debug.getPss(app.pid, mTmpLong, null);
                 long endTime = SystemClock.currentThreadTimeMillis();
-                recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1],
+                recordPssSampleLocked(app, app.getCurProcState(), pss, mTmpLong[0], mTmpLong[1],
                         mTmpLong[2], ProcessStats.ADD_PSS_INTERNAL_SINGLE, endTime-startTime, now);
                 mPendingPssProcesses.remove(app);
                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
-                        + " to " + app.curProcState + ": "
+                        + " to " + app.getCurProcState() + ": "
                         + (SystemClock.uptimeMillis()-start) + "ms");
             }
             app.lastStateTime = now;
-            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
+            app.nextPssTime = ProcessList.computeNextPssTime(app.getCurProcState(),
                     app.procStateMemTracker, mTestPssMode, mAtmInternal.isSleeping(), now);
             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
                     + ProcessList.makeProcStateString(app.setProcState) + " to "
-                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
+                    + ProcessList.makeProcStateString(app.getCurProcState()) + " next pss in "
                     + (app.nextPssTime-now) + ": " + app);
         } else {
             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
                     mTestPssMode)))) {
                 if (requestPssLocked(app, app.setProcState)) {
-                    app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
+                    app.nextPssTime = ProcessList.computeNextPssTime(app.getCurProcState(),
                             app.procStateMemTracker, mTestPssMode, mAtmInternal.isSleeping(), now);
                 }
             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
                     "Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
         }
-        if (app.setProcState != app.curProcState) {
+        if (app.setProcState != app.getCurProcState()) {
             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
                 String msg = "Proc state change of " + app.processName
-                        + " to " + ProcessList.makeProcStateString(app.curProcState)
-                        + " (" + app.curProcState + ")" + ": " + app.adjType;
+                        + " to " + ProcessList.makeProcStateString(app.getCurProcState())
+                        + " (" + app.getCurProcState() + ")" + ": " + app.adjType;
                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
             }
             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
-            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
+            boolean curImportant = app.getCurProcState() < ActivityManager.PROCESS_STATE_SERVICE;
             if (setImportant && !curImportant) {
-                // This app is no longer something we consider important enough to allow to
-                // use arbitrary amounts of battery power.  Note
-                // its current CPU time to later know to kill it if
-                // it is not behaving well.
-                app.whenUnimportant = now;
+                // This app is no longer something we consider important enough to allow to use
+                // arbitrary amounts of battery power. Note its current CPU time to later know to
+                // kill it if it is not behaving well.
+                app.setWhenUnimportant(now);
                 app.lastCpuTime = 0;
             }
             // Inform UsageStats of important process state change
@@ -18659,7 +16665,7 @@
 
             maybeUpdateLastTopTime(app, now);
 
-            app.setProcState = app.curProcState;
+            app.setProcState = app.getCurProcState();
             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
                 app.notCachedSinceIdle = false;
             }
@@ -18668,7 +16674,7 @@
             } else {
                 app.procStateChanged = true;
             }
-        } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
+        } else if (app.reportedInteraction && (nowElapsed - app.getInteractionEventTime())
                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
             // For apps that sit around for a long time in the interactive state, we need
             // to report this at least once a day so they don't go idle.
@@ -18790,8 +16796,7 @@
             }
         }
         pendingChange.change = change;
-        pendingChange.processState = uidRec != null
-                ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
+        pendingChange.processState = uidRec != null ? uidRec.setProcState : PROCESS_STATE_NONEXISTENT;
         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
         if (uidRec != null) {
@@ -18822,7 +16827,7 @@
     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
             String authority) {
         if (app == null) return;
-        if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
+        if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
             UserState userState = mUserController.getStartedUserState(app.userId);
             if (userState == null) return;
             final long now = SystemClock.elapsedRealtime();
@@ -18842,7 +16847,7 @@
         if (DEBUG_USAGE_STATS) {
             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
                     + "] state changes: old = " + app.setProcState + ", new = "
-                    + app.curProcState);
+                    + app.getCurProcState());
         }
         if (mUsageStatsService == null) {
             return;
@@ -18851,24 +16856,26 @@
         // To avoid some abuse patterns, we are going to be careful about what we consider
         // to be an app interaction.  Being the top activity doesn't count while the display
         // is sleeping, nor do short foreground services.
-        if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP) {
+        if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP) {
             isInteraction = true;
-            app.fgInteractionTime = 0;
-        } else if (app.curProcState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
-            if (app.fgInteractionTime == 0) {
-                app.fgInteractionTime = nowElapsed;
+            app.setFgInteractionTime(0);
+        } else if (app.getCurProcState() <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
+            if (app.getFgInteractionTime() == 0) {
+                app.setFgInteractionTime(nowElapsed);
                 isInteraction = false;
             } else {
-                isInteraction = nowElapsed > app.fgInteractionTime
+                isInteraction = nowElapsed > app.getFgInteractionTime()
                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
             }
         } else {
-            isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
-            app.fgInteractionTime = 0;
+            isInteraction =
+                    app.getCurProcState() <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+            app.setFgInteractionTime(0);
         }
-        if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
+        if (isInteraction
+                && (!app.reportedInteraction || (nowElapsed - app.getInteractionEventTime())
                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
-            app.interactionEventTime = nowElapsed;
+            app.setInteractionEventTime(nowElapsed);
             String[] packages = app.getPackageList();
             if (packages != null) {
                 for (int i = 0; i < packages.length; i++) {
@@ -18879,13 +16886,13 @@
         }
         app.reportedInteraction = isInteraction;
         if (!isInteraction) {
-            app.interactionEventTime = 0;
+            app.setInteractionEventTime(0);
         }
     }
 
     private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) {
         if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP
-                && app.curProcState > ActivityManager.PROCESS_STATE_TOP) {
+                && app.getCurProcState() > ActivityManager.PROCESS_STATE_TOP) {
             app.lastTopTime = nowUptime;
         }
     }
@@ -18945,13 +16952,14 @@
 
     // TODO(b/111541062): This method is only used for updating OOM adjustments. We need to update
     // the logic there and in mBatteryStatsService to make them aware of multiple resumed activities
-    private ActivityRecord resumedAppLocked() {
-        final ActivityRecord act = mStackSupervisor.getTopResumedActivity();
+    ProcessRecord getTopAppLocked() {
+        final WindowProcessController wpc = mAtmInternal != null ? mAtmInternal.getTopApp() : null;
+        final ProcessRecord r = wpc != null ? (ProcessRecord) wpc.mOwner : null;
         String pkg;
         int uid;
-        if (act != null) {
-            pkg = act.packageName;
-            uid = act.info.applicationInfo.uid;
+        if (r != null) {
+            pkg = r.processName;
+            uid = r.info.uid;
         } else {
             pkg = null;
             uid = -1;
@@ -18977,7 +16985,7 @@
             }
 
         }
-        return act;
+        return r;
     }
 
     /**
@@ -18989,9 +16997,7 @@
      */
     @GuardedBy("this")
     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
-        final ActivityRecord TOP_ACT = resumedAppLocked();
-        final ProcessRecord TOP_APP = TOP_ACT != null && TOP_ACT.hasProcess()
-                ? (ProcessRecord) TOP_ACT.app.mOwner : null;
+        final ProcessRecord TOP_APP = getTopAppLocked();
         final boolean wasCached = app.cached;
 
         mAdjSeq++;
@@ -19000,12 +17006,12 @@
         // If our app is currently cached, we know it, and that is it.  Otherwise,
         // we don't know it yet, and it needs to now be cached we will then
         // need to do a complete oom adj.
-        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
-                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
+        final int cachedAdj = app.getCurRawAdj() >= ProcessList.CACHED_APP_MIN_ADJ
+                ? app.getCurRawAdj() : ProcessList.UNKNOWN_ADJ;
         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
                 SystemClock.uptimeMillis());
         if (oomAdjAll
-                && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
+                && (wasCached != app.cached || app.getCurRawAdj() == ProcessList.UNKNOWN_ADJ)) {
             // Changed to/from cached state, so apps after it in the LRU
             // list may also be changed.
             updateOomAdjLocked();
@@ -19014,23 +17020,13 @@
     }
 
     @GuardedBy("this")
-    ProcessRecord getTopAppLocked() {
-        final ActivityRecord TOP_ACT = resumedAppLocked();
-        if (TOP_ACT != null && TOP_ACT.hasProcess()) {
-            return (ProcessRecord) TOP_ACT.app.mOwner;
-        } else {
-            return null;
-        }
-    }
-
-    @GuardedBy("this")
     final void updateOomAdjLocked() {
         mOomAdjProfiler.oomAdjStarted();
         final ProcessRecord TOP_APP = getTopAppLocked();
         final long now = SystemClock.uptimeMillis();
         final long nowElapsed = SystemClock.elapsedRealtime();
         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
-        final int N = mLruProcesses.size();
+        final int N = mProcessList.getLruSizeLocked();
 
         // Reset state in all uid records.
         for (int i=mActiveUids.size()-1; i>=0; i--) {
@@ -19040,8 +17036,8 @@
             uidRec.reset();
         }
 
-        if (mStackSupervisor != null) {
-            mStackSupervisor.rankTaskLayersIfNeeded();
+        if (mAtmInternal != null) {
+            mAtmInternal.rankTaskLayersIfNeeded();
         }
 
         mAdjSeq++;
@@ -19091,11 +17087,11 @@
 
         // need to reset cycle state before calling computeOomAdjLocked because of service connections
         for (int i=N-1; i>=0; i--) {
-            ProcessRecord app = mLruProcesses.get(i);
+            ProcessRecord app = mProcessList.mLruProcesses.get(i);
             app.containsCycle = false;
         }
         for (int i=N-1; i>=0; i--) {
-            ProcessRecord app = mLruProcesses.get(i);
+            ProcessRecord app = mProcessList.mLruProcesses.get(i);
             if (!app.killedByAm && app.thread != null) {
                 app.procStateChanged = false;
                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
@@ -19106,14 +17102,14 @@
                 // If we haven't yet assigned the final cached adj
                 // to the process, do that now.
                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
-                    switch (app.curProcState) {
+                    switch (app.getCurProcState()) {
                         case PROCESS_STATE_CACHED_ACTIVITY:
                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
                         case ActivityManager.PROCESS_STATE_CACHED_RECENT:
                             // This process is a cached process holding activities...
                             // assign it the next cached value for that type, and then
                             // step that cached level.
-                            app.curRawAdj = curCachedAdj;
+                            app.setCurRawAdj(curCachedAdj);
                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
@@ -19136,7 +17132,7 @@
                             // long-running services that have dropped down to the
                             // cached level will be treated as empty (since their process
                             // state is still as a service), which is what we want.
-                            app.curRawAdj = curEmptyAdj;
+                            app.setCurRawAdj(curEmptyAdj);
                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
@@ -19170,7 +17166,7 @@
             retryCycles = false;
 
             for (int i=0; i<N; i++) {
-                ProcessRecord app = mLruProcesses.get(i);
+                ProcessRecord app = mProcessList.mLruProcesses.get(i);
                 if (!app.killedByAm && app.thread != null && app.containsCycle == true) {
                     app.adjSeq--;
                     app.completedAdjSeq--;
@@ -19178,7 +17174,7 @@
             }
 
             for (int i=0; i<N; i++) {
-                ProcessRecord app = mLruProcesses.get(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)) {
@@ -19189,12 +17185,12 @@
         }
 
         for (int i=N-1; i>=0; i--) {
-            ProcessRecord app = mLruProcesses.get(i);
+            ProcessRecord app = mProcessList.mLruProcesses.get(i);
             if (!app.killedByAm && app.thread != null) {
                 applyOomAdjLocked(app, true, now, nowElapsed);
 
                 // Count the number of process types.
-                switch (app.curProcState) {
+                switch (app.getCurProcState()) {
                     case PROCESS_STATE_CACHED_ACTIVITY:
                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
                         mNumCachedHiddenProcs++;
@@ -19235,8 +17231,8 @@
                     final UidRecord uidRec = app.uidRecord;
                     if (uidRec != null) {
                         uidRec.ephemeral = app.info.isInstantApp();
-                        if (uidRec.curProcState > app.curProcState) {
-                            uidRec.curProcState = app.curProcState;
+                        if (uidRec.getCurProcState() > app.getCurProcState()) {
+                            uidRec.setCurProcState(app.getCurProcState());
                         }
                         if (app.hasForegroundServices()) {
                             uidRec.foregroundServices = true;
@@ -19244,7 +17240,7 @@
                     }
                 }
 
-                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
+                if (app.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME
                         && !app.killedByAm) {
                     numTrimming++;
                 }
@@ -19282,9 +17278,9 @@
         // has gone down since last time.
         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
-                + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
+                + " numProcs=" + mProcessList.getLruSizeLocked() + " last=" + mLastNumProcesses);
         if (memFactor > mLastMemoryLevel) {
-            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
+            if (!mAllowLowerMemLevel || mProcessList.getLruSizeLocked() >= mLastNumProcesses) {
                 memFactor = mLastMemoryLevel;
                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
             }
@@ -19294,7 +17290,7 @@
             StatsLog.write(StatsLog.MEMORY_FACTOR_STATE_CHANGED, memFactor);
         }
         mLastMemoryLevel = memFactor;
-        mLastNumProcesses = mLruProcesses.size();
+        mLastNumProcesses = mProcessList.getLruSizeLocked();
         boolean allChanged = mProcessStats.setMemFactorLocked(
                 memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
@@ -19322,12 +17318,12 @@
             if (factor < minFactor) factor = minFactor;
             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
             for (int i=N-1; i>=0; i--) {
-                ProcessRecord app = mLruProcesses.get(i);
+                ProcessRecord app = mProcessList.mLruProcesses.get(i);
                 if (allChanged || app.procStateChanged) {
                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
                     app.procStateChanged = false;
                 }
-                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
+                if (app.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME
                         && !app.killedByAm) {
                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
                         try {
@@ -19350,7 +17346,7 @@
                                 break;
                         }
                     }
-                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+                } else if (app.getCurProcState() == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
                         && !app.killedByAm) {
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
                             && app.thread != null) {
@@ -19365,8 +17361,8 @@
                     }
                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
                 } else {
-                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-                            || app.systemNoUi) && app.pendingUiClean) {
+                    if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+                            || app.systemNoUi) && app.hasPendingUiClean()) {
                         // If this application is now in the background and it
                         // had done UI, then give it the special trim level to
                         // have it free UI resources.
@@ -19380,7 +17376,7 @@
                             } catch (RemoteException e) {
                             }
                         }
-                        app.pendingUiClean = false;
+                        app.setPendingUiClean(false);
                     }
                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
                         try {
@@ -19400,13 +17396,13 @@
                 mLowRamStartTime = 0;
             }
             for (int i=N-1; i>=0; i--) {
-                ProcessRecord app = mLruProcesses.get(i);
+                ProcessRecord app = mProcessList.mLruProcesses.get(i);
                 if (allChanged || app.procStateChanged) {
                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
                     app.procStateChanged = false;
                 }
-                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
-                        || app.systemNoUi) && app.pendingUiClean) {
+                if ((app.getCurProcState() >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+                        || app.systemNoUi) && app.hasPendingUiClean()) {
                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
                             && app.thread != null) {
                         try {
@@ -19418,7 +17414,7 @@
                         } catch (RemoteException e) {
                         }
                     }
-                    app.pendingUiClean = false;
+                    app.setPendingUiClean(false);
                 }
                 app.trimMemoryLevel = 0;
             }
@@ -19427,7 +17423,7 @@
         if (mAlwaysFinishActivities) {
             // Need to do this on its own message because the stack may not
             // be in a consistent state at this point.
-            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
+            mAtmInternal.scheduleDestroyAllActivities("always-finish");
         }
 
         if (allChanged) {
@@ -19443,14 +17439,14 @@
         for (int i=mActiveUids.size()-1; i>=0; i--) {
             final UidRecord uidRec = mActiveUids.valueAt(i);
             int uidChange = UidRecord.CHANGE_PROCSTATE;
-            if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
-                    && (uidRec.setProcState != uidRec.curProcState
+            if (uidRec.getCurProcState() != PROCESS_STATE_NONEXISTENT
+                    && (uidRec.setProcState != uidRec.getCurProcState()
                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
-                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
-                        "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
-                        + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
+                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "Changes in " + uidRec
+                        + ": proc state from " + uidRec.setProcState + " to "
+                        + uidRec.getCurProcState() + ", whitelist from " + uidRec.setWhitelist
                         + " to " + uidRec.curWhitelist);
-                if (ActivityManager.isProcStateBackground(uidRec.curProcState)
+                if (ActivityManager.isProcStateBackground(uidRec.getCurProcState())
                         && !uidRec.curWhitelist) {
                     // UID is now in the background (and not on the temp whitelist).  Was it
                     // previously in the foreground (or on the temp whitelist)?
@@ -19483,17 +17479,16 @@
                 }
                 final boolean wasCached = uidRec.setProcState
                         > ActivityManager.PROCESS_STATE_RECEIVER;
-                final boolean isCached = uidRec.curProcState
+                final boolean isCached = uidRec.getCurProcState()
                         > ActivityManager.PROCESS_STATE_RECEIVER;
-                if (wasCached != isCached ||
-                        uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
+                if (wasCached != isCached || uidRec.setProcState == PROCESS_STATE_NONEXISTENT) {
                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
                 }
-                uidRec.setProcState = uidRec.curProcState;
+                uidRec.setProcState = uidRec.getCurProcState();
                 uidRec.setWhitelist = uidRec.curWhitelist;
                 uidRec.setIdle = uidRec.idle;
                 enqueueUidChangeLocked(uidRec, -1, uidChange);
-                noteUidProcessState(uidRec.uid, uidRec.curProcState);
+                noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
                 if (uidRec.foregroundServices) {
                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
                 }
@@ -19654,7 +17649,7 @@
                 continue;
             }
             // If process state is not changed, then there's nothing to do.
-            if (uidRec.setProcState == uidRec.curProcState) {
+            if (uidRec.setProcState == uidRec.getCurProcState()) {
                 continue;
             }
             final int blockState = getBlockStateForUid(uidRec);
@@ -19664,7 +17659,7 @@
                 continue;
             }
             synchronized (uidRec.networkStateLock) {
-                uidRec.curProcStateSeq = ++mProcStateSeqCounter;
+                uidRec.curProcStateSeq = ++mProcessList.mProcStateSeqCounter; // TODO: use method
                 if (blockState == NETWORK_STATE_BLOCK) {
                     if (blockingUids == null) {
                         blockingUids = new ArrayList<>();
@@ -19687,8 +17682,8 @@
             return;
         }
 
-        for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
-            final ProcessRecord app = mLruProcesses.get(i);
+        for (int i = mProcessList.mLruProcesses.size() - 1; i >= 0; --i) {
+            final ProcessRecord app = mProcessList.mLruProcesses.get(i);
             if (!blockingUids.contains(app.uid)) {
                 continue;
             }
@@ -19718,8 +17713,9 @@
     @VisibleForTesting
     int getBlockStateForUid(UidRecord uidRec) {
         // Denotes whether uid's process state is currently allowed network access.
-        final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
-                || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
+        final boolean isAllowed =
+                isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.getCurProcState())
+                || isProcStateAllowedWhileOnRestrictBackground(uidRec.getCurProcState());
         // Denotes whether uid's process state was previously allowed network access.
         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
@@ -19886,8 +17882,8 @@
     final void trimApplicationsLocked() {
         // First remove any unused application processes whose package
         // has been removed.
-        for (int i=mRemovedProcesses.size()-1; i>=0; i--) {
-            final ProcessRecord app = mRemovedProcesses.get(i);
+        for (int i = mProcessList.mRemovedProcesses.size() - 1; i >= 0; i--) {
+            final ProcessRecord app = mProcessList.mRemovedProcesses.get(i);
             if (!app.hasActivitiesOrRecentTasks()
                     && app.curReceivers.isEmpty() && app.services.size() == 0) {
                 Slog.i(
@@ -19905,7 +17901,7 @@
                     }
                 }
                 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
-                mRemovedProcesses.remove(i);
+                mProcessList.mRemovedProcesses.remove(i);
 
                 if (app.isPersistent()) {
                     addAppLocked(app.info, null, false, null /* ABI override */);
@@ -19931,8 +17927,8 @@
                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
             }
 
-            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
-                ProcessRecord r = mLruProcesses.get(i);
+            for (int i = mProcessList.mLruProcesses.size() - 1 ; i >= 0 ; i--) {
+                ProcessRecord r = mProcessList.mLruProcesses.get(i);
                 if (r.thread != null && r.isPersistent()) {
                     sendSignal(r.pid, sig);
                 }
@@ -20059,7 +18055,7 @@
 
         if (proc == null) {
             ArrayMap<String, SparseArray<ProcessRecord>> all
-                    = mProcessNames.getMap();
+                    = mProcessList.mProcessNames.getMap();
             SparseArray<ProcessRecord> procs = all.get(process);
             if (procs != null && procs.size() > 0) {
                 proc = procs.valueAt(0);
@@ -20189,15 +18185,8 @@
     }
 
     void onCoreSettingsChange(Bundle settings) {
-        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
-            ProcessRecord processRecord = mLruProcesses.get(i);
-            try {
-                if (processRecord.thread != null) {
-                    processRecord.thread.setCoreSettings(settings);
-                }
-            } catch (RemoteException re) {
-                /* ignore */
-            }
+        synchronized (this) {
+            mProcessList.updateCoreSettingsLocked(settings);
         }
     }
 
@@ -20329,8 +18318,8 @@
                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
             }
 
-            for (int i = 0; i < mLruProcesses.size(); i++) {
-                ProcessRecord process = mLruProcesses.get(i);
+            for (int i = 0; i < mProcessList.mLruProcesses.size(); i++) {
+                ProcessRecord process = mProcessList.mLruProcesses.get(i);
                 if (!processSanityChecksLocked(process)) {
                     continue;
                 }
@@ -20362,7 +18351,7 @@
 
                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
                 pw.println("Binder transaction traces for all processes.\n");
-                for (ProcessRecord process : mLruProcesses) {
+                for (ProcessRecord process : mProcessList.mLruProcesses) {
                     if (!processSanityChecksLocked(process)) {
                         continue;
                     }
@@ -20423,9 +18412,10 @@
         public void killForegroundAppsForUser(int userHandle) {
             synchronized (ActivityManagerService.this) {
                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
-                final int NP = mProcessNames.getMap().size();
+                final int NP = mProcessList.mProcessNames.getMap().size();
                 for (int ip = 0; ip < NP; ip++) {
-                    final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
+                    final SparseArray<ProcessRecord> apps =
+                            mProcessList.mProcessNames.getMap().valueAt(ip);
                     final int NA = apps.size();
                     for (int ia = 0; ia < NA; ia++) {
                         final ProcessRecord app = apps.valueAt(ia);
@@ -20435,7 +18425,7 @@
                         }
                         if (app.removed) {
                             procs.add(app);
-                        } else if (app.userId == userHandle && app.foregroundActivities) {
+                        } else if (app.userId == userHandle && app.hasForegroundActivities()) {
                             app.removed = true;
                             procs.add(app);
                         }
@@ -20444,7 +18434,7 @@
 
                 final int N = procs.size();
                 for (int i = 0; i < N; i++) {
-                    removeProcessLocked(procs.get(i), false, true, "kill all fg");
+                    mProcessList.removeProcessLocked(procs.get(i), false, true, "kill all fg");
                 }
             }
         }
@@ -20506,10 +18496,10 @@
                         return;
                     }
                 }
-                if (pr.hasOverlayUi == hasOverlayUi) {
+                if (pr.hasOverlayUi() == hasOverlayUi) {
                     return;
                 }
-                pr.hasOverlayUi = hasOverlayUi;
+                pr.setHasOverlayUi(hasOverlayUi);
                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
                 updateOomAdjLocked(pr, true);
             }
@@ -20565,36 +18555,6 @@
         }
 
         @Override
-        public void saveANRState(String reason) {
-            synchronized (ActivityManagerService.this) {
-                final StringWriter sw = new StringWriter();
-                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
-                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
-                if (reason != null) {
-                    pw.println("  Reason: " + reason);
-                }
-                pw.println();
-                mActivityTaskManager.getActivityStartController().dump(pw, "  ", null);
-                pw.println();
-                pw.println("-------------------------------------------------------------------------------");
-                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
-                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
-                        "" /* header */);
-                pw.println();
-                pw.close();
-
-                mLastANRState = sw.toString();
-            }
-        }
-
-        @Override
-        public void clearSavedANRState() {
-            synchronized (ActivityManagerService.this) {
-                mLastANRState = null;
-            }
-        }
-
-        @Override
         public boolean isRuntimeRestarted() {
             return mSystemServiceManager.isRuntimeRestarted();
         }
@@ -20660,6 +18620,28 @@
         }
 
         @Override
+        public List<ProcessMemoryState> getMemoryStateForNativeProcesses() {
+            List<ProcessMemoryState> processMemoryStates = new ArrayList<>();
+            int[] pids = getPidsForCommands(MEMORY_STAT_INTERESTING_NATIVE_PROCESSES);
+            for (int i = 0; i < pids.length; i++) {
+                int pid = pids[i];
+                MemoryStat memoryStat = readMemoryStatFromProcfs(pid);
+                if (memoryStat == null) {
+                    continue;
+                }
+                int uid = getUidForPid(pid);
+                String processName = readCmdlineFromProcfs(pid);
+                int oomScore = -1; // Unused, not included in the NativeProcessMemoryState atom.
+                ProcessMemoryState processMemoryState = new ProcessMemoryState(uid, processName,
+                        oomScore, memoryStat.pgfault, memoryStat.pgmajfault,
+                        memoryStat.rssInBytes, memoryStat.cacheInBytes, memoryStat.swapInBytes,
+                        memoryStat.rssHighWatermarkInBytes);
+                processMemoryStates.add(processMemoryState);
+            }
+            return processMemoryStates;
+        }
+
+        @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,
@@ -20687,10 +18669,6 @@
             ActivityManagerService.this.trimApplications();
         }
 
-        public void closeSystemDialogs(String reason) {
-            ActivityManagerService.this.closeSystemDialogs(reason);
-        }
-
         public void killProcessesForRemovedTask(ArrayList<Object> procsToKill) {
             synchronized (ActivityManagerService.this) {
                 for (int i = 0; i < procsToKill.size(); i++) {
@@ -20714,8 +18692,8 @@
             if (packageName == null) return false;
 
             synchronized (ActivityManagerService.this) {
-                for (int i = 0; i < mLruProcesses.size(); i++) {
-                    final ProcessRecord pr = mLruProcesses.get(i);
+                for (int i = 0; i < mProcessList.mLruProcesses.size(); i++) {
+                    final ProcessRecord pr = mProcessList.mLruProcesses.get(i);
                     if (pr.uid != uid) {
                         continue;
                     }
@@ -20807,13 +18785,6 @@
         }
 
         @Override
-        public Intent getHomeIntent() {
-            synchronized (ActivityManagerService.this) {
-                return ActivityManagerService.this.getHomeIntent();
-            }
-        }
-
-        @Override
         public void scheduleAppGcs() {
             synchronized (ActivityManagerService.this) {
                 ActivityManagerService.this.scheduleAppGcsLocked();
@@ -20891,6 +18862,233 @@
                 return res;
             }
         }
+
+        @Override
+        public void disconnectActivityFromServices(Object connectionHolder) {
+            synchronized(ActivityManagerService.this) {
+                final ActivityServiceConnectionsHolder c =
+                        (ActivityServiceConnectionsHolder) connectionHolder;
+                c.forEachConnection(cr -> mServices.removeConnectionLocked(
+                        (ConnectionRecord) cr, null, c));
+            }
+        }
+
+        public void cleanUpServices(int userId, ComponentName component, Intent baseIntent) {
+            synchronized(ActivityManagerService.this) {
+                mServices.cleanUpServices(userId, component, baseIntent);
+            }
+        }
+
+        public ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
+            // Locked intentionally not held as it isn't needed for this case.
+            return ActivityManagerService.this.getActivityInfoForUser(aInfo, userId);
+        }
+
+        public void ensureBootCompleted() {
+            // Locked intentionally not held as it isn't needed for this case.
+            ActivityManagerService.this.ensureBootCompleted();
+        }
+
+        public void updateOomLevelsForDisplay(int displayId) {
+            synchronized(ActivityManagerService.this) {
+                if (mWindowManager != null) {
+                    mProcessList.applyDisplaySize(mWindowManager);
+                }
+            }
+        }
+
+        public boolean isActivityStartsLoggingEnabled() {
+            return mConstants.mFlagActivityStartsLoggingEnabled;
+        }
+
+        public void reportCurKeyguardUsageEvent(boolean keyguardShowing) {
+            synchronized(ActivityManagerService.this) {
+                ActivityManagerService.this.reportGlobalUsageEventLocked(keyguardShowing
+                        ? UsageEvents.Event.KEYGUARD_SHOWN
+                        : UsageEvents.Event.KEYGUARD_HIDDEN);
+            }
+        }
+
+        @Override
+        public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
+            synchronized (ActivityManagerService.this) {
+                return ActivityManagerService.this.inputDispatchingTimedOut(
+                        pid, aboveSystem, reason);
+            }
+        }
+
+        @Override
+        public boolean inputDispatchingTimedOut(Object proc, String activityShortComponentName,
+                ApplicationInfo aInfo, String parentShortComponentName, Object parentProc,
+                boolean aboveSystem, String reason) {
+            return ActivityManagerService.this.inputDispatchingTimedOut((ProcessRecord) proc,
+                    activityShortComponentName, aInfo, parentShortComponentName,
+                    (WindowProcessController) parentProc, aboveSystem, reason);
+
+        }
+
+        @Override
+        public void broadcastGlobalConfigurationChanged(int changes, boolean initLocale) {
+            synchronized (ActivityManagerService.this) {
+                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
+                        | Intent.FLAG_RECEIVER_FOREGROUND
+                        | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+                broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+                        OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+                        UserHandle.USER_ALL);
+                if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
+                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
+                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
+                            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
+                            | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
+                    if (initLocale || !mProcessesReady) {
+                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+                    }
+                    broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+                            OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+                            UserHandle.USER_ALL);
+                }
+
+                // Send a broadcast to PackageInstallers if the configuration change is interesting
+                // for the purposes of installing additional splits.
+                if (!initLocale && isSplitConfigurationChange(changes)) {
+                    intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
+                    intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
+                            | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+
+                    // Typically only app stores will have this permission.
+                    String[] permissions =
+                            new String[] { android.Manifest.permission.INSTALL_PACKAGES };
+                    broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
+                            permissions, OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
+                            UserHandle.USER_ALL);
+                }
+            }
+        }
+
+        /**
+         * Returns true if this configuration change is interesting enough to send an
+         * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
+         */
+        private boolean isSplitConfigurationChange(int configDiff) {
+            return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
+        }
+
+        @Override
+        public void broadcastCloseSystemDialogs(String reason) {
+            synchronized (ActivityManagerService.this) {
+                final Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                        | Intent.FLAG_RECEIVER_FOREGROUND);
+                if (reason != null) {
+                    intent.putExtra("reason", reason);
+                }
+
+                broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+                        OP_NONE, null, false, false, -1, SYSTEM_UID, UserHandle.USER_ALL);
+            }
+        }
+
+        @Override
+        public void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
+            synchronized (ActivityManagerService.this) {
+                ActivityManagerService.this.killAllBackgroundProcessesExcept(
+                        minTargetSdk, maxProcState);
+            }
+        }
+
+        @Override
+        public void startProcess(String processName, ApplicationInfo info,
+                boolean knownToBeDead, String hostingType, ComponentName hostingName) {
+            synchronized (ActivityManagerService.this) {
+                startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
+                        hostingType, hostingName, false /* allowWhileBooting */,
+                        false /* isolated */, true /* keepIfLarge */);
+            }
+        }
+
+        @Override
+        public void setDebugFlagsForStartingActivity(ActivityInfo aInfo, int startFlags,
+                ProfilerInfo profilerInfo) {
+            synchronized (ActivityManagerService.this) {
+                if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
+                    setDebugApp(aInfo.processName, true, false);
+                }
+
+                if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
+                    setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
+                }
+
+                if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
+                    setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
+                }
+
+                if (profilerInfo != null) {
+                    setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+                }
+            }
+        }
+    }
+
+    long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
+        if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires permission " + FILTER_EVENTS);
+        }
+        ProcessRecord proc;
+        long timeout;
+        synchronized (this) {
+            synchronized (mPidsSelfLocked) {
+                proc = mPidsSelfLocked.get(pid);
+            }
+            timeout = proc != null ? proc.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
+        }
+
+        if (inputDispatchingTimedOut(proc, null, null, null, null, aboveSystem, reason)) {
+            return -1;
+        }
+
+        return timeout;
+    }
+
+    /**
+     * Handle input dispatching timeouts.
+     * @return whether input dispatching should be aborted or not.
+     */
+    boolean inputDispatchingTimedOut(ProcessRecord proc, String activityShortComponentName,
+            ApplicationInfo aInfo, String parentShortComponentName,
+            WindowProcessController parentProcess, boolean aboveSystem, String reason) {
+        if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Requires permission " + FILTER_EVENTS);
+        }
+
+        final String annotation;
+        if (reason == null) {
+            annotation = "Input dispatching timed out";
+        } else {
+            annotation = "Input dispatching timed out (" + reason + ")";
+        }
+
+        if (proc != null) {
+            synchronized (this) {
+                if (proc.isDebugging()) {
+                    return false;
+                }
+
+                if (proc.getActiveInstrumentation() != null) {
+                    Bundle info = new Bundle();
+                    info.putString("shortMsg", "keyDispatchingTimedOut");
+                    info.putString("longMsg", annotation);
+                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
+                    return true;
+                }
+            }
+            proc.appNotResponding(activityShortComponentName, aInfo,
+                    parentShortComponentName, parentProcess, aboveSystem, annotation);
+        }
+
+        return true;
     }
 
     /**
@@ -21013,8 +19211,8 @@
         }
         try {
             synchronized(this) {
-                killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
-                        ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
+                mProcessList.killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid),
+                        userId, ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
                         "dep: " + packageName);
             }
         } finally {
@@ -21044,33 +19242,9 @@
 
     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
-        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
-            final ProcessRecord app = mLruProcesses.get(i);
-            if (app.thread == null) {
-                continue;
-            }
 
-            if (userId != UserHandle.USER_ALL && app.userId != userId) {
-                continue;
-            }
+        mProcessList.updateApplicationInfoLocked(packagesToUpdate, userId, updateFrameworkRes);
 
-            final int packageCount = app.pkgList.size();
-            for (int j = 0; j < packageCount; j++) {
-                final String packageName = app.pkgList.keyAt(j);
-                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
-                    try {
-                        final ApplicationInfo ai = AppGlobals.getPackageManager()
-                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
-                        if (ai != null) {
-                            app.thread.scheduleApplicationInfoChanged(ai);
-                        }
-                    } catch (RemoteException e) {
-                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
-                                    packageName, app));
-                    }
-                }
-            }
-        }
         if (updateFrameworkRes) {
             // Update system server components that need to know about changed overlays. Because the
             // overlay is applied in ActivityThread, we need to serialize through its thread too.
@@ -21092,7 +19266,8 @@
     public void attachAgent(String process, String path) {
         try {
             synchronized (this) {
-                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
+                ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM,
+                        "attachAgent");
                 if (proc == null || proc.thread == null) {
                     throw new IllegalArgumentException("Unknown process: " + process);
                 }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 40c555f8..96601a2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -17,14 +17,13 @@
 package com.android.server.am;
 
 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
 import static android.app.ActivityTaskManager.RESIZE_MODE_USER;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.view.Display.INVALID_DISPLAY;
 
-import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
-
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
 import android.app.ActivityTaskManager;
@@ -481,12 +480,12 @@
                 options.setLockTaskEnabled(true);
             }
             if (mWaitOption) {
-                result = mTaskInterface.startActivityAndWait(null, null, intent, mimeType,
+                result = mInternal.startActivityAndWait(null, null, intent, mimeType,
                         null, null, 0, mStartFlags, profilerInfo,
                         options != null ? options.toBundle() : null, mUserId);
                 res = result.result;
             } else {
-                res = mTaskInterface.startActivityAsUser(null, null, intent, mimeType,
+                res = mInternal.startActivityAsUser(null, null, intent, mimeType,
                         null, null, 0, mStartFlags, profilerInfo,
                         options != null ? options.toBundle() : null, mUserId);
             }
@@ -2902,6 +2901,7 @@
             pw.println("      --receiver-permission <PERMISSION>: Require receiver to hold permission.");
             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]");
             pw.println("          [--no-window-animation] [--abi <ABI>] <COMPONENT>");
             pw.println("      Start an Instrumentation.  Typically this target <COMPONENT> is in the");
             pw.println("      form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there");
@@ -2920,6 +2920,8 @@
             pw.println("      --user <USER_ID> | current: Specify user instrumentation runs in;");
             pw.println("          current user if not specified.");
             pw.println("      --no-hidden-api-checks: disable restrictions on use of hidden API.");
+            pw.println("      --no-isolated-storage: don't use isolated storage sandbox and ");
+            pw.println("          mount full external storage");
             pw.println("      --no-window-animation: turn off window animations while running.");
             pw.println("      --abi <ABI>: Launch the instrumented process with the selected ABI.");
             pw.println("          This assumes that the process supports the selected ABI.");
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 18cdb05..a0dd878 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -72,9 +72,9 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_NO_BUNDLE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_REPORTED_DRAWN_WITH_BUNDLE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_WARM_LAUNCH;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_METRICS;
-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.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.EventLogTags.AM_ACTIVITY_LAUNCH_TIME;
 import static com.android.server.am.MemoryStatUtil.MemoryStat;
 import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
@@ -110,11 +110,11 @@
  * data for Tron, logcat, event logs and {@link android.app.WaitResult}.
  *
  * Tests:
- * atest SystemMetricsFunctionalTests
+ * atest CtsActivityManagerDeviceTestCases:ActivityMetricsLoggerTests
  */
 class ActivityMetricsLogger {
 
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityMetricsLogger" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityMetricsLogger" : TAG_ATM;
 
     // Window modes we are interested in logging. If we ever introduce a new type, we need to add
     // a value here and increase the {@link #TRON_WINDOW_STATE_VARZ_STRINGS} array.
@@ -155,7 +155,6 @@
     private final H mHandler;
 
     private ArtManagerInternal mArtManagerInternal;
-    private boolean mDrawingTraceActive;
     private final StringBuilder mStringBuilder = new StringBuilder();
 
     private final class H extends Handler {
@@ -230,14 +229,14 @@
             launchedActivityLaunchToken = launchedActivity.info.launchToken;
             launchedActivityAppRecordRequiredAbi = launchedActivity.app == null
                     ? null
-                    : info.launchedActivity.app.getRequiredAbi();
+                    : launchedActivity.app.getRequiredAbi();
             reason = info.reason;
             startingWindowDelayMs = info.startingWindowDelayMs;
             bindApplicationDelayMs = info.bindApplicationDelayMs;
             windowsDrawnDelayMs = info.windowsDrawnDelayMs;
             type = getTransitionType(info);
-            processRecord = findProcessForActivity(info.launchedActivity);
-            processName = info.launchedActivity.processName;
+            processRecord = findProcessForActivity(launchedActivity);
+            processName = launchedActivity.processName;
             userId = launchedActivity.userId;
             launchedActivityShortComponentName = launchedActivity.shortComponentName;
             activityRecordIdHashCode = System.identityHashCode(launchedActivity);
@@ -351,18 +350,24 @@
                 + " processRunning=" + processRunning
                 + " processSwitch=" + processSwitch);
 
-        // If we are already in an existing transition, only update the activity name, but not the
-        // other attributes.
         final int windowingMode = launchedActivity != null
                 ? launchedActivity.getWindowingMode()
                 : WINDOWING_MODE_UNDEFINED;
-
+        final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
         if (mCurrentTransitionStartTime == INVALID_START_TIME) {
+            // No transition is active ignore this launch.
             return;
         }
 
-        final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
+        if (launchedActivity != null && launchedActivity.nowVisible) {
+            // Launched activity is already visible. We cannot measure windows drawn delay.
+            reset(true /* abort */, info);
+            return;
+        }
+
         if (launchedActivity != null && info != null) {
+            // If we are already in an existing transition, only update the activity name, but not
+            // the other attributes.
             info.launchedActivity = launchedActivity;
             return;
         }
@@ -371,7 +376,6 @@
                 mWindowingModeTransitionInfo.size() > 0 && info == null;
         if ((!isLoggableResultCode(resultCode) || launchedActivity == null || !processSwitch
                 || windowingMode == WINDOWING_MODE_UNDEFINED) && !otherWindowModesLaunching) {
-
             // Failed to launch or it was not a process switch, so we don't care about the timing.
             reset(true /* abort */, info);
             return;
@@ -496,7 +500,6 @@
                 if (mWindowingModeTransitionInfo.size() == 0) {
                     reset(true /* abort */, info);
                 }
-                stopFullyDrawnTraceIfNeeded();
             }
         }
     }
@@ -504,14 +507,14 @@
     /**
      * Notifies the tracker that we called immediately before we call bindApplication on the client.
      *
-     * @param app The client into which we'll call bindApplication.
+     * @param appInfo The client into which we'll call bindApplication.
      */
-    void notifyBindApplication(ProcessRecord app) {
+    void notifyBindApplication(ApplicationInfo appInfo) {
         for (int i = mWindowingModeTransitionInfo.size() - 1; i >= 0; i--) {
             final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.valueAt(i);
 
             // App isn't attached to record yet, so match with info.
-            if (info.launchedActivity.appInfo == app.info) {
+            if (info.launchedActivity.appInfo == appInfo) {
                 info.bindApplicationDelayMs = calculateCurrentDelay();
             }
         }
@@ -694,6 +697,13 @@
         if (info == null) {
             return null;
         }
+
+        // Record the handling of the reportFullyDrawn callback in the trace system. This is not
+        // actually used to trace this function, but instead the logical task that this function
+        // fullfils (handling reportFullyDrawn() callbacks).
+        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                "ActivityManager:ReportingFullyDrawn " + info.launchedActivity.packageName);
+
         final LogMaker builder = new LogMaker(APP_TRANSITION_REPORTED_DRAWN);
         builder.setPackageName(r.packageName);
         builder.addTaggedData(FIELD_CLASS_NAME, r.info.name);
@@ -715,7 +725,11 @@
                 info.launchedActivity.info.name,
                 info.currentTransitionProcessRunning,
                 startupTimeMs);
-        stopFullyDrawnTraceIfNeeded();
+
+        // Ends the trace started at the beginning of this function. This is located here to allow
+        // the trace slice to have a noticable duration.
+        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+
         final WindowingModeTransitionInfoSnapshot infoSnapshot =
                 new WindowingModeTransitionInfoSnapshot(info, r, (int) startupTimeMs);
         BackgroundThread.getHandler().post(() -> logAppFullyDrawn(infoSnapshot));
@@ -736,7 +750,7 @@
         Log.i(TAG, sb.toString());
     }
 
-    void logActivityStart(Intent intent, ProcessRecord callerApp, ActivityRecord r,
+    void logActivityStart(Intent intent, WindowProcessController callerApp, ActivityRecord r,
             int callingUid, String callingPackage, int callingUidProcState,
             boolean callingUidHasAnyVisibleWindow,
             int realCallingUid, int realCallingUidProcState,
@@ -771,31 +785,31 @@
         builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0);
         builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction());
         if (callerApp != null) {
-            builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.processName);
+            builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.mName);
             builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE,
-                    processStateAmToProto(callerApp.curProcState));
+                    processStateAmToProto(callerApp.getCurrentProcState()));
             builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES,
-                    callerApp.hasClientActivities ? 1 : 0);
+                    callerApp.hasClientActivities() ? 1 : 0);
             builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES,
                     callerApp.hasForegroundServices() ? 1 : 0);
             builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES,
-                    callerApp.foregroundActivities ? 1 : 0);
-            builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi ? 1 : 0);
+                    callerApp.hasForegroundActivities() ? 1 : 0);
+            builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi() ? 1 : 0);
             builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI,
-                    callerApp.hasOverlayUi ? 1 : 0);
+                    callerApp.hasOverlayUi() ? 1 : 0);
             builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN,
-                    callerApp.pendingUiClean ? 1 : 0);
-            if (callerApp.interactionEventTime != 0) {
+                    callerApp.hasPendingUiClean() ? 1 : 0);
+            if (callerApp.getInteractionEventTime() != 0) {
                 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT,
-                        (nowElapsed - callerApp.interactionEventTime));
+                        (nowElapsed - callerApp.getInteractionEventTime()));
             }
-            if (callerApp.fgInteractionTime != 0) {
+            if (callerApp.getFgInteractionTime() != 0) {
                 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION,
-                        (nowElapsed - callerApp.fgInteractionTime));
+                        (nowElapsed - callerApp.getFgInteractionTime()));
             }
-            if (callerApp.whenUnimportant != 0) {
+            if (callerApp.getWhenUnimportant() != 0) {
                 builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT,
-                        (nowUptime - callerApp.whenUnimportant));
+                        (nowUptime - callerApp.getWhenUnimportant()));
             }
         }
         builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode);
@@ -882,10 +896,7 @@
     }
 
     /**
-     * Starts traces for app launch and draw times. We stop the fully drawn trace if its already
-     * active since the app may not have reported fully drawn in the previous launch.
-     *
-     * See {@link android.app.Activity#reportFullyDrawn()}
+     * Starts traces for app launch.
      *
      * @param info
      * */
@@ -893,14 +904,11 @@
         if (info == null) {
             return;
         }
-        stopFullyDrawnTraceIfNeeded();
         int transitionType = getTransitionType(info);
         if (!info.launchTraceActive && transitionType == TYPE_TRANSITION_WARM_LAUNCH
                 || transitionType == TYPE_TRANSITION_COLD_LAUNCH) {
             Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
                     + info.launchedActivity.packageName, 0);
-            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-            mDrawingTraceActive = true;
             info.launchTraceActive = true;
         }
     }
@@ -915,11 +923,4 @@
             info.launchTraceActive = false;
         }
     }
-
-    void stopFullyDrawnTraceIfNeeded() {
-        if (mDrawingTraceActive) {
-            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER, "drawing", 0);
-            mDrawingTraceActive = false;
-        }
-    }
 }
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 5853ad9..865c774 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -81,20 +81,23 @@
 import static android.os.Build.VERSION_CODES.HONEYCOMB;
 import static android.os.Build.VERSION_CODES.O;
 import static android.os.Process.SYSTEM_UID;
+import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SAVED_STATE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
-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.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STATES;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityRecordProto.CONFIGURATION_CONTAINER;
 import static com.android.server.am.ActivityRecordProto.FRONT_OF_TASK;
 import static com.android.server.am.ActivityRecordProto.IDENTIFIER;
@@ -112,11 +115,14 @@
 import static com.android.server.am.ActivityStack.LAUNCH_TICK_MSG;
 import static com.android.server.am.ActivityStack.PAUSE_TIMEOUT_MSG;
 import static com.android.server.am.ActivityStack.STOP_TIMEOUT_MSG;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
 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.am.TaskPersister.DEBUG;
 import static com.android.server.am.TaskPersister.IMAGE_EXTENSION;
-import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static com.android.server.wm.IdentifierProto.HASH_CODE;
 import static com.android.server.wm.IdentifierProto.TITLE;
 import static com.android.server.wm.IdentifierProto.USER_ID;
@@ -209,12 +215,13 @@
  * An entry in the history stack, representing an activity.
  */
 final class ActivityRecord extends ConfigurationContainer implements AppWindowContainerListener {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityRecord" : TAG_AM;
+    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_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_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";
 
@@ -283,7 +290,7 @@
     ActivityOptions pendingOptions; // most recently given options
     ActivityOptions returningOptions; // options that are coming back via convertToTranslucent
     AppTimeTracker appTimeTracker; // set if we are tracking the time in this app/task/activity
-    HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
+    ActivityServiceConnectionsHolder mServiceConnectionsHolder; // Service connections.
     UriPermissionOwner uriPermissions; // current special URI access perms.
     WindowProcessController app;      // if non-null, hosting application
     private ActivityState mState;    // current state we are in
@@ -335,12 +342,6 @@
     int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
     boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
 
-    // This activity is not being relaunched, or being relaunched for a non-resize reason.
-    static final int RELAUNCH_REASON_NONE = 0;
-    // This activity is being relaunched due to windowing mode change.
-    static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
-    // This activity is being relaunched due to a free-resize operation.
-    static final int RELAUNCH_REASON_FREE_RESIZE = 2;
     // Marking the reason why this activity is being relaunched. Mainly used to track that this
     // activity is being relaunched to fulfill a resize request due to compatibility issues, e.g. in
     // pre-NYC apps that don't have a sense of being resized.
@@ -549,8 +550,8 @@
                     pw.print(" configChangeFlags=");
                     pw.println(Integer.toHexString(configChangeFlags));
         }
-        if (connections != null) {
-            pw.print(prefix); pw.print("connections="); pw.println(connections);
+        if (mServiceConnectionsHolder != null) {
+            pw.print(prefix); pw.print("connections="); pw.println(mServiceConnectionsHolder);
         }
         if (info != null) {
             pw.println(prefix + "resizeMode=" + ActivityInfo.resizeModeToString(info.resizeMode));
@@ -849,13 +850,12 @@
         }
     }
 
-    ActivityRecord(ActivityTaskManagerService _service, ProcessRecord _caller, int _launchedFromPid,
-            int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
-            ActivityInfo aInfo, Configuration _configuration,
-            ActivityRecord _resultTo, String _resultWho, int _reqCode,
-            boolean _componentSpecified, boolean _rootVoiceInteraction,
-            ActivityStackSupervisor supervisor, ActivityOptions options,
-            ActivityRecord sourceRecord) {
+    ActivityRecord(ActivityTaskManagerService _service, WindowProcessController _caller,
+            int _launchedFromPid, int _launchedFromUid, String _launchedFromPackage, Intent _intent,
+            String _resolvedType, ActivityInfo aInfo, Configuration _configuration,
+            ActivityRecord _resultTo, String _resultWho, int _reqCode, boolean _componentSpecified,
+            boolean _rootVoiceInteraction, ActivityStackSupervisor supervisor,
+            ActivityOptions options, ActivityRecord sourceRecord) {
         service = _service;
         appToken = new Token(this, _intent);
         info = aInfo;
@@ -925,8 +925,8 @@
         }
         if ((aInfo.flags & FLAG_MULTIPROCESS) != 0 && _caller != null
                 && (aInfo.applicationInfo.uid == SYSTEM_UID
-                    || aInfo.applicationInfo.uid == _caller.info.uid)) {
-            processName = _caller.processName;
+                    || aInfo.applicationInfo.uid == _caller.mInfo.uid)) {
+            processName = _caller.mName;
         } else {
             processName = aInfo.processName;
         }
@@ -1348,6 +1348,42 @@
         return (info.flags & FLAG_ALWAYS_FOCUSABLE) != 0;
     }
 
+    /** Move activity with its stack to front and make the stack focused. */
+    boolean moveFocusableActivityToTop(String reason) {
+        if (!isFocusable()) {
+            if (DEBUG_FOCUS) {
+                Slog.d(TAG_FOCUS, "moveActivityStackToFront: unfocusable activity=" + this);
+            }
+            return false;
+        }
+
+        final TaskRecord task = getTask();
+        final ActivityStack stack = getStack();
+        if (stack == null) {
+            Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: activity="
+                    + this + " task=" + task);
+            return false;
+        }
+
+        if (mStackSupervisor.getTopResumedActivity() == this) {
+            if (DEBUG_FOCUS) {
+                Slog.d(TAG_FOCUS, "moveActivityStackToFront: already on top, activity=" + this);
+            }
+            return false;
+        }
+
+        if (DEBUG_FOCUS) {
+            Slog.d(TAG_FOCUS, "moveActivityStackToFront: activity=" + this);
+        }
+
+        stack.moveToFront(reason, task);
+        // Report top activity change to tracking services and WM
+        if (mStackSupervisor.getTopResumedActivity() == this) {
+            // TODO(b/111361570): Support multiple focused apps in WM
+            service.setResumedActivityUncheckLocked(this, reason);
+        }
+        return true;
+    }
 
     /**
      * @return true if the activity contains windows that have
@@ -1744,7 +1780,7 @@
             }
             setVisible(true);
             sleeping = false;
-            app.setPendingUiClean(true);
+            app.postPendingUiCleanMsg(true);
             if (reportToClient) {
                 makeClientVisible();
             } else {
@@ -2076,12 +2112,16 @@
             windowFromSameProcessAsActivity =
                     !hasProcess() || app.getPid() == windowPid || windowPid == -1;
         }
+
         if (windowFromSameProcessAsActivity) {
-            return service.inputDispatchingTimedOut(anrApp, anrActivity, this, false, reason);
+            return service.mAmInternal.inputDispatchingTimedOut(anrApp.mOwner,
+                    anrActivity.shortComponentName, anrActivity.appInfo, 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.
-            return service.inputDispatchingTimedOut(windowPid, false /* aboveSystem */, reason) < 0;
+            return service.mAmInternal.inputDispatchingTimedOut(
+                    windowPid, false /* aboveSystem */, reason) < 0;
         }
     }
 
@@ -2173,12 +2213,13 @@
     }
 
     /**
-     * @return display id to which this record is attached, -1 if not attached.
+     * @return display id to which this record is attached,
+     *         {@link android.view.Display#INVALID_DISPLAY} if not attached.
      */
     int getDisplayId() {
         final ActivityStack stack = getStack();
         if (stack == null) {
-            return -1;
+            return INVALID_DISPLAY;
         }
         return stack.mDisplayId;
     }
@@ -2243,6 +2284,11 @@
             // We don't show starting window for overlay activities.
             return;
         }
+        if (pendingOptions != null
+                && pendingOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
+            // Don't show starting window when using shared element transition.
+            return;
+        }
 
         final CompatibilityInfo compatInfo =
                 service.compatibilityInfoForPackageLocked(info.applicationInfo);
@@ -2968,17 +3014,6 @@
         mWindowContainerController.registerRemoteAnimations(definition);
     }
 
-    static String relaunchReasonToString(int relaunchReason) {
-        switch (relaunchReason) {
-            case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
-                return "window_resize";
-            case RELAUNCH_REASON_FREE_RESIZE:
-                return "free_resize";
-            default:
-                return null;
-        }
-    }
-
     @Override
     public String toString() {
         if (stringName != null) {
diff --git a/services/core/java/com/android/server/am/ActivityServiceConnectionsHolder.java b/services/core/java/com/android/server/am/ActivityServiceConnectionsHolder.java
new file mode 100644
index 0000000..b1ced29
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActivityServiceConnectionsHolder.java
@@ -0,0 +1,113 @@
+/*
+ * 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.am;
+
+import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
+
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.function.Consumer;
+
+/**
+ * Class for tracking the connections to services on the AM side that activities on the
+ * WM side (in the future) bind with for things like oom score adjustment. Would normally be one
+ * instance of this per activity for tracking all services connected to that activity. AM will
+ * sometimes query this to bump the OOM score for the processes with services connected to visible
+ * activities.
+ */
+public class ActivityServiceConnectionsHolder<T> {
+
+    private final ActivityTaskManagerService mService;
+
+    /** The activity the owns this service connection object. */
+    private final ActivityRecord mActivity;
+
+    /**
+     * The service connection object bounded with the owning activity. They represent
+     * ConnectionRecord on the AM side, however we don't need to know their object representation
+     * on the WM side since we don't perform operations on the object. Mainly here for communication
+     * and booking with the AM side.
+     */
+    private HashSet<T> mConnections;
+
+    ActivityServiceConnectionsHolder(ActivityTaskManagerService service, ActivityRecord activity) {
+        mService = service;
+        mActivity = activity;
+    }
+
+    /** Adds a connection record that the activity has bound to a specific service. */
+    public void addConnection(T c) {
+        synchronized (mService.mGlobalLock) {
+            if (mConnections == null) {
+                mConnections = new HashSet<>();
+            }
+            mConnections.add(c);
+        }
+    }
+
+    /** Removed a connection record between the activity and a specific service. */
+    public void removeConnection(T c) {
+        synchronized (mService.mGlobalLock) {
+            if (mConnections == null) {
+                return;
+            }
+            mConnections.remove(c);
+        }
+    }
+
+    public boolean isActivityVisible() {
+        synchronized (mService.mGlobalLock) {
+            return mActivity.visible || mActivity.isState(RESUMED, PAUSING);
+        }
+    }
+
+    public int getActivityPid() {
+        synchronized (mService.mGlobalLock) {
+            return mActivity.hasProcess() ? mActivity.app.getPid() : -1;
+        }
+    }
+
+    public void forEachConnection(Consumer<T> consumer) {
+        synchronized (mService.mGlobalLock) {
+            if (mConnections == null || mConnections.isEmpty()) {
+                return;
+            }
+            final Iterator<T> it = mConnections.iterator();
+            while (it.hasNext()) {
+                T c = it.next();
+                consumer.accept(c);
+            }
+        }
+    }
+
+    /** Removes the connection between the activity and all services that were connected to it. */
+    void disconnectActivityFromServices() {
+        if (mConnections == null || mConnections.isEmpty()) {
+            return;
+        }
+        mService.mH.post(() -> mService.mAmInternal.disconnectActivityFromServices(this));
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        synchronized (mService.mGlobalLock) {
+            pw.println(prefix + "activity=" + mActivity);
+        }
+    }
+
+}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 29b04cc..026c5cc 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -48,41 +48,41 @@
 
 import static com.android.server.am.ActivityDisplay.POSITION_BOTTOM;
 import static com.android.server.am.ActivityDisplay.POSITION_TOP;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_APP;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SAVED_STATE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TRANSITION;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_APP;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_APP;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONTAINERS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SAVED_STATE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STATES;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TRANSITION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_APP;
 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONTAINERS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SAVED_STATE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TRANSITION;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
-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.ActivityRecord.RELAUNCH_REASON_FREE_RESIZE;
-import static com.android.server.am.ActivityRecord.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONTAINERS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SAVED_STATE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_TRANSITION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
 import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
 import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
 import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
@@ -103,6 +103,7 @@
 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
 
+import static com.android.server.am.ActivityTaskManagerService.H.FIRST_ACTIVITY_STACK_MSG;
 import static java.lang.Integer.MAX_VALUE;
 
 import android.app.Activity;
@@ -163,7 +164,6 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -173,7 +173,7 @@
  */
 class ActivityStack<T extends StackWindowController> extends ConfigurationContainer
         implements StackWindowListener {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_ATM;
     private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
     private static final String TAG_APP = TAG + POSTFIX_APP;
     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
@@ -228,7 +228,7 @@
     }
 
     @Override
-    protected ConfigurationContainer getChildAt(int index) {
+    protected TaskRecord getChildAt(int index) {
         return mTaskHistory.get(index);
     }
 
@@ -365,12 +365,12 @@
     private boolean mTopActivityOccludesKeyguard;
     private ActivityRecord mTopDismissingKeyguardActivity;
 
-    static final int PAUSE_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 1;
-    static final int DESTROY_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 2;
-    static final int LAUNCH_TICK_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 3;
-    static final int STOP_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 4;
-    static final int DESTROY_ACTIVITIES_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 5;
-    static final int TRANSLUCENT_TIMEOUT_MSG = ActivityManagerService.FIRST_ACTIVITY_STACK_MSG + 6;
+    static final int PAUSE_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 1;
+    static final int DESTROY_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 2;
+    static final int LAUNCH_TICK_MSG = FIRST_ACTIVITY_STACK_MSG + 3;
+    static final int STOP_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 4;
+    static final int DESTROY_ACTIVITIES_MSG = FIRST_ACTIVITY_STACK_MSG + 5;
+    static final int TRANSLUCENT_TIMEOUT_MSG = FIRST_ACTIVITY_STACK_MSG + 6;
 
     private static class ScheduleDestroyArgs {
         final WindowProcessController mOwner;
@@ -1102,16 +1102,14 @@
         if (!isActivityTypeHome() && returnsToHomeStack()) {
             // Make sure the home stack is behind this stack since that is where we should return to
             // when this stack is no longer visible.
-            // TODO(b/111541062): Move home stack on the current display
-            mStackSupervisor.moveHomeStackToFront(reason + " returnToHome");
+            display.moveHomeStackToFront(reason + " returnToHome");
         }
 
-        display.positionChildAtTop(this, true /* includingParents */);
-        mStackSupervisor.setFocusStackUnchecked(reason, this);
-        if (task != null) {
+        final boolean movingTask = task != null;
+        display.positionChildAtTop(this, !movingTask /* includingParents */, reason);
+        if (movingTask) {
             // This also moves the entire hierarchy branch to top, including parents
-            insertTaskAtTop(task, null);
-            return;
+            insertTaskAtTop(task, null /* starting */);
         }
     }
 
@@ -1132,13 +1130,11 @@
             setWindowingMode(WINDOWING_MODE_UNDEFINED);
         }
 
-        getDisplay().positionChildAtBottom(this);
-        mStackSupervisor.setFocusStackUnchecked(reason, getDisplay().getTopStack());
+        getDisplay().positionChildAtBottom(this, reason);
         if (task != null) {
             // TODO(b/111541062): We probably don't want to change display z-order to bottom just
             // because one of its stacks moved to bottom.
             insertTaskAtBottom(task);
-            return;
         }
     }
 
@@ -1147,6 +1143,10 @@
         return mStackSupervisor.isFocusable(this, r != null && r.isFocusable());
     }
 
+    boolean isFocusableAndVisible() {
+        return isFocusable() && shouldBeVisible(null /* starting */);
+    }
+
     final boolean isAttached() {
         return getParent() != null;
     }
@@ -1510,8 +1510,6 @@
         prev.getTask().touchActiveTime();
         clearLaunchTime(prev);
 
-        mStackSupervisor.getActivityMetricsLogger().stopFullyDrawnTraceIfNeeded();
-
         mService.updateCpuStats();
 
         if (prev.attachedToProcess()) {
@@ -1681,13 +1679,16 @@
         if (prev != null) {
             prev.resumeKeyDispatchingLocked();
 
-            final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
-            if (prev.hasProcess() && prev.cpuTimeAtResume > 0 && diff > 0) {
-                final Runnable r = PooledLambda.obtainRunnable(
-                        ActivityManagerInternal::updateForegroundTimeIfOnBattery,
-                        mService.mAmInternal, prev.info.packageName, prev.info.applicationInfo.uid,
-                        diff);
-                mService.mH.post(r);
+            if (prev.hasProcess() && prev.cpuTimeAtResume > 0) {
+                final long diff = prev.app.getCpuTime() - prev.cpuTimeAtResume;
+                if (diff > 0) {
+                    final Runnable r = PooledLambda.obtainRunnable(
+                            ActivityManagerInternal::updateForegroundTimeIfOnBattery,
+                            mService.mAmInternal, prev.info.packageName,
+                            prev.info.applicationInfo.uid,
+                            diff);
+                    mService.mH.post(r);
+                }
             }
             prev.cpuTimeAtResume = 0; // reset it
         }
@@ -2428,10 +2429,11 @@
         }
 
         next.delayedResume = false;
+        final ActivityDisplay display = getDisplay();
 
         // If the top activity is the resumed one, nothing to do.
         if (mResumedActivity == next && next.isState(RESUMED)
-                && mStackSupervisor.allResumedActivitiesComplete()) {
+                && display.allResumedActivitiesComplete()) {
             // Make sure we have executed any pending transitions, since there
             // should be nothing left to do at this point.
             executeAppTransition(options);
@@ -2497,7 +2499,7 @@
 
         boolean lastResumedCanPip = false;
         ActivityRecord lastResumed = null;
-        final ActivityStack lastFocusedStack = mStackSupervisor.getTopDisplayLastFocusedStack();
+        final ActivityStack lastFocusedStack = display.getLastFocusedStack();
         if (lastFocusedStack != null && lastFocusedStack != this) {
             // So, why aren't we using prev here??? See the param comment on the method. prev doesn't
             // represent the last resumed activity. However, the last focus stack does if it isn't null.
@@ -2542,7 +2544,7 @@
             }
             return true;
         } else if (mResumedActivity == next && next.isState(RESUMED)
-                && mStackSupervisor.allResumedActivitiesComplete()) {
+                && display.allResumedActivitiesComplete()) {
             // It is possible for the activity to be resumed when we paused back stacks above if the
             // next activity doesn't have to wait for pause to complete.
             // So, nothing else to-do except:
@@ -2658,7 +2660,6 @@
 
         mStackSupervisor.mNoAnimActivities.clear();
 
-        ActivityStack lastStack = mStackSupervisor.getTopDisplayLastFocusedStack();
         if (next.attachedToProcess()) {
             if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resume running: " + next
                     + " stopped=" + next.stopped + " visible=" + next.visible);
@@ -2670,10 +2671,10 @@
             // Launcher is already visible in this case. If we don't add it to opening
             // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
             // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
-            final boolean lastActivityTranslucent = lastStack != null
-                    && (lastStack.inMultiWindowMode()
-                    || (lastStack.mLastPausedActivity != null
-                    && !lastStack.mLastPausedActivity.fullscreen));
+            final boolean lastActivityTranslucent = lastFocusedStack != null
+                    && (lastFocusedStack.inMultiWindowMode()
+                    || (lastFocusedStack.mLastPausedActivity != null
+                    && !lastFocusedStack.mLastPausedActivity.fullscreen));
 
             // The contained logic must be synchronized, since we are both changing the visibility
             // and updating the {@link Configuration}. {@link ActivityRecord#setVisibility} will
@@ -2690,7 +2691,7 @@
                 next.startLaunchTickingLocked();
 
                 ActivityRecord lastResumedActivity =
-                        lastStack == null ? null :lastStack.mResumedActivity;
+                        lastFocusedStack == null ? null : lastFocusedStack.mResumedActivity;
                 final ActivityState lastState = next.getState();
 
                 mService.updateCpuStats();
@@ -2795,8 +2796,8 @@
                     Slog.i(TAG, "Restarting because process died: " + next);
                     if (!next.hasBeenLaunched) {
                         next.hasBeenLaunched = true;
-                    } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null
-                            && lastStack.isTopStackOnDisplay()) {
+                    } else  if (SHOW_APP_STARTING_PREVIEW && lastFocusedStack != null
+                            && lastFocusedStack.isTopStackOnDisplay()) {
                         next.showStartingWindow(null /* prev */, false /* newTask */,
                                 false /* taskSwitch */);
                     }
@@ -2854,9 +2855,7 @@
         if (DEBUG_STATES) Slog.d(TAG_STATES,
                 "resumeTopActivityInNextFocusableStack: " + reason + ", go home");
         if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
-        // Only resume home if on home display
-        return isOnHomeDisplay() &&
-                mStackSupervisor.resumeHomeStackTask(prev, reason);
+        return mStackSupervisor.resumeHomeActivity(prev, reason, mDisplayId);
     }
 
     /** Returns the position the input task should be placed in this stack. */
@@ -3450,8 +3449,10 @@
         final String myReason = reason + " adjustFocus";
 
         if (next == r) {
-            mStackSupervisor.moveFocusableActivityStackToFrontLocked(
-                    mStackSupervisor.topRunningActivityLocked(), myReason);
+            final ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
+            if (top != null) {
+                top.moveFocusableActivityToTop(myReason);
+            }
             return;
         }
 
@@ -3482,7 +3483,7 @@
         }
 
         // Whatever...go home.
-        mStackSupervisor.moveHomeStackTaskToTop(myReason);
+        getDisplay().moveHomeActivityToTop(myReason);
     }
 
     /**
@@ -3511,7 +3512,7 @@
         if (stack.isActivityTypeHome() && (top == null || !top.visible)) {
             // If we will be focusing on the home stack next and its current top activity isn't
             // visible, then use the move the home stack task to top to make the activity visible.
-            mStackSupervisor.moveHomeStackTaskToTop(reason);
+            stack.getDisplay().moveHomeActivityToTop(reason);
             return stack;
         }
 
@@ -3876,8 +3877,8 @@
         // 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.
-        final ActivityRecord next = mStackSupervisor.topRunningActivityLocked(
-                true /* considerKeyguardState */);
+        final ActivityDisplay display = getDisplay();
+        final ActivityRecord next = display.topRunningActivity(true /* considerKeyguardState */);
 
         if (mode == FINISH_AFTER_VISIBLE && (r.visible || r.nowVisible)
                 && next != null && !next.nowVisible) {
@@ -3901,23 +3902,25 @@
         if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r);
 
         r.setState(FINISHING, "finishCurrentActivityLocked");
-        final boolean finishingActivityInNonFocusedStack
-                = r.getStack() != mStackSupervisor.getTopDisplayFocusedStack()
-                && prevState == PAUSED && mode == FINISH_AFTER_VISIBLE;
+        final boolean finishingInNonFocusedStackOrNoRunning = mode == FINISH_AFTER_VISIBLE
+                && prevState == PAUSED && (r.getStack() != display.getFocusedStack()
+                        || (next == null && display.topRunningActivity() == null));
 
         if (mode == FINISH_IMMEDIATELY
                 || (prevState == PAUSED
                     && (mode == FINISH_AFTER_PAUSE || inPinnedWindowingMode()))
-                || finishingActivityInNonFocusedStack
+                || finishingInNonFocusedStackOrNoRunning
                 || prevState == STOPPING
                 || prevState == STOPPED
                 || prevState == ActivityState.INITIALIZING) {
             r.makeFinishingLocked();
             boolean activityRemoved = destroyActivityLocked(r, true, "finish-imm:" + reason);
 
-            if (finishingActivityInNonFocusedStack) {
+            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.
+                // 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.
                 mStackSupervisor.ensureVisibilityAndConfig(next, mDisplayId,
                         false /* markFrozenIfConfigChanged */, true /* deferResume */);
             }
@@ -4233,15 +4236,11 @@
      * Perform clean-up of service connections in an activity record.
      */
     private void cleanUpActivityServicesLocked(ActivityRecord r) {
-        // Throw away any services that have been bound by this activity.
-        if (r.connections != null) {
-            Iterator<ConnectionRecord> it = r.connections.iterator();
-            while (it.hasNext()) {
-                ConnectionRecord c = it.next();
-                mService.mAm.mServices.removeConnectionLocked(c, null, r);
-            }
-            r.connections = null;
+        if (r.mServiceConnectionsHolder == null) {
+            return;
         }
+        // Throw away any services that have been bound by this activity.
+        r.mServiceConnectionsHolder.disconnectActivityFromServices();
     }
 
     final void scheduleDestroyActivities(WindowProcessController owner, String reason) {
@@ -4619,22 +4618,6 @@
         mStackSupervisor.invalidateTaskLayers();
     }
 
-    void moveHomeStackTaskToTop() {
-        if (!isActivityTypeHome()) {
-            throw new IllegalStateException("Calling moveHomeStackTaskToTop() on non-home stack: "
-                    + this);
-        }
-        final int top = mTaskHistory.size() - 1;
-        if (top >= 0) {
-            final TaskRecord task = mTaskHistory.get(top);
-            if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG_STACK,
-                    "moveHomeStackTaskToTop: moving " + task);
-            mTaskHistory.remove(top);
-            mTaskHistory.add(top, task);
-            updateTaskMovement(task, true);
-        }
-    }
-
     final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, ActivityOptions options,
             AppTimeTracker timeTracker, String reason) {
         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
@@ -4682,7 +4665,9 @@
 
             // Set focus to the top running activity of this stack.
             final ActivityRecord r = topRunningActivityLocked();
-            mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, reason);
+            if (r != null) {
+                r.moveFocusableActivityToTop(reason);
+            }
 
             if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to front transition: task=" + tr);
             if (noAnimation) {
@@ -5223,11 +5208,11 @@
             if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this);
             // We only need to adjust focused stack if this stack is in focus and we are not in the
             // process of moving the task to the top of the stack that will be focused.
-            if (isOnHomeDisplay() && mode != REMOVE_TASK_MODE_MOVING_TO_TOP
+            if (mode != REMOVE_TASK_MODE_MOVING_TO_TOP
                     && mStackSupervisor.isTopDisplayFocusedStack(this)) {
                 String myReason = reason + " leftTaskHistoryEmpty";
                 if (!inMultiWindowMode() || adjustFocusToNextFocusableStack(myReason) == null) {
-                    mStackSupervisor.moveHomeStackToFront(myReason);
+                    getDisplay().moveHomeStackToFront(myReason);
                 }
             }
             if (isAttached()) {
@@ -5434,7 +5419,7 @@
 
         // Do not sleep activities in this stack if we're marked as focused and the keyguard
         // is in the process of going away.
-        if (mStackSupervisor.getTopDisplayFocusedStack() == this
+        if (isFocusedStackOnDisplay()
                 && mStackSupervisor.getKeyguardController().isKeyguardGoingAway()) {
             return false;
         }
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 9688d26..257a004 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -21,8 +21,12 @@
 import static android.Manifest.permission.START_ANY_ACTIVITY;
 import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
+import static android.app.ActivityManager.START_FLAG_DEBUG;
+import static android.app.ActivityManager.START_FLAG_NATIVE_DEBUGGING;
+import static android.app.ActivityManager.START_FLAG_TRACK_ALLOCATION;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
 import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
 import static android.app.WaitResult.INVALID_DELAY;
@@ -40,6 +44,9 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.app.WindowConfiguration.activityTypeToString;
 import static android.app.WindowConfiguration.windowingModeToString;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
+import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
+import static android.content.pm.PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY;
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.graphics.Rect.copyOrNull;
@@ -51,30 +58,6 @@
 import static android.view.Display.TYPE_VIRTUAL;
 import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IDLE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PAUSE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IDLE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PAUSE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STATES;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
-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.ActivityManagerService.ANIMATE;
-import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
-import static com.android.server.am.ActivityRecord.RELAUNCH_REASON_NONE;
 import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
 import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
@@ -90,7 +73,28 @@
 import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
 import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
 import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
-import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IDLE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STATES;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IDLE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_PAUSE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STATES;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityTaskManagerService.ANIMATE;
+import static com.android.server.am.ActivityTaskManagerService.H.FIRST_SUPERVISOR_STACK_MSG;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
@@ -112,6 +116,7 @@
 import android.app.ActivityManagerInternal;
 import android.app.ActivityOptions;
 import android.app.AppOpsManager;
+import android.app.IApplicationThread;
 import android.app.ProfilerInfo;
 import android.app.ResultInfo;
 import android.app.WaitResult;
@@ -132,6 +137,7 @@
 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.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManager.DisplayListener;
@@ -156,6 +162,7 @@
 import android.service.voice.IVoiceInteractionSession;
 import android.util.ArrayMap;
 import android.util.ArraySet;
+import android.util.DisplayMetrics;
 import android.util.EventLog;
 import android.util.IntArray;
 import android.util.MergedConfiguration;
@@ -195,8 +202,7 @@
 
 public class ActivityStackSupervisor extends ConfigurationContainer implements DisplayListener,
         RecentTasks.Callbacks, RootWindowContainerListener {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_AM;
-    private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStackSupervisor" : TAG_ATM;
     private static final String TAG_IDLE = TAG + POSTFIX_IDLE;
     private static final String TAG_PAUSE = TAG + POSTFIX_PAUSE;
     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
@@ -335,15 +341,6 @@
     /** The current user */
     int mCurrentUser;
 
-    /** The stack containing the launcher app. Assumed to always be attached to
-     * Display.DEFAULT_DISPLAY. */
-    ActivityStack mHomeStack;
-
-    /** If this is the same as mFocusedStack then the activity on the top of the focused stack has
-     * been resumed. If stacks are changing position this will hold the old stack until the new
-     * stack becomes resumed after which it will be set to mFocusedStack. */
-    private ActivityStack mLastFocusedStack;
-
     /** List of activities that are waiting for a new activity to become visible before completing
      * whatever operation they are supposed to do. */
     // TODO: Remove mActivitiesWaitingForVisibleActivity list and just remove activity from
@@ -445,7 +442,7 @@
 
     // The default minimal size that will be used if the activity doesn't specify its minimal size.
     // It will be calculated when the default display gets added.
-    int mDefaultMinSizeOfResizeableTask = -1;
+    int mDefaultMinSizeOfResizeableTaskDp = -1;
 
     // Whether tasks have moved and we need to rank the tasks before next OOM scoring
     private boolean mTaskLayersChanged = true;
@@ -689,12 +686,12 @@
                 mDefaultDisplay = activityDisplay;
             }
             addChild(activityDisplay, ActivityDisplay.POSITION_TOP);
-            calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
         }
+        calculateDefaultMinimalSizeOfResizeableTasks();
 
         final ActivityDisplay defaultDisplay = getDefaultDisplay();
-        mHomeStack = mLastFocusedStack = defaultDisplay.getOrCreateStack(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
+
+        defaultDisplay.getOrCreateStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
         positionChildAt(defaultDisplay, ActivityDisplay.POSITION_TOP);
     }
 
@@ -734,10 +731,6 @@
     }
 
     ActivityRecord getTopResumedActivity() {
-        if (mWindowManager == null) {
-            return null;
-        }
-
         final ActivityStack focusedStack = getTopDisplayFocusedStack();
         if (focusedStack == null) {
             return null;
@@ -766,47 +759,10 @@
         return container.getWindowConfiguration().canReceiveKeys() || alwaysFocusable;
     }
 
-    ActivityStack getTopDisplayLastFocusedStack() {
-        return mLastFocusedStack;
-    }
-
     boolean isTopDisplayFocusedStack(ActivityStack stack) {
         return stack != null && stack == getTopDisplayFocusedStack();
     }
 
-    /** NOTE: Should only be called from {@link ActivityStack#moveToFront} */
-    void setFocusStackUnchecked(String reason, ActivityStack focusCandidate) {
-        if (!focusCandidate.isFocusable()) {
-            // The focus candidate isn't focusable. Move focus to the top stack that is focusable.
-            focusCandidate = getNextFocusableStackLocked(focusCandidate, false /* ignoreCurrent */);
-            if (focusCandidate == null) {
-                Slog.w(TAG,
-                        "setFocusStackUnchecked: No focusable stack found, focus home as default");
-                focusCandidate = mHomeStack;
-            }
-        }
-
-        final ActivityStack currentFocusedStack = getTopDisplayFocusedStack();
-        if (currentFocusedStack != focusCandidate) {
-            mLastFocusedStack = currentFocusedStack;
-            // TODO(b/111541062): Update event log to include focus movements on all displays
-            EventLogTags.writeAmFocusedStack(
-                    mCurrentUser, focusCandidate == null ? -1 : focusCandidate.getStackId(),
-                    mLastFocusedStack == null ? -1 : mLastFocusedStack.getStackId(), reason);
-        }
-
-        final ActivityRecord r = topRunningActivityLocked();
-        if (mService.isBooting() || !mService.isBooted()) {
-            if (r != null && r.idle) {
-                checkFinishBootingLocked();
-            }
-        }
-    }
-
-    void moveHomeStackToFront(String reason) {
-        mHomeStack.moveToFront(reason);
-    }
-
     void moveRecentsStackToFront(String reason) {
         final ActivityStack recentsStack = getDefaultDisplay().getStack(
                 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_RECENTS);
@@ -815,34 +771,48 @@
         }
     }
 
-    /** Returns true if the focus activity was adjusted to the home stack top activity. */
-    boolean moveHomeStackTaskToTop(String reason) {
-        mHomeStack.moveHomeStackTaskToTop();
-
-        final ActivityRecord top = getHomeActivity();
-        if (top == null) {
-            return false;
-        }
-        moveFocusableActivityStackToFrontLocked(top, reason);
-        return true;
-    }
-
-    boolean resumeHomeStackTask(ActivityRecord prev, String reason) {
+    boolean resumeHomeActivity(ActivityRecord prev, String reason, int displayId) {
         if (!mService.isBooting() && !mService.isBooted()) {
             // Not ready yet!
             return false;
         }
 
-        mHomeStack.moveHomeStackTaskToTop();
-        ActivityRecord r = getHomeActivity();
-        final String myReason = reason + " resumeHomeStackTask";
+        if (displayId == INVALID_DISPLAY) {
+            displayId = DEFAULT_DISPLAY;
+        }
+
+        final ActivityRecord r = getActivityDisplay(displayId).getHomeActivity();
+        final String myReason = reason + " resumeHomeActivity";
 
         // Only resume home activity if isn't finishing.
         if (r != null && !r.finishing) {
-            moveFocusableActivityStackToFrontLocked(r, myReason);
-            return resumeFocusedStacksTopActivitiesLocked(mHomeStack, prev, null);
+            r.moveFocusableActivityToTop(myReason);
+            return resumeFocusedStacksTopActivitiesLocked(r.getStack(), prev, null);
         }
-        return mService.mAm.startHomeActivityLocked(mCurrentUser, myReason);
+        return mService.startHomeActivityLocked(mCurrentUser, myReason, displayId);
+    }
+
+    boolean canStartHomeOnDisplay(ActivityInfo homeActivity, int displayId) {
+        if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
+                && displayId == mService.mVr2dDisplayId)) {
+            // No restrictions to default display or vr 2d display.
+            return true;
+        }
+
+        final ActivityDisplay display = getActivityDisplay(displayId);
+        if (display == null || display.isRemoved() || !display.supportsSystemDecorations()) {
+            // Can't launch home on display that doesn't support system decorations.
+            return false;
+        }
+
+        final boolean supportMultipleInstance = homeActivity.launchMode != LAUNCH_SINGLE_TASK
+                && homeActivity.launchMode != LAUNCH_SINGLE_INSTANCE;
+        if (!supportMultipleInstance) {
+            // Can't launch home on other displays if it requested to be single instance.
+            return false;
+        }
+
+        return true;
     }
 
     TaskRecord anyTaskForIdLocked(int id) {
@@ -1029,8 +999,8 @@
         return candidateTaskId;
     }
 
-    boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
-        final String processName = app.processName;
+    boolean attachApplicationLocked(WindowProcessController app) throws RemoteException {
+        final String processName = app.mName;
         boolean didSomething = false;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
             final ActivityDisplay display = mActivityDisplays.get(displayNdx);
@@ -1044,7 +1014,7 @@
                 final int size = mTmpActivityList.size();
                 for (int i = 0; i < size; i++) {
                     final ActivityRecord activity = mTmpActivityList.get(i);
-                    if (activity.app == null && app.uid == activity.info.applicationInfo.uid
+                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                             && processName.equals(activity.processName)) {
                         try {
                             if (realStartActivityLocked(activity, app,
@@ -1087,28 +1057,6 @@
         return true;
     }
 
-    boolean allResumedActivitiesComplete() {
-        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
-            final ActivityDisplay display = mActivityDisplays.get(displayNdx);
-            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
-                final ActivityStack stack = display.getChildAt(stackNdx);
-                if (isTopDisplayFocusedStack(stack)) {
-                    final ActivityRecord r = stack.getResumedActivity();
-                    if (r != null && !r.isState(RESUMED)) {
-                        return false;
-                    }
-                }
-            }
-        }
-        // TODO: Not sure if this should check if all Paused are complete too.
-        final ActivityStack focusedStack = getTopDisplayFocusedStack();
-        if (DEBUG_STACK) Slog.d(TAG_STACK,
-                "allResumedActivitiesComplete: mLastFocusedStack changing from="
-                        + mLastFocusedStack + " to=" + focusedStack);
-        mLastFocusedStack = focusedStack;
-        return true;
-    }
-
     private boolean allResumedActivitiesVisible() {
         boolean foundResumed = false;
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
@@ -1266,75 +1214,15 @@
     }
 
     ActivityRecord topRunningActivityLocked() {
-        return topRunningActivityLocked(false /* considerKeyguardState */);
-    }
-
-    /**
-     * Returns the top running activity in the focused stack. In the case the focused stack has no
-     * such activity, the next focusable stack on top of a display is returned.
-     * @param considerKeyguardState Indicates whether the locked state should be considered. if
-     *                            {@code true} and the keyguard is locked, only activities that
-     *                            can be shown on top of the keyguard will be considered.
-     * @return The top running activity. {@code null} if none is available.
-     */
-    ActivityRecord topRunningActivityLocked(boolean considerKeyguardState) {
-        final ActivityStack focusedStack = getTopDisplayFocusedStack();
-        ActivityRecord r = focusedStack.topRunningActivityLocked();
-        if (r != null && isValidTopRunningActivity(r, considerKeyguardState)) {
-            return r;
-        }
-
-        // Look in other non-focused and non-home stacks.
         for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
-            final ActivityDisplay display = mActivityDisplays.get(i);
-
-            // TODO: We probably want to consider the top fullscreen stack as we could have a pinned
-            // stack on top.
-            final ActivityStack topStack = display.getTopStack();
-
-            // Only consider focusable top stacks other than the current focused one.
-            if (topStack == null || !topStack.isFocusable() || topStack == focusedStack) {
-                continue;
-            }
-
-            final ActivityRecord topActivity = topStack.topRunningActivityLocked();
-
-            // Skip if no top activity.
-            if (topActivity == null) {
-                continue;
-            }
-
-
-            // This activity can be considered the top running activity if we are not
-            // considering the locked state, the keyguard isn't locked, or we can show when
-            // locked.
-            if (isValidTopRunningActivity(topActivity, considerKeyguardState)) {
+            final ActivityRecord topActivity = mActivityDisplays.get(i).topRunningActivity();
+            if (topActivity != null) {
                 return topActivity;
             }
         }
-
         return null;
     }
 
-    /**
-     * Verifies an {@link ActivityRecord} can be the top activity based on keyguard state and
-     * whether we are considering it.
-     */
-    private boolean isValidTopRunningActivity(ActivityRecord record,
-            boolean considerKeyguardState) {
-        if (!considerKeyguardState) {
-            return true;
-        }
-
-        final boolean keyguardLocked = getKeyguardController().isKeyguardLocked();
-
-        if (!keyguardLocked) {
-            return true;
-        }
-
-        return record.canShowWhenLocked();
-    }
-
     @VisibleForTesting
     void getRunningTasks(int maxNum, List<RunningTaskInfo> list,
             @ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode,
@@ -1356,20 +1244,17 @@
 
             // Don't debug things in the system process
             if (!aInfo.processName.equals("system")) {
-                if ((startFlags & ActivityManager.START_FLAG_DEBUG) != 0) {
-                    mService.mAm.setDebugApp(aInfo.processName, true, false);
-                }
-
-                if ((startFlags & ActivityManager.START_FLAG_NATIVE_DEBUGGING) != 0) {
-                    mService.mAm.setNativeDebuggingAppLocked(aInfo.applicationInfo, aInfo.processName);
-                }
-
-                if ((startFlags & ActivityManager.START_FLAG_TRACK_ALLOCATION) != 0) {
-                    mService.mAm.setTrackAllocationApp(aInfo.applicationInfo, aInfo.processName);
-                }
-
-                if (profilerInfo != null) {
-                    mService.mAm.setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo);
+                if ((startFlags & (START_FLAG_DEBUG | START_FLAG_NATIVE_DEBUGGING
+                        | START_FLAG_TRACK_ALLOCATION)) != 0 || profilerInfo != null) {
+                    /**
+                     * Assume safe to call into AMS synchronously because the call that set these
+                     * flags should have originated from AMS which will already have its lock held.
+                     * @see ActivityManagerService#startActivityAndWait(IApplicationThread, String,
+                     * Intent, String, IBinder, String, int, int, ProfilerInfo, Bundle, int)
+                     * TODO(b/80414790): Investigate a better way of untangling this.
+                     */
+                    mService.mAmInternal.setDebugFlagsForStartingActivity(
+                            aInfo, startFlags, profilerInfo);
                 }
             }
             final String intentLaunchToken = intent.getLaunchToken();
@@ -1416,7 +1301,7 @@
         return resolveActivity(intent, rInfo, startFlags, profilerInfo);
     }
 
-    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
+    private boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
             boolean andResume, boolean checkConfig) throws RemoteException {
 
         if (!allPausedActivitiesComplete()) {
@@ -1435,7 +1320,6 @@
         beginDeferResume();
 
         try {
-            final WindowProcessController proc = app.getWindowProcessController();
             r.startFreezingScreenLocked(proc, 0);
 
             // schedule launch ticks to collect information about slow apps.
@@ -1471,15 +1355,15 @@
 
             final int applicationInfoUid =
                     (r.info.applicationInfo != null) ? r.info.applicationInfo.uid : -1;
-            if ((r.userId != app.userId) || (r.appInfo.uid != applicationInfoUid)) {
+            if ((r.userId != proc.mUserId) || (r.appInfo.uid != applicationInfoUid)) {
                 Slog.wtf(TAG,
                         "User ID for activity changing for " + r
                                 + " appInfo.uid=" + r.appInfo.uid
                                 + " info.ai.uid=" + applicationInfoUid
-                                + " old=" + r.app + " new=" + app);
+                                + " old=" + r.app + " new=" + proc);
             }
 
-            app.waitingToKill = null;
+            proc.clearWaitingToKill();
             r.launchCount++;
             r.lastLaunchTime = SystemClock.uptimeMillis();
 
@@ -1498,7 +1382,7 @@
             }
 
             try {
-                if (app.thread == null) {
+                if (!proc.hasThread()) {
                     throw new RemoteException();
                 }
                 List<ResultInfo> results = null;
@@ -1518,56 +1402,35 @@
                     // Home process is the root process of the task.
                     mService.mHomeProcess = task.mActivities.get(0).app;
                 }
-                mService.mAm.notifyPackageUse(r.intent.getComponent().getPackageName(),
-                        PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY);
+                mService.getPackageManagerInternalLocked().notifyPackageUse(
+                        r.intent.getComponent().getPackageName(), NOTIFY_PACKAGE_USE_ACTIVITY);
                 r.sleeping = false;
                 r.forceNewConfig = false;
                 mService.getAppWarningsLocked().onStartActivity(r);
                 r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
-                ProfilerInfo profilerInfo = null;
-                if (mService.mAm.mProfileApp != null && mService.mAm.mProfileApp.equals(app.processName)) {
-                    if (mService.mAm.mProfileProc == null || mService.mAm.mProfileProc == app) {
-                        mService.mAm.mProfileProc = app;
-                        ProfilerInfo profilerInfoSvc = mService.mAm.mProfilerInfo;
-                        if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
-                            if (profilerInfoSvc.profileFd != null) {
-                                try {
-                                    profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
-                                } catch (IOException e) {
-                                    profilerInfoSvc.closeFd();
-                                }
-                            }
+                ProfilerInfo profilerInfo = proc.onStartActivity(mService.mTopProcessState);
 
-                            profilerInfo = new ProfilerInfo(profilerInfoSvc);
-                        }
-                    }
-                }
-
-                app.hasShownUi = true;
-                app.pendingUiClean = true;
-                app.forceProcessStateUpTo(mService.mTopProcessState);
                 // Because we could be starting an Activity in the system process this may not go
                 // across a Binder interface which would create a new Configuration. Consequently
                 // we have to always create a new Configuration here.
 
                 final MergedConfiguration mergedConfiguration = new MergedConfiguration(
-                        app.getWindowProcessController().getConfiguration(),
-                        r.getMergedOverrideConfiguration());
+                        proc.getConfiguration(), r.getMergedOverrideConfiguration());
                 r.setLastReportedConfiguration(mergedConfiguration);
 
                 logIfTransactionTooLarge(r.intent, r.icicle);
 
 
                 // Create activity launch transaction.
-                final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
-                        r.appToken);
+                final ClientTransaction clientTransaction = ClientTransaction.obtain(
+                        proc.getThread(), r.appToken);
                 clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                         System.identityHashCode(r), r.info,
                         // TODO: Have this take the merged configuration instead of separate global
                         // and override configs.
                         mergedConfiguration.getGlobalConfiguration(),
                         mergedConfiguration.getOverrideConfiguration(), r.compat,
-                        r.launchedFromPackage, task.voiceInteractor, app.getReportedProcState(),
+                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                         r.icicle, r.persistentState, results, newIntents,
                         mService.isNextTransitionForward(), profilerInfo));
 
@@ -1583,12 +1446,12 @@
                 // Schedule transaction.
                 mService.getLifecycleManager().scheduleTransaction(clientTransaction);
 
-                if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
-                        && mService.mAm.mHasHeavyWeightFeature) {
+                if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
+                        && mService.mHasHeavyWeightFeature) {
                     // This may be a heavy-weight process! Note that the package manager will ensure
                     // that only activity can run in the main process of the .apk, which is the only
                     // thing that will be considered heavy-weight.
-                    if (app.processName.equals(app.info.packageName)) {
+                    if (proc.mName.equals(proc.mInfo.packageName)) {
                         if (mService.mHeavyWeightProcess != null
                                 && mService.mHeavyWeightProcess != proc) {
                             Slog.w(TAG, "Starting new heavy weight process " + proc
@@ -1601,12 +1464,10 @@
 
             } catch (RemoteException e) {
                 if (r.launchFailed) {
-                    // This is the second time we failed -- finish activity
-                    // and give up.
+                    // This is the second time we failed -- finish activity and give up.
                     Slog.e(TAG, "Second failure launching "
-                            + r.intent.getComponent().flattenToShortString()
-                            + ", giving up", e);
-                    mService.mAm.appDiedLocked(app);
+                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
+                    proc.appDied();
                     stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                             "2nd-crash", false);
                     return false;
@@ -1715,24 +1576,21 @@
         }
     }
 
-    void startSpecificActivityLocked(ActivityRecord r,
-            boolean andResume, boolean checkConfig) {
+    void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
         // Is this activity's application already running?
-        ProcessRecord app = mService.mAm.getProcessRecordLocked(r.processName,
-                r.info.applicationInfo.uid, true);
+        final WindowProcessController wpc =
+                mService.getProcessController(r.processName, r.info.applicationInfo.uid);
 
-        if (app != null && app.thread != null) {
+        if (wpc != null && wpc.hasThread()) {
             try {
-                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
+                if ((r.info.flags & ActivityInfo.FLAG_MULTIPROCESS) == 0
                         || !"android".equals(r.info.packageName)) {
-                    // Don't add this if it is a platform component that is marked
-                    // to run in multiple processes, because this is actually
-                    // part of the framework so doesn't make sense to track as a
-                    // separate apk in the process.
-                    app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
-                            mService.mAm.mProcessStats);
+                    // Don't add this if it is a platform component that is marked to run in
+                    // multiple processes, because this is actually part of the framework so doesn't
+                    // make sense to track as a separate apk in the process.
+                    wpc.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode);
                 }
-                realStartActivityLocked(r, app, andResume, checkConfig);
+                realStartActivityLocked(r, wpc, andResume, checkConfig);
                 return;
             } catch (RemoteException e) {
                 Slog.w(TAG, "Exception when starting activity "
@@ -1743,8 +1601,12 @@
             // restart the application.
         }
 
-        mService.mAm.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
-                "activity", r.intent.getComponent(), false, false, true);
+        // 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, true, "activity", r.intent.getComponent());
+        mService.mH.sendMessage(msg);
     }
 
     void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
@@ -1774,24 +1636,25 @@
             sendHint = noResumedActivities || allFocusedProcessesDiffer;
         }
 
-        if (sendHint && mService.mAm.mLocalPowerManager != null) {
-            mService.mAm.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 1);
+        if (sendHint && mService.mPowerManagerInternal != null) {
+            mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 1);
             mPowerHintSent = true;
         }
     }
 
     void sendPowerHintForLaunchEndIfNeeded() {
         // Trigger launch power hint if activity is launched
-        if (mPowerHintSent && mService.mAm.mLocalPowerManager != null) {
-            mService.mAm.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 0);
+        if (mPowerHintSent && mService.mPowerManagerInternal != null) {
+            mService.mPowerManagerInternal.powerHint(PowerHint.LAUNCH, 0);
             mPowerHintSent = false;
         }
     }
 
-    boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo,
-            String resultWho, int requestCode, int callingPid, int callingUid,
-            String callingPackage, boolean ignoreTargetSecurity, boolean launchingInTask,
-            ProcessRecord callerApp, ActivityRecord resultRecord, ActivityStack resultStack) {
+    boolean checkStartAnyActivityPermission(Intent intent, ActivityInfo aInfo, String resultWho,
+            int requestCode, int callingPid, int callingUid, String callingPackage,
+            boolean ignoreTargetSecurity, boolean launchingInTask,
+            WindowProcessController callerApp, ActivityRecord resultRecord,
+            ActivityStack resultStack) {
         final boolean isCallerRecents = mService.getRecentTasks() != null
                 && mService.getRecentTasks().isCallerRecents(callingUid);
         final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
@@ -1953,7 +1816,7 @@
 
     private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo,
             String callingPackage, int callingPid, int callingUid, boolean ignoreTargetSecurity) {
-        if (!ignoreTargetSecurity && mService.mAm.checkComponentPermission(activityInfo.permission,
+        if (!ignoreTargetSecurity && mService.checkComponentPermission(activityInfo.permission,
                 callingPid, callingUid, activityInfo.applicationInfo.uid, activityInfo.exported)
                 == PERMISSION_DENIED) {
             return ACTIVITY_RESTRICTION_PERMISSION;
@@ -2206,7 +2069,8 @@
      */
     void updateUserStackLocked(int userId, ActivityStack stack) {
         if (userId != mCurrentUser) {
-            mUserStackInFront.put(userId, stack != null ? stack.getStackId() : mHomeStack.mStackId);
+            mUserStackInFront.put(userId, stack != null ? stack.getStackId()
+                    : getDefaultDisplay().getHomeStack().mStackId);
         }
     }
 
@@ -2275,7 +2139,8 @@
             return false;
         }
 
-        if (targetStack != null && targetStack.isTopStackOnDisplay()) {
+        if (targetStack != null && (targetStack.isTopStackOnDisplay()
+                || getTopDisplayFocusedStack() == targetStack)) {
             return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
         }
 
@@ -2312,9 +2177,9 @@
      * Finish the topmost activities in all stacks that belong to the crashed app.
      * @param app The app that crashed.
      * @param reason Reason to perform this action.
-     * @return The task that was finished in this stack, {@code null} if haven't found any.
+     * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
      */
-    TaskRecord finishTopCrashedActivitiesLocked(WindowProcessController app, String reason) {
+    int finishTopCrashedActivitiesLocked(WindowProcessController app, String reason) {
         TaskRecord finishedTask = null;
         ActivityStack focusedStack = getTopDisplayFocusedStack();
         for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
@@ -2329,7 +2194,7 @@
                 }
             }
         }
-        return finishedTask;
+        return finishedTask != null ? finishedTask.taskId : INVALID_TASK_ID;
     }
 
     void finishVoiceTask(IVoiceInteractionSession session) {
@@ -2348,7 +2213,7 @@
      */
     void findTaskToMoveToFront(TaskRecord task, int flags, ActivityOptions options, String reason,
             boolean forceNonResizeable) {
-        final ActivityStack currentStack = task.getStack();
+        ActivityStack currentStack = task.getStack();
         if (currentStack == null) {
             Slog.e(TAG, "findTaskToMoveToFront: can't move task="
                     + task + " to front. Stack is null");
@@ -2359,15 +2224,8 @@
             mUserLeaving = true;
         }
 
-        final ActivityRecord prev = topRunningActivityLocked();
-
-        if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0
-                || (prev != null && prev.isActivityTypeRecents())) {
-            // Caller wants the home activity moved with it or the previous task is recents in which
-            // case we always return home from the task we are moving to the front.
-            moveHomeStackToFront("findTaskToMoveToFront");
-        }
-
+        reason = reason + " findTaskToMoveToFront";
+        boolean reparented = false;
         if (task.isResizeable() && canUseActivityOptionsLaunchBounds(options)) {
             final Rect bounds = options.getLaunchBounds();
             task.updateOverrideConfiguration(bounds);
@@ -2375,10 +2233,12 @@
             ActivityStack stack = getLaunchStack(null, options, task, ON_TOP);
 
             if (stack != currentStack) {
+                moveHomeStackToFrontIfNeeded(flags, stack.getDisplay(), reason);
                 task.reparent(stack, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, !ANIMATE, DEFER_RESUME,
-                        "findTaskToMoveToFront");
-                stack = currentStack;
-                // moveTaskToStackUncheckedLocked() should already placed the task on top,
+                        reason);
+                currentStack = stack;
+                reparented = true;
+                // task.reparent() should already placed the task on top,
                 // still need moveTaskToFrontLocked() below for any transition settings.
             }
             if (stack.resizeStackWithLaunchBounds()) {
@@ -2393,6 +2253,10 @@
             }
         }
 
+        if (!reparented) {
+            moveHomeStackToFrontIfNeeded(flags, currentStack.getDisplay(), reason);
+        }
+
         final ActivityRecord r = task.getTopActivity();
         currentStack.moveTaskToFrontLocked(task, false /* noAnimation */, options,
                 r == null ? null : r.appTimeTracker, reason);
@@ -2404,6 +2268,18 @@
                 currentStack, forceNonResizeable);
     }
 
+    private void moveHomeStackToFrontIfNeeded(int flags, ActivityDisplay display, String reason) {
+        final ActivityStack focusedStack = display.getFocusedStack();
+
+        if ((display.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+                && (flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0)
+                || (focusedStack != null && focusedStack.isActivityTypeRecents())) {
+            // We move home stack to front when we are on a fullscreen display and caller has
+            // requested the home activity to move with it. Or the previous stack is recents.
+            display.moveHomeStackToFront(reason);
+        }
+    }
+
     boolean canUseActivityOptionsLaunchBounds(ActivityOptions options) {
         // We use the launch bounds in the activity options is the device supports freeform
         // window management or is launching into the pinned stack.
@@ -2509,7 +2385,7 @@
         }
         if (displayId != INVALID_DISPLAY && canLaunchOnDisplay(r, displayId)) {
             if (r != null) {
-                stack = (T) getValidLaunchStackOnDisplay(displayId, r, options);
+                stack = (T) getValidLaunchStackOnDisplay(displayId, r, candidateTask, options);
                 if (stack != null) {
                     return stack;
                 }
@@ -2574,10 +2450,11 @@
      * If there is no such stack, new dynamic stack can be created.
      * @param displayId Target display.
      * @param r Activity that should be launched there.
+     * @param candidateTask The possible task the activity might be put in.
      * @return Existing stack if there is a valid one, new dynamic stack if it is valid or null.
      */
     ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
-            @Nullable ActivityOptions options) {
+            @Nullable TaskRecord candidateTask, @Nullable ActivityOptions options) {
         final ActivityDisplay activityDisplay = getActivityDisplayOrCreateLocked(displayId);
         if (activityDisplay == null) {
             throw new IllegalArgumentException(
@@ -2588,6 +2465,13 @@
             return null;
         }
 
+        // If {@code r} is already in target display and its task is the same as the candidate task,
+        // the intention should be getting a launch stack for the reusable activity, so we can use
+        // the existing stack.
+        if (r.getDisplayId() == displayId && r.getTask() == candidateTask) {
+            return candidateTask.getStack();
+        }
+
         // Return the topmost valid stack on the display.
         for (int i = activityDisplay.getChildCount() - 1; i >= 0; --i) {
             final ActivityStack stack = activityDisplay.getChildAt(i);
@@ -2608,6 +2492,11 @@
         return null;
     }
 
+    ActivityStack getValidLaunchStackOnDisplay(int displayId, @NonNull ActivityRecord r,
+            @Nullable ActivityOptions options) {
+        return getValidLaunchStackOnDisplay(displayId, r, null /* candidateTask */, options);
+    }
+
     // TODO: Can probably be consolidated into getLaunchStack()...
     private boolean isValidLaunchStack(ActivityStack stack, int displayId, ActivityRecord r) {
         switch (stack.getActivityType()) {
@@ -2644,6 +2533,12 @@
         if (preferredFocusableStack != null) {
             return preferredFocusableStack;
         }
+        if (preferredDisplay.supportsSystemDecorations()) {
+            // Stop looking for focusable stack on other displays because the preferred display
+            // supports system decorations. Home activity would be launched on the same display if
+            // no focusable stack found.
+            return null;
+        }
 
         // Now look through all displays
         for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
@@ -2687,25 +2582,12 @@
         return null;
     }
 
-    ActivityRecord getHomeActivity() {
-        return getHomeActivityForUser(mCurrentUser);
+    ActivityRecord getDefaultDisplayHomeActivity() {
+        return getDefaultDisplayHomeActivityForUser(mCurrentUser);
     }
 
-    ActivityRecord getHomeActivityForUser(int userId) {
-        final ArrayList<TaskRecord> tasks = mHomeStack.getAllTasks();
-        for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
-            final TaskRecord task = tasks.get(taskNdx);
-            if (task.isActivityTypeHome()) {
-                final ArrayList<ActivityRecord> activities = task.mActivities;
-                for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
-                    final ActivityRecord r = activities.get(activityNdx);
-                    if (r.isActivityTypeHome()
-                            && ((userId == UserHandle.USER_ALL) || (r.userId == userId))) {
-                        return r;
-                    }
-                }
-            }
-        }
+    ActivityRecord getDefaultDisplayHomeActivityForUser(int userId) {
+        getActivityDisplay(DEFAULT_DISPLAY).getHomeActivityForUser(userId);
         return null;
     }
 
@@ -3132,7 +3014,9 @@
         }
 
         // Find any running services associated with this app and stop if needed.
-        mService.mAm.mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
+        final Message msg = PooledLambda.obtainMessage(ActivityManagerInternal::cleanUpServices,
+                mService.mAmInternal, tr.userId, component, new Intent(tr.getBaseIntent()));
+        mService.mH.sendMessage(msg);
 
         if (!killProcess) {
             return;
@@ -3418,40 +3302,6 @@
         mService.getTaskChangeNotificationController().notifyActivityPinned(r);
     }
 
-    /** Move activity with its stack to front and make the stack focused. */
-    boolean moveFocusableActivityStackToFrontLocked(ActivityRecord r, String reason) {
-        if (r == null || !r.isFocusable()) {
-            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
-                    "moveActivityStackToFront: unfocusable r=" + r);
-            return false;
-        }
-
-        final TaskRecord task = r.getTask();
-        final ActivityStack stack = r.getStack();
-        if (stack == null) {
-            Slog.w(TAG, "moveActivityStackToFront: invalid task or stack: r="
-                    + r + " task=" + task);
-            return false;
-        }
-
-        if (r == getTopResumedActivity()) {
-            if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
-                    "moveActivityStackToFront: already on top, r=" + r);
-            return false;
-        }
-
-        if (DEBUG_FOCUS) Slog.d(TAG_FOCUS,
-                "moveActivityStackToFront: r=" + r);
-
-        stack.moveToFront(reason, task);
-        // Report top activity change to tracking services and WM
-        if (r == getTopResumedActivity()) {
-            // TODO(b/111361570): Support multiple focused apps in WM
-            mService.setResumedActivityUncheckLocked(r, reason);
-        }
-        return true;
-    }
-
     ActivityRecord findTaskLocked(ActivityRecord r, int preferredDisplayId) {
         if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Looking for task of " + r);
         mTmpFindTaskResult.clear();
@@ -3516,7 +3366,7 @@
                     throw new IllegalStateException("Calling must be system uid");
                 }
                 mLaunchingActivity.release();
-                mService.mAm.mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
+                mHandler.removeMessages(LAUNCH_TIMEOUT_MSG);
             }
         }
 
@@ -3588,7 +3438,7 @@
                     stack.goToSleepIfPossible(false /* shuttingDown */);
                 } else {
                     stack.awakeFromSleepingLocked();
-                    if (isTopDisplayFocusedStack(stack) && !getKeyguardController()
+                    if (stack.isFocusedStackOnDisplay() && !getKeyguardController()
                             .isKeyguardOrAodShowing(display.mDisplayId)) {
                         // If the keyguard is unlocked - resume immediately.
                         // It is possible that the display will not be awake at the time we
@@ -3671,7 +3521,7 @@
         if (isTopDisplayFocusedStack(stack)) {
             mService.updateUsageStats(r, true);
         }
-        if (allResumedActivitiesComplete()) {
+        if (stack.getDisplay().allResumedActivitiesComplete()) {
             ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
             mWindowManager.executeAppTransition();
             return true;
@@ -3828,7 +3678,8 @@
         removeStacksInWindowingModes(WINDOWING_MODE_PINNED);
 
         mUserStackInFront.put(mCurrentUser, focusStackId);
-        final int restoreStackId = mUserStackInFront.get(userId, mHomeStack.mStackId);
+        final int restoreStackId =
+                mUserStackInFront.get(userId, getDefaultDisplay().getHomeStack().mStackId);
         mCurrentUser = userId;
 
         mStartingUsers.add(uss);
@@ -3846,14 +3697,14 @@
 
         ActivityStack stack = getStack(restoreStackId);
         if (stack == null) {
-            stack = mHomeStack;
+            stack = getDefaultDisplay().getHomeStack();
         }
         final boolean homeInFront = stack.isActivityTypeHome();
         if (stack.isOnHomeDisplay()) {
             stack.moveToFront("switchUserOnHomeDisplay");
         } else {
             // Stack was moved to another display while user was swapped out.
-            resumeHomeStackTask(null, "switchUserOnOtherDisplay");
+            resumeHomeActivity(null, "switchUserOnOtherDisplay", DEFAULT_DISPLAY);
         }
         return homeInFront;
     }
@@ -3976,8 +3827,10 @@
     }
 
     public void dump(PrintWriter pw, String prefix) {
-        pw.print(prefix); pw.print("mFocusedStack=" + getTopDisplayFocusedStack());
-                pw.print(" mLastFocusedStack="); pw.println(mLastFocusedStack);
+        pw.println();
+        pw.println("ActivityStackSupervisor state:");
+        pw.print(prefix);
+        pw.println("topDisplayFocusedStack=" + getTopDisplayFocusedStack());
         pw.print(prefix);
         pw.println("mCurTaskIdForUser=" + mCurTaskIdForUser);
         pw.print(prefix); pw.println("mUserStackInFront=" + mUserStackInFront);
@@ -4273,6 +4126,7 @@
     private void handleDisplayAdded(int displayId) {
         synchronized (mService.mGlobalLock) {
             getActivityDisplayOrCreateLocked(displayId);
+            mService.startHomeActivityLocked(mCurrentUser, "displayAdded", displayId);
         }
     }
 
@@ -4319,7 +4173,6 @@
         // The display hasn't been added to ActivityManager yet, create a new record now.
         activityDisplay = new ActivityDisplay(this, display);
         addChild(activityDisplay, ActivityDisplay.POSITION_BOTTOM);
-        calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay);
         mWindowManager.onDisplayAdded(displayId);
         return activityDisplay;
     }
@@ -4337,10 +4190,13 @@
         mActivityDisplays.remove(activityDisplay);
     }
 
-    private void calculateDefaultMinimalSizeOfResizeableTasks(ActivityDisplay display) {
-        mDefaultMinSizeOfResizeableTask =
-                mService.mContext.getResources().getDimensionPixelSize(
-                        com.android.internal.R.dimen.default_minimal_size_resizable_task);
+    private void calculateDefaultMinimalSizeOfResizeableTasks() {
+        final Resources res = mService.mContext.getResources();
+        final float minimalSize = res.getDimension(
+                com.android.internal.R.dimen.default_minimal_size_resizable_task);
+        final DisplayMetrics dm = res.getDisplayMetrics();
+
+        mDefaultMinSizeOfResizeableTaskDp = (int) (minimalSize / dm.density);
     }
 
     private void handleDisplayRemoved(int displayId) {
@@ -4508,10 +4364,6 @@
             if (!task.canBeLaunchedOnDisplay(actualDisplayId)) {
                 throw new IllegalStateException("Task resolved to incompatible display");
             }
-            // The task might have landed on a display different from requested.
-            // TODO(multi-display): Find proper stack for the task on the default display.
-            mService.setTaskWindowingMode(task.taskId,
-                    WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */);
             if (preferredDisplayId != actualDisplayId) {
                 Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplayId);
                 // Display a warning toast that we failed to put a task on a secondary display.
@@ -4836,7 +4688,8 @@
                 // We always want to return to the home activity instead of the recents activity
                 // from whatever is started from the recents activity, so move the home stack
                 // forward.
-                moveHomeStackToFront("startActivityFromRecents");
+                // TODO (b/115289124): Multi-display supports for recents.
+                getDefaultDisplay().moveHomeStackToFront("startActivityFromRecents");
             }
 
             // If the user must confirm credentials (e.g. when first launching a work app and the
@@ -4879,12 +4732,13 @@
                 final ActivityStack topSecondaryStack =
                         display.getTopStackInWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
                 if (topSecondaryStack.isActivityTypeHome()) {
-                    // If the home activity if the top split-screen secondary stack, then the
+                    // If the home activity is the top split-screen secondary stack, then the
                     // primary split-screen stack is in the minimized mode which means it can't
                     // 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.
-                    moveHomeStackToFront("startActivityFromRecents: homeVisibleInSplitScreen");
+                    display.moveHomeStackToFront(
+                            "startActivityFromRecents: homeVisibleInSplitScreen");
 
                     // Immediately update the minimized docked stack mode, the upcoming animation
                     // for the docked activity (WMS.overridePendingAppTransitionMultiThumbFuture)
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index 6e3a79c..20d5ab2 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -17,12 +17,15 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.START_SUCCESS;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
+import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
+import android.app.ActivityOptions;
 import android.app.IApplicationThread;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -62,7 +65,7 @@
  * through the pending activity list, and recording home activity launches.
  */
 public class ActivityStartController {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStartController" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStartController" : TAG_ATM;
 
     private static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 1;
 
@@ -75,7 +78,7 @@
     /** Temporary array to capture start activity results */
     private ActivityRecord[] tmpOutRecord = new ActivityRecord[1];
 
-    /**The result of the last home activity we attempted to start. */
+    /** The result of the last home activity we attempted to start. */
     private int mLastHomeActivityStartResult;
 
     /** A list of activities that are waiting to launch. */
@@ -88,6 +91,8 @@
 
     private final PendingRemoteAnimationRegistry mPendingRemoteAnimationRegistry;
 
+    boolean mCheckedForSetup = false;
+
     private final class StartHandler extends Handler {
         public StartHandler(Looper looper) {
             super(looper, null, true);
@@ -161,13 +166,20 @@
         mLastStarter.postStartActivityProcessing(r, result, targetStack);
     }
 
-    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason) {
-        mSupervisor.moveHomeStackTaskToTop(reason);
+    void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {
+        if (!mSupervisor.canStartHomeOnDisplay(aInfo, displayId)) {
+            return;
+        }
 
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
+        options.setLaunchDisplayId(displayId);
         mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
                 .setOutActivity(tmpOutRecord)
                 .setCallingUid(0)
                 .setActivityInfo(aInfo)
+                .setActivityOptions(options.toBundle())
                 .execute();
         mLastHomeActivityStartRecord = tmpOutRecord[0];
         if (mSupervisor.inResumeTopActivity) {
@@ -183,7 +195,7 @@
      */
     void startSetupActivity() {
         // Only do this once per boot.
-        if (mService.mAm.getCheckedForSetup()) {
+        if (mCheckedForSetup) {
             return;
         }
 
@@ -191,10 +203,9 @@
         // version than the last one shown, and we are not running in
         // low-level factory test mode.
         final ContentResolver resolver = mService.mContext.getContentResolver();
-        if (mService.mAm.mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
-                Settings.Global.getInt(resolver,
-                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
-            mService.mAm.setCheckedForSetup(true);
+        if (mService.mFactoryTest != FACTORY_TEST_LOW_LEVEL
+                && Settings.Global.getInt(resolver, Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
+            mCheckedForSetup = true;
 
             // See if we should be showing the platform update setup UI.
             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
@@ -348,7 +359,7 @@
                             null, userId, ActivityStarter.computeResolveFilterUid(
                                     callingUid, realCallingUid, UserHandle.USER_NULL));
                     // TODO: New, check if this is correct
-                    aInfo = mService.mAm.getActivityInfoForUser(aInfo, userId);
+                    aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
 
                     if (aInfo != null &&
                             (aInfo.applicationInfo.privateFlags
diff --git a/services/core/java/com/android/server/am/ActivityStartInterceptor.java b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
index 1fb8f87..e51824f 100644
--- a/services/core/java/com/android/server/am/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/am/ActivityStartInterceptor.java
@@ -44,6 +44,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.os.Binder;
 import android.os.Bundle;
@@ -246,9 +247,9 @@
         if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
             return interceptSuspendedByAdminPackage();
         }
-        final String dialogMessage = pmi.getSuspendedDialogMessage(suspendedPackage, mUserId);
+        final SuspendDialogInfo dialogInfo = pmi.getSuspendedDialogInfo(suspendedPackage, mUserId);
         mIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(suspendedPackage,
-                suspendingPackage, dialogMessage, mUserId);
+                suspendingPackage, dialogInfo, mUserId);
         mCallingPid = mRealCallingPid;
         mCallingUid = mRealCallingUid;
         mResolvedType = null;
@@ -277,7 +278,7 @@
             mActivityOptions = ActivityOptions.makeBasic();
         }
 
-        ActivityRecord homeActivityRecord = mSupervisor.getHomeActivity();
+        ActivityRecord homeActivityRecord = mSupervisor.getDefaultDisplayHomeActivity();
         if (homeActivityRecord != null && homeActivityRecord.getTask() != null) {
             // Showing credential confirmation activity in home task to avoid stopping multi-windowed
             // mode after showing the full-screen credential confirmation activity.
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 8236bd0..fa227a2 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -53,25 +53,25 @@
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.Display.INVALID_DISPLAY;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RESULTS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USER_LEAVING;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RESULTS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAVING;
-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.ActivityManagerService.ANIMATE;
 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_RESULTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_USER_LEAVING;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityTaskManagerService.ANIMATE;
 import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
 import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
@@ -127,7 +127,7 @@
  * an activity and associated task and stack.
  */
 class ActivityStarter {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStarter" : TAG_ATM;
     private static final String TAG_RESULTS = TAG + POSTFIX_RESULTS;
     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
@@ -590,12 +590,12 @@
         final Bundle verificationBundle
                 = options != null ? options.popAppVerificationBundle() : null;
 
-        ProcessRecord callerApp = null;
+        WindowProcessController callerApp = null;
         if (caller != null) {
-            callerApp = mService.mAm.getRecordForAppLocked(caller);
+            callerApp = mService.getProcessController(caller);
             if (callerApp != null) {
-                callingPid = callerApp.pid;
-                callingUid = callerApp.info.uid;
+                callingPid = callerApp.getPid();
+                callingUid = callerApp.mInfo.uid;
             } else {
                 Slog.w(TAG, "Unable to find app for caller " + caller
                         + " (pid=" + callingPid + ") when starting: "
@@ -726,14 +726,12 @@
         boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
                 requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
                 inTask != null, callerApp, resultRecord, resultStack);
-        abort |= !mService.mAm.mIntentFirewall.checkStartActivity(intent, callingUid,
+        abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
                 callingPid, resolvedType, aInfo.applicationInfo);
 
-        final WindowProcessController callerWpc =
-                callerApp != null ? callerApp.getWindowProcessController() : null;
         // Merge the two options bundles, while realCallerOptions takes precedence.
         ActivityOptions checkedOptions = options != null
-                ? options.getOptions(intent, aInfo, callerWpc, mSupervisor) : null;
+                ? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
         if (allowPendingRemoteAnimationRegistryLookup) {
             checkedOptions = mService.getActivityStartController()
                     .getPendingRemoteAnimationRegistry()
@@ -833,8 +831,7 @@
             aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
         }
 
-        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid,
-                callingUid,
+        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                 callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                 resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                 mSupervisor, checkedOptions, sourceRecord);
@@ -857,7 +854,7 @@
             if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
                     realCallingPid, realCallingUid, "Activity start")) {
                 mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
-                        sourceRecord, startFlags, stack, callerWpc));
+                        sourceRecord, startFlags, stack, callerApp));
                 ActivityOptions.abort(checkedOptions);
                 return ActivityManager.START_SWITCHES_CANCELED;
             }
@@ -874,12 +871,11 @@
     }
 
     private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid,
-            Intent intent, ProcessRecord callerApp, ActivityRecord r,
+            Intent intent, WindowProcessController callerApp, ActivityRecord r,
             PendingIntentRecord originatingPendingIntent) {
-        boolean callerAppHasForegroundActivity = (callerApp != null)
-                ? callerApp.foregroundActivities
-                : false;
-        if (!mService.mAm.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity
+        boolean callerAppHasForegroundActivity =
+                callerApp != null && callerApp.hasForegroundActivities();
+        if (!mService.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity
                 || r == null) {
             // skip logging in this case
             return;
@@ -887,23 +883,23 @@
 
         try {
             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart");
-            final int callingUidProcState = mService.mAm.getUidStateLocked(callingUid);
+            final int callingUidProcState = mService.getUidStateLocked(callingUid);
             final boolean callingUidHasAnyVisibleWindow =
                     mService.mWindowManager.isAnyWindowVisibleForUid(callingUid);
             final int realCallingUidProcState = (callingUid == realCallingUid)
                     ? callingUidProcState
-                    : mService.mAm.getUidStateLocked(realCallingUid);
+                    : mService.getUidStateLocked(realCallingUid);
             final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
                     ? callingUidHasAnyVisibleWindow
                     : mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid);
             final String targetPackage = r.packageName;
             final int targetUid = (r.appInfo != null) ? r.appInfo.uid : -1;
-            final int targetUidProcState = mService.mAm.getUidStateLocked(targetUid);
+            final int targetUidProcState = mService.getUidStateLocked(targetUid);
             final boolean targetUidHasAnyVisibleWindow = (targetUid != -1)
                     ? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid)
                     : false;
             final String targetWhitelistTag = (targetUid != -1)
-                    ? mService.mAm.getPendingTempWhitelistTagForUidLocked(targetUid)
+                    ? mService.getPendingTempWhitelistTagForUidLocked(targetUid)
                     : null;
 
             mSupervisor.getActivityMetricsLogger().logActivityStart(intent, callerApp, r,
@@ -975,7 +971,8 @@
                             clearedTask);
                     break;
                 case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
-                    final ActivityStack homeStack = mSupervisor.mHomeStack;
+                    final ActivityStack homeStack =
+                            startedActivityStack.getDisplay().getHomeStack();
                     if (homeStack != null && homeStack.shouldBeVisible(null /* starting */)) {
                         mService.mWindowManager.showRecentApps();
                     }
@@ -1075,7 +1072,7 @@
             if (aInfo != null &&
                     (aInfo.applicationInfo.privateFlags
                             & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0 &&
-                    mService.mAm.mHasHeavyWeightFeature) {
+                    mService.mHasHeavyWeightFeature) {
                 // This may be a heavy-weight process!  Check to see if we already
                 // have another, different heavy-weight process running.
                 if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
@@ -1084,9 +1081,10 @@
                             || !heavy.mName.equals(aInfo.processName))) {
                         int appCallingUid = callingUid;
                         if (caller != null) {
-                            ProcessRecord callerApp = mService.mAm.getRecordForAppLocked(caller);
+                            WindowProcessController callerApp =
+                                    mService.getProcessController(caller);
                             if (callerApp != null) {
-                                appCallingUid = callerApp.info.uid;
+                                appCallingUid = callerApp.mInfo.uid;
                             } else {
                                 Slog.w(TAG, "Unable to find app for caller " + caller
                                         + " (pid=" + callingPid + ") when starting: "
@@ -1126,7 +1124,7 @@
                                         callingUid, realCallingUid, mRequest.filterCallingUid));
                         aInfo = rInfo != null ? rInfo.activityInfo : null;
                         if (aInfo != null) {
-                            aInfo = mService.mAm.getActivityInfoForUser(aInfo, userId);
+                            aInfo = mService.mAmInternal.getActivityInfoForUser(aInfo, userId);
                         }
                     }
                 }
@@ -1279,6 +1277,16 @@
 
         setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                 voiceInteractor);
+        final int preferredWindowingMode = mLaunchParams.mWindowingMode;
+
+        // Do not start home activity if it cannot be launched on preferred display. We are not
+        // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
+        // fallback to launch on other displays.
+        if (r.isActivityTypeHome()
+                && !mSupervisor.canStartHomeOnDisplay(r.info, mPreferredDisplayId)) {
+            Slog.w(TAG, "Cannot launch home on display " + mPreferredDisplayId);
+            return START_CANCELED;
+        }
 
         computeLaunchingTaskFlags();
 
@@ -1288,25 +1296,6 @@
 
         ActivityRecord reusedActivity = getReusableIntentActivity();
 
-        int preferredWindowingMode = WINDOWING_MODE_UNDEFINED;
-        int preferredLaunchDisplayId = DEFAULT_DISPLAY;
-        if (mOptions != null) {
-            preferredWindowingMode = mOptions.getLaunchWindowingMode();
-            preferredLaunchDisplayId = mOptions.getLaunchDisplayId();
-        }
-
-        // windowing mode and preferred launch display values from {@link LaunchParams} take
-        // priority over those specified in {@link ActivityOptions}.
-        if (!mLaunchParams.isEmpty()) {
-            if (mLaunchParams.hasPreferredDisplay()) {
-                preferredLaunchDisplayId = mLaunchParams.mPreferredDisplayId;
-            }
-
-            if (mLaunchParams.hasWindowingMode()) {
-                preferredWindowingMode = mLaunchParams.mWindowingMode;
-            }
-        }
-
         if (reusedActivity != null) {
             // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
             // still needs to be a lock task mode violation since the task gets cleared out and
@@ -1430,7 +1419,11 @@
                 && top.userId == mStartActivity.userId
                 && top.attachedToProcess()
                 && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
-                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK));
+                || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK))
+                // This allows home activity to automatically launch on secondary display when
+                // display added, if home was the top activity on default display, instead of
+                // sending new intent to the home activity on default display.
+                && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId);
         if (dontStart) {
             // For paranoia, make sure we have correctly resumed the top activity.
             topStack.mLastPausedActivity = null;
@@ -1449,7 +1442,7 @@
             // Don't use mStartActivity.task to show the toast. We're not starting a new activity
             // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
             mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
-                    preferredLaunchDisplayId, topStack);
+                    mPreferredDisplayId, topStack);
 
             return START_DELIVERED_TO_TOP;
         }
@@ -1463,7 +1456,7 @@
         if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                 && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
             newTask = true;
-            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, topStack);
+            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate);
         } else if (mSourceRecord != null) {
             result = setTaskFromSourceRecord();
         } else if (mInTask != null) {
@@ -1479,8 +1472,9 @@
 
         mService.mUgmInternal.grantUriPermissionFromIntent(mCallingUid, mStartActivity.packageName,
                 mIntent, mStartActivity.getUriPermissionsLocked(), mStartActivity.userId);
-        mService.mAm.grantEphemeralAccessLocked(mStartActivity.userId, mIntent,
-                UserHandle.getAppId(mStartActivity.appInfo.uid), UserHandle.getAppId(mCallingUid));
+        mService.getPackageManagerInternalLocked().grantEphemeralAccess(
+                mStartActivity.userId, mIntent, UserHandle.getAppId(mStartActivity.appInfo.uid),
+                UserHandle.getAppId(mCallingUid));
         if (newTask) {
             EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, mStartActivity.userId,
                     mStartActivity.getTask().taskId);
@@ -1528,7 +1522,7 @@
         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
 
         mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
-                preferredLaunchDisplayId, mTargetStack);
+                mPreferredDisplayId, mTargetStack);
 
         return START_SUCCESS;
     }
@@ -1592,12 +1586,16 @@
         mVoiceSession = voiceSession;
         mVoiceInteractor = voiceInteractor;
 
-        mPreferredDisplayId = getPreferedDisplayId(mSourceRecord, mStartActivity, options);
-
         mLaunchParams.reset();
 
-        mSupervisor.getLaunchParamsController().calculate(inTask, null /*layout*/, r, sourceRecord,
-                options, mLaunchParams);
+        mSupervisor.getLaunchParamsController().calculate(inTask, r.info.windowLayout, r,
+                sourceRecord, options, mLaunchParams);
+
+        if (mLaunchParams.hasPreferredDisplay()) {
+            mPreferredDisplayId = mLaunchParams.mPreferredDisplayId;
+        } else {
+            mPreferredDisplayId = DEFAULT_DISPLAY;
+        }
 
         mLaunchMode = r.launchMode;
 
@@ -1858,48 +1856,17 @@
                 intentActivity = mSupervisor.findTaskLocked(mStartActivity, mPreferredDisplayId);
             }
         }
+
+        if (mStartActivity.isActivityTypeHome() && intentActivity != null
+                && intentActivity.getDisplayId() != mPreferredDisplayId) {
+            // Do not reuse home activity on other displays.
+            intentActivity = null;
+        }
+
         return intentActivity;
     }
 
     /**
-     * Returns the ID of the display to use for a new activity. If the device is in VR mode,
-     * then return the Vr mode's virtual display ID. If not,  if the activity was started with
-     * a launchDisplayId, use that. Otherwise, if the source activity has a explicit display ID
-     * set, use that to launch the activity.
-     */
-    private int getPreferedDisplayId(
-            ActivityRecord sourceRecord, ActivityRecord startingActivity, ActivityOptions options) {
-        // Check if the Activity is a VR activity. If so, the activity should be launched in
-        // main display.
-        if (startingActivity != null && startingActivity.requestedVrComponent != null) {
-            return DEFAULT_DISPLAY;
-        }
-
-        // Get the virtual display id from ActivityManagerService.
-        int displayId = mService.mVr2dDisplayId;
-        if (displayId != INVALID_DISPLAY) {
-            if (DEBUG_STACK) {
-                Slog.d(TAG, "getSourceDisplayId :" + displayId);
-            }
-            return displayId;
-        }
-
-        // If the caller requested a display, prefer that display.
-        final int launchDisplayId =
-                (options != null) ? options.getLaunchDisplayId() : INVALID_DISPLAY;
-        if (launchDisplayId != INVALID_DISPLAY) {
-            return launchDisplayId;
-        }
-
-        displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
-        // If the activity has a displayId set explicitly, launch it on the same displayId.
-        if (displayId != INVALID_DISPLAY) {
-            return displayId;
-        }
-        return DEFAULT_DISPLAY;
-    }
-
-    /**
      * Figure out which task and activity to bring to front when we have found an existing matching
      * activity record in history. May also clear the task if needed.
      * @param intentActivity Existing matching activity.
@@ -2104,8 +2071,7 @@
         mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);
     }
 
-    private int setTaskFromReuseOrCreateNewTask(
-            TaskRecord taskToAffiliate, ActivityStack topStack) {
+    private int setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
         mTargetStack = computeStackFocus(mStartActivity, true, mLaunchFlags, mOptions);
 
         // Do no move the target stack to front yet, as we might bail if
@@ -2410,17 +2376,6 @@
             }
         }
         if (stack == null) {
-            // We first try to put the task in the first dynamic stack on home display.
-            final ActivityDisplay display = mSupervisor.getDefaultDisplay();
-            for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
-                stack = display.getChildAt(stackNdx);
-                if (!stack.isOnHomeDisplay()) {
-                    if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS,
-                            "computeStackFocus: Setting focused stack=" + stack);
-                    return stack;
-                }
-            }
-            // If there is no suitable dynamic stack then we figure out which static stack to use.
             stack = mSupervisor.getLaunchStack(r, aOptions, task, ON_TOP);
         }
         if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG_FOCUS, "computeStackFocus: New stack r="
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityTaskManagerDebugConfig.java
new file mode 100644
index 0000000..cf72738
--- /dev/null
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerDebugConfig.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+/**
+ * Common class for the various debug {@link android.util.Log} output configuration relating to
+ * activities.
+ */
+public class ActivityTaskManagerDebugConfig {
+    // All output logs relating to acitvities use the {@link #TAG_ATM} string for tagging their log
+    // output. This makes it easy to identify the origin of the log message when sifting
+    // through a large amount of log output from multiple sources. However, it also makes trying
+    // to figure-out the origin of a log message while debugging the activity manager a little
+    // painful. By setting this constant to true, log messages from the activity manager package
+    // will be tagged with their class names instead fot the generic tag.
+    static final boolean TAG_WITH_CLASS_NAME = false;
+
+    // While debugging it is sometimes useful to have the category name of the log appended to the
+    // base log tag to make sifting through logs with the same base tag easier. By setting this
+    // constant to true, the category name of the log point will be appended to the log tag.
+    private static final boolean APPEND_CATEGORY_NAME = false;
+
+    // Default log tag for the activities.
+    static final String TAG_ATM = "ActivityTaskManager";
+
+    // Enable all debug log categories.
+    static final boolean DEBUG_ALL = false;
+
+    // Enable all debug log categories for activities.
+    private static final boolean DEBUG_ALL_ACTIVITIES = DEBUG_ALL || false;
+
+    static final boolean DEBUG_ADD_REMOVE = DEBUG_ALL_ACTIVITIES || false;
+    static final boolean DEBUG_CONFIGURATION = DEBUG_ALL || false;
+    static final boolean DEBUG_CONTAINERS = DEBUG_ALL_ACTIVITIES || false;
+    static final boolean DEBUG_FOCUS = false;
+    static final boolean DEBUG_IMMERSIVE = DEBUG_ALL || false;
+    static final boolean DEBUG_LOCKTASK = DEBUG_ALL || false;
+    static final boolean DEBUG_PAUSE = DEBUG_ALL || false;
+    static final boolean DEBUG_RECENTS = DEBUG_ALL || false;
+    static final boolean DEBUG_RECENTS_TRIM_TASKS = DEBUG_RECENTS || false;
+    static final boolean DEBUG_SAVED_STATE = DEBUG_ALL_ACTIVITIES || false;
+    static final boolean DEBUG_STACK = DEBUG_ALL || false;
+    static final boolean DEBUG_STATES = DEBUG_ALL_ACTIVITIES || false;
+    static final boolean DEBUG_SWITCH = DEBUG_ALL || false;
+    static final boolean DEBUG_TASKS = DEBUG_ALL || false;
+    static final boolean DEBUG_TRANSITION = DEBUG_ALL || false;
+    static final boolean DEBUG_VISIBILITY = DEBUG_ALL || false;
+    static final boolean DEBUG_APP = DEBUG_ALL_ACTIVITIES || false;
+    static final boolean DEBUG_IDLE = DEBUG_ALL_ACTIVITIES || false;
+    static final boolean DEBUG_RELEASE = DEBUG_ALL_ACTIVITIES || false;
+    static final boolean DEBUG_USER_LEAVING = DEBUG_ALL || false;
+    static final boolean DEBUG_PERMISSIONS_REVIEW = DEBUG_ALL || false;
+    static final boolean DEBUG_RESULTS = DEBUG_ALL || false;
+    static final boolean DEBUG_CLEANUP = DEBUG_ALL || false;
+    static final boolean DEBUG_METRICS = DEBUG_ALL || false;
+
+    static final String POSTFIX_APP = APPEND_CATEGORY_NAME ? "_App" : "";
+    static final String POSTFIX_IDLE = APPEND_CATEGORY_NAME ? "_Idle" : "";
+    static final String POSTFIX_RELEASE = APPEND_CATEGORY_NAME ? "_Release" : "";
+    static final String POSTFIX_USER_LEAVING = APPEND_CATEGORY_NAME ? "_UserLeaving" : "";
+    static final String POSTFIX_ADD_REMOVE = APPEND_CATEGORY_NAME ? "_AddRemove" : "";
+    static final String POSTFIX_CONFIGURATION = APPEND_CATEGORY_NAME ? "_Configuration" : "";
+    static final String POSTFIX_CONTAINERS = APPEND_CATEGORY_NAME ? "_Containers" : "";
+    static final String POSTFIX_FOCUS = APPEND_CATEGORY_NAME ? "_Focus" : "";
+    static final String POSTFIX_IMMERSIVE = APPEND_CATEGORY_NAME ? "_Immersive" : "";
+    static final String POSTFIX_LOCKTASK = APPEND_CATEGORY_NAME ? "_LockTask" : "";
+    static final String POSTFIX_PAUSE = APPEND_CATEGORY_NAME ? "_Pause" : "";
+    static final String POSTFIX_RECENTS = APPEND_CATEGORY_NAME ? "_Recents" : "";
+    static final String POSTFIX_SAVED_STATE = APPEND_CATEGORY_NAME ? "_SavedState" : "";
+    static final String POSTFIX_STACK = APPEND_CATEGORY_NAME ? "_Stack" : "";
+    static final String POSTFIX_STATES = APPEND_CATEGORY_NAME ? "_States" : "";
+    static final String POSTFIX_SWITCH = APPEND_CATEGORY_NAME ? "_Switch" : "";
+    static final String POSTFIX_TASKS = APPEND_CATEGORY_NAME ? "_Tasks" : "";
+    static final String POSTFIX_TRANSITION = APPEND_CATEGORY_NAME ? "_Transition" : "";
+    static final String POSTFIX_VISIBILITY = APPEND_CATEGORY_NAME ? "_Visibility" : "";
+    static final String POSTFIX_RESULTS = APPEND_CATEGORY_NAME ? "_Results" : "";
+}
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 36261b5..02707fb 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -19,7 +19,6 @@
 import static android.Manifest.permission.BIND_VOICE_INTERACTION;
 import static android.Manifest.permission.CHANGE_CONFIGURATION;
 import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS;
-import static android.Manifest.permission.FILTER_EVENTS;
 import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
 import static android.Manifest.permission.READ_FRAME_BUFFER;
@@ -27,10 +26,11 @@
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.Manifest.permission.STOP_APP_SWITCHES;
 import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW;
 import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.AppOpsManager.OP_NONE;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -38,7 +38,11 @@
 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.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
+import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
+import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
 import static android.content.pm.PackageManager.FEATURE_PC;
@@ -46,6 +50,10 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
 import static android.os.Build.VERSION_CODES.N;
+import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
+import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
+import static android.os.FactoryTest.FACTORY_TEST_OFF;
+import static android.os.Process.FIRST_APPLICATION_UID;
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
@@ -63,31 +71,27 @@
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
 import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
-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.ActivityManagerService.ANIMATE;
+import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
 import static com.android.server.am.ActivityManagerService.MY_PID;
-import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG;
 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
-import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG;
-import static com.android.server.am.ActivityManagerService.checkComponentPermission;
 import static com.android.server.am.ActivityManagerService.dumpStackTraces;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HOME_PROC;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto
+        .PREVIOUS_PROC_VISIBLE_TIME_MS;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage
+        .MODE;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage
+        .PACKAGE;
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY;
@@ -95,9 +99,26 @@
 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_FOCUS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_IMMERSIVE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
 import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
-import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
 import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
 import static com.android.server.am.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
@@ -138,8 +159,7 @@
 import android.app.admin.DevicePolicyCache;
 import android.app.assist.AssistContent;
 import android.app.assist.AssistStructure;
-import android.app.servertransaction.ConfigurationChangeItem;
-import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManagerInternal;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -167,6 +187,7 @@
 import android.os.Binder;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.FactoryTest;
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.IBinder;
@@ -176,6 +197,7 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.PowerManager;
+import android.os.PowerManagerInternal;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
@@ -186,6 +208,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.WorkSource;
+import android.os.storage.IStorageManager;
+import android.os.storage.StorageManager;
 import android.provider.Settings;
 import android.service.voice.IVoiceInteractionSession;
 import android.service.voice.VoiceInteractionManagerInternal;
@@ -216,9 +240,12 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.os.TransferPipe;
 import com.android.internal.os.logging.MetricsLoggerWrapper;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.KeyguardDismissCallback;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.AppOpsService;
@@ -227,6 +254,7 @@
 import com.android.server.SystemService;
 import com.android.server.SystemServiceManager;
 import com.android.server.Watchdog;
+import com.android.server.firewall.IntentFirewall;
 import com.android.server.pm.UserManagerService;
 import com.android.server.uri.UriGrantsManagerInternal;
 import com.android.server.vr.VrManagerInternal;
@@ -234,16 +262,23 @@
 import com.android.server.wm.PinnedStackWindowController;
 import com.android.server.wm.WindowManagerService;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.lang.ref.WeakReference;
+import java.text.DateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * System service for managing activities and their containers (task, stacks, displays,... ).
@@ -251,7 +286,7 @@
  * {@hide}
  */
 public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
     private static final String TAG_STACK = TAG + POSTFIX_STACK;
     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
@@ -261,30 +296,61 @@
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
 
     // How long we wait until we timeout on key dispatching.
-    private static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
+    public static final int KEY_DISPATCHING_TIMEOUT_MS = 5 * 1000;
     // How long we wait until we timeout on key dispatching during instrumentation.
-    private static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
+    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS = 60 * 1000;
+
+    /** Used to indicate that an app transition should be animated. */
+    static final boolean ANIMATE = true;
+
+    /** Hardware-reported OpenGLES version. */
+    final int GL_ES_VERSION;
+
+    public static final String DUMP_ACTIVITIES_CMD = "activities" ;
+    public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
+    public static final String DUMP_LASTANR_CMD = "lastanr" ;
+    public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
+    public static final String DUMP_STARTER_CMD = "starter" ;
+    public static final String DUMP_CONTAINERS_CMD = "containers" ;
+    public static final String DUMP_RECENTS_CMD = "recents" ;
+    public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
+
+    /** This activity is not being relaunched, or being relaunched for a non-resize reason. */
+    public static final int RELAUNCH_REASON_NONE = 0;
+    /** This activity is being relaunched due to windowing mode change. */
+    public static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
+    /** This activity is being relaunched due to a free-resize operation. */
+    public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
 
     Context mContext;
+
     /**
      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
      * change at runtime. Use mContext for non-UI purposes.
      */
     final Context mUiContext;
+    final ActivityThread mSystemThread;
     H mH;
     UiHandler mUiHandler;
-    ActivityManagerService mAm;
     ActivityManagerInternal mAmInternal;
     UriGrantsManagerInternal mUgmInternal;
     private PackageManagerInternal mPmInternal;
     private ActivityTaskManagerInternal mInternal;
+    PowerManagerInternal mPowerManagerInternal;
+    private UsageStatsManagerInternal mUsageStatsInternal;
+
     PendingIntentController mPendingIntentController;
+    IntentFirewall mIntentFirewall;
+
     /* Global service lock used by the package the owns this service. */
     Object mGlobalLock;
     ActivityStackSupervisor mStackSupervisor;
     WindowManagerService mWindowManager;
     private UserManagerService mUserManager;
     private AppOpsService mAppOpsService;
+    /** All active uids in the system. */
+    private final SparseArray<Integer> mActiveUids = new SparseArray<>();
+    private final SparseArray<String> mPendingTempWhitelist = new SparseArray<>();
     /** All processes currently running that might have a window organized by name. */
     final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
     /** All processes we currently have running mapped by pid */
@@ -293,6 +359,7 @@
     WindowProcessController mHomeProcess;
     /** The currently running heavy-weight process, if any. */
     WindowProcessController mHeavyWeightProcess = null;
+    boolean mHasHeavyWeightFeature;
     /**
      * This is the process holding the activity the user last visited that is in a different process
      * from the one they are currently in.
@@ -388,6 +455,19 @@
     IActivityController mController = null;
     boolean mControllerIsAMonkey = false;
 
+    final int mFactoryTest;
+
+    /** Used to control how we initialize the service. */
+    ComponentName mTopComponent;
+    String mTopAction = Intent.ACTION_MAIN;
+    String mTopData;
+
+    /**
+     * Dump of the activity state at the time of the last ANR. Cleared after
+     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
+     */
+    String mLastANRState;
+
     /**
      * Used to retain an update lock when the foreground activity is in
      * immersive mode.
@@ -524,11 +604,16 @@
 
     ActivityTaskManagerService(Context context) {
         mContext = context;
-        mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
+        mFactoryTest = FactoryTest.getMode();
+        mSystemThread = ActivityThread.currentActivityThread();
+        mUiContext = mSystemThread.getSystemUiContext();
         mLifecycleManager = new ClientLifecycleManager();
+        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
     }
 
     void onSystemReady() {
+        mHasHeavyWeightFeature = mContext.getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_CANT_SAVE_STATE);
         mAssistUtils = new AssistUtils(mContext);
         mVrController.onSystemReady();
         mRecentTasks.onSystemReadyLocked();
@@ -537,6 +622,7 @@
     void onInitPowerManagement() {
         mStackSupervisor.initPowerManagement();
         final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+        mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
         mVoiceWakeLock.setReferenceCounted(false);
     }
@@ -623,15 +709,16 @@
     }
 
     // TODO: Will be converted to WM lock once transition is complete.
-    void setActivityManagerService(ActivityManagerService am) {
-        mAm = am;
-        mGlobalLock = mAm;
-        mH = new H(mAm.mHandlerThread.getLooper());
+    void setActivityManagerService(Object globalLock, Looper looper,
+            IntentFirewall intentFirewall, PendingIntentController intentController) {
+        mGlobalLock = globalLock;
+        mH = new H(looper);
         mUiHandler = new UiHandler();
+        mIntentFirewall = intentFirewall;
         final File systemDir = SystemServiceManager.ensureSystemDir();
         mAppWarnings = new AppWarnings(this, mUiContext, mH, mUiHandler, systemDir);
         mCompatModePackages = new CompatModePackages(this, systemDir, mH);
-        mPendingIntentController = mAm.mPendingIntentController;
+        mPendingIntentController = intentController;
 
         mTempConfig.setToDefaults();
         mTempConfig.setLocales(LocaleList.getDefault());
@@ -668,6 +755,11 @@
     void setWindowManager(WindowManagerService wm) {
         mWindowManager = wm;
         mLockTaskController.setWindowManager(wm);
+        mStackSupervisor.setWindowManager(wm);
+    }
+
+    void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
+        mUsageStatsInternal = usageStatsManager;
     }
 
     UserManagerService getUserManager() {
@@ -749,7 +841,7 @@
                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
             }
-            config.reqGlEsVersion = mAm.GL_ES_VERSION;
+            config.reqGlEsVersion = GL_ES_VERSION;
         }
         return config;
     }
@@ -1280,7 +1372,7 @@
                         Slog.i(TAG, "Removing task failed to finish activity");
                     }
                     // Explicitly dismissing the activity so reset its relaunch flag.
-                    r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
+                    r.mRelaunchReason = RELAUNCH_REASON_NONE;
                 } else {
                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
                             resultData, "app-request", true);
@@ -1692,8 +1784,7 @@
                     return;
                 }
                 final ActivityRecord r = stack.topRunningActivityLocked();
-                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
-                        r, "setFocusedStack")) {
+                if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
                     mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
                 }
             }
@@ -1714,7 +1805,7 @@
                     return;
                 }
                 final ActivityRecord r = task.topRunningActivityLocked();
-                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
+                if (r != null && r.moveFocusableActivityToTop("setFocusedTask")) {
                     mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
                 }
             }
@@ -2581,7 +2672,7 @@
                 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                mAmInternal.closeSystemDialogs("assist");
+                mInternal.closeSystemDialogs("assist");
 
                 try {
                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
@@ -2748,8 +2839,7 @@
         synchronized (mGlobalLock) {
             final long origId = Binder.clearCallingIdentity();
             try {
-                WindowProcessController app =
-                        mAm.getRecordForAppLocked(appInt).getWindowProcessController();
+                final WindowProcessController app = getProcessController(appInt);
                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
             } finally {
                 Binder.restoreCallingIdentity(origId);
@@ -2770,7 +2860,10 @@
             long ident = Binder.clearCallingIdentity();
             if (mKeyguardShown != keyguardShowing) {
                 mKeyguardShown = keyguardShowing;
-                reportCurKeyguardUsageEventLocked(keyguardShowing);
+                final Message msg = PooledLambda.obtainMessage(
+                        ActivityManagerInternal::reportCurKeyguardUsageEvent, mAmInternal,
+                        keyguardShowing);
+                mH.sendMessage(msg);
             }
             try {
                 mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
@@ -2907,12 +3000,6 @@
         mTaskChangeNotificationController.unregisterTaskStackListener(listener);
     }
 
-    private void reportCurKeyguardUsageEventLocked(boolean keyguardShowing) {
-        mAm.reportGlobalUsageEventLocked(keyguardShowing
-                ? UsageEvents.Event.KEYGUARD_SHOWN
-                : UsageEvents.Event.KEYGUARD_HIDDEN);
-    }
-
     @Override
     public boolean requestAssistContextExtras(int requestType, IAssistDataReceiver receiver,
             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
@@ -2971,7 +3058,7 @@
     }
 
     /** This can be called with or without the global lock held. */
-    void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
+    private void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
         if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) {
             mAmInternal.enforceCallingPermission(permission, func);
         }
@@ -2989,6 +3076,12 @@
         return checkComponentPermission(permission, pid, uid, -1, true);
     }
 
+    public static int checkComponentPermission(String permission, int pid, int uid,
+            int owningUid, boolean exported) {
+        return ActivityManagerService.checkComponentPermission(
+                permission, pid, uid, owningUid, exported);
+    }
+
     boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
         if (getRecentTasks().isCallerRecents(callingUid)) {
             // Always allow the recents component to get tasks
@@ -3873,8 +3966,9 @@
             }
 
             if (mWindowManager != null) {
-                // Update OOM levels based on display size.
-                mAm.mProcessList.applyDisplaySize(mWindowManager);
+                final Message msg = PooledLambda.obtainMessage(
+                        ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal, displayId);
+                mH.sendMessage(msg);
             }
 
             final long origId = Binder.clearCallingIdentity();
@@ -3902,8 +3996,10 @@
             }
 
             if (mWindowManager != null) {
-                // Update OOM levels based on display size.
-                mAm.mProcessList.applyDisplaySize(mWindowManager);
+                final Message msg = PooledLambda.obtainMessage(
+                        ActivityManagerInternal::updateOomLevelsForDisplay, mAmInternal,
+                        DEFAULT_DISPLAY);
+                mH.sendMessage(msg);
             }
 
             final long origId = Binder.clearCallingIdentity();
@@ -4110,11 +4206,9 @@
     public void setVrThread(int tid) {
         enforceSystemHasVrFeature();
         synchronized (mGlobalLock) {
-            synchronized (mAm.mPidsSelfLocked) {
-                final int pid = Binder.getCallingPid();
-                final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
-                mVrController.setVrThreadLocked(tid, pid, proc.getWindowProcessController());
-            }
+            final int pid = Binder.getCallingPid();
+            final WindowProcessController wpc = mPidMap.get(pid);
+            mVrController.setVrThreadLocked(tid, pid, wpc);
         }
     }
 
@@ -4131,11 +4225,9 @@
         }
         enforceSystemHasVrFeature();
         synchronized (mGlobalLock) {
-            synchronized (mAm.mPidsSelfLocked) {
-                final int pid = Binder.getCallingPid();
-                final ProcessRecord proc = mAm.mPidsSelfLocked.get(pid);
-                mVrController.setPersistentVrThreadLocked(tid, pid, proc);
-            }
+            final int pid = Binder.getCallingPid();
+            final WindowProcessController proc = mPidMap.get(pid);
+            mVrController.setPersistentVrThreadLocked(tid, pid, proc);
         }
     }
 
@@ -4243,6 +4335,17 @@
         }
     }
 
+    public static String relaunchReasonToString(int relaunchReason) {
+        switch (relaunchReason) {
+            case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
+                return "window_resize";
+            case RELAUNCH_REASON_FREE_RESIZE:
+                return "free_resize";
+            default:
+                return null;
+        }
+    }
+
     ActivityStack getTopDisplayFocusedStack() {
         return mStackSupervisor.getTopDisplayFocusedStack();
     }
@@ -4267,16 +4370,177 @@
                 || transit == TRANSIT_TASK_TO_FRONT;
     }
 
-    void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
-        synchronized (mGlobalLock) {
-            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
-            if (mRunningVoice != null) {
-                pw.println("  mRunningVoice=" + mRunningVoice);
-                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
+    void dumpLastANRLocked(PrintWriter pw) {
+        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
+        if (mLastANRState == null) {
+            pw.println("  <no ANR has occurred since boot>");
+        } else {
+            pw.println(mLastANRState);
+        }
+    }
+
+    void dumpLastANRTracesLocked(PrintWriter pw) {
+        pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
+
+        final File[] files = new File(ANR_TRACE_DIR).listFiles();
+        if (ArrayUtils.isEmpty(files)) {
+            pw.println("  <no ANR has occurred since boot>");
+            return;
+        }
+        // Find the latest file.
+        File latest = null;
+        for (File f : files) {
+            if ((latest == null) || (latest.lastModified() < f.lastModified())) {
+                latest = f;
             }
-            pw.println("  mSleeping=" + mSleeping);
-            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
-            pw.println("  mVrController=" + mVrController);
+        }
+        pw.print("File: ");
+        pw.print(latest.getName());
+        pw.println();
+        try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
+            String line;
+            while ((line = in.readLine()) != null) {
+                pw.println(line);
+            }
+        } catch (IOException e) {
+            pw.print("Unable to read: ");
+            pw.print(e);
+            pw.println();
+        }
+    }
+
+    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
+        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
+                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
+    }
+
+    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
+        pw.println(header);
+
+        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
+                dumpPackage);
+        boolean needSep = printedAnything;
+
+        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
+                mStackSupervisor.getTopResumedActivity(),  dumpPackage, needSep,
+                "  ResumedActivity: ");
+        if (printed) {
+            printedAnything = true;
+            needSep = false;
+        }
+
+        if (dumpPackage == null) {
+            if (needSep) {
+                pw.println();
+            }
+            printedAnything = true;
+            mStackSupervisor.dump(pw, "  ");
+        }
+
+        if (!printedAnything) {
+            pw.println("  (nothing)");
+        }
+    }
+
+    void dumpActivityContainersLocked(PrintWriter pw) {
+        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
+        mStackSupervisor.dumpChildrenNames(pw, " ");
+        pw.println(" ");
+    }
+
+    void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
+        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
+        getActivityStartController().dump(pw, "", dumpPackage);
+    }
+
+    /**
+     * There are three things that cmd can be:
+     *  - a flattened component name that matches an existing activity
+     *  - 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.
+     *
+     *  @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
+     */
+    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
+            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
+        ArrayList<ActivityRecord> activities;
+
+        synchronized (mGlobalLock) {
+            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
+                    dumpFocusedStackOnly);
+        }
+
+        if (activities.size() <= 0) {
+            return false;
+        }
+
+        String[] newArgs = new String[args.length - opti];
+        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
+
+        TaskRecord lastTask = null;
+        boolean needSep = false;
+        for (int i = activities.size() - 1; i >= 0; i--) {
+            ActivityRecord r = activities.get(i);
+            if (needSep) {
+                pw.println();
+            }
+            needSep = true;
+            synchronized (mGlobalLock) {
+                final TaskRecord task = r.getTask();
+                if (lastTask != task) {
+                    lastTask = task;
+                    pw.print("TASK "); pw.print(lastTask.affinity);
+                    pw.print(" id="); pw.print(lastTask.taskId);
+                    pw.print(" userId="); pw.println(lastTask.userId);
+                    if (dumpAll) {
+                        lastTask.dump(pw, "  ");
+                    }
+                }
+            }
+            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
+        }
+        return true;
+    }
+
+    /**
+     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
+     * there is a thread associated with the activity.
+     */
+    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
+            final ActivityRecord r, String[] args, boolean dumpAll) {
+        String innerPrefix = prefix + "  ";
+        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 (dumpAll) {
+                r.dump(pw, innerPrefix);
+            }
+        }
+        if (r.attachedToProcess()) {
+            // 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();
+                }
+            } catch (IOException e) {
+                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
+            } catch (RemoteException e) {
+                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
+            }
         }
     }
 
@@ -4409,14 +4673,6 @@
         return kept;
     }
 
-    /**
-     * Returns true if this configuration change is interesting enough to send an
-     * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast.
-     */
-    private static boolean isSplitConfigurationChange(int configDiff) {
-        return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0;
-    }
-
     /** Update default (global) configuration and notify listeners about changes. */
     private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale,
             boolean persistent, int userId, boolean deferResume) {
@@ -4467,8 +4723,11 @@
             SystemProperties.set("persist.sys.locale",
                     locales.get(bestLocaleIndex).toLanguageTag());
             LocaleList.setDefault(locales, bestLocaleIndex);
-            mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
-                    locales.get(bestLocaleIndex)));
+
+            final Message m = PooledLambda.obtainMessage(
+                    ActivityTaskManagerService::sendLocaleToMountDaemonMsg, this,
+                    locales.get(bestLocaleIndex));
+            mH.sendMessage(m);
         }
 
         mTempConfig.seq = increaseConfigurationSeqLocked();
@@ -4478,8 +4737,7 @@
 
         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
         // TODO(multi-display): Update UsageEvents#Event to include displayId.
-        mAm.mUsageStatsService.reportConfigurationChange(
-                mTempConfig, mAmInternal.getCurrentUserId());
+        mUsageStatsInternal.reportConfigurationChange(mTempConfig, mAmInternal.getCurrentUserId());
 
         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
         updateShouldShowDialogsLocked(mTempConfig);
@@ -4493,65 +4751,32 @@
         // to retrieve resource values after we return will be sure to get the new ones. This is
         // especially important during boot, where the first config change needs to guarantee all
         // resources have that config before following boot code is executed.
-        mAm.mSystemThread.applyConfigurationToResources(mTempConfig);
+        mSystemThread.applyConfigurationToResources(mTempConfig);
 
         // We need another copy of global config because we're scheduling some calls instead of
         // running them in place. We need to be sure that object we send will be handled unchanged.
         final Configuration configCopy = new Configuration(mTempConfig);
         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
-            Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
-            msg.obj = configCopy;
-            msg.arg1 = userId;
-            mAm.mHandler.sendMessage(msg);
+            final Message msg = PooledLambda.obtainMessage(
+                    ActivityTaskManagerService::sendPutConfigurationForUserMsg,
+                    this, userId, configCopy);
+            mH.sendMessage(msg);
         }
 
-        // TODO: Consider using mPidMap to update configurations for processes.
-        for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) {
-            ProcessRecord app = mAm.mLruProcesses.get(i);
-            try {
-                if (app.thread != null) {
-                    if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
-                            + app.processName + " new config " + configCopy);
-                    getLifecycleManager().scheduleTransaction(app.thread,
-                            ConfigurationChangeItem.obtain(configCopy));
-                }
-            } catch (Exception e) {
-                Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e);
+        for (int i = mPidMap.size() - 1; i >= 0; i--) {
+            final int pid = mPidMap.keyAt(i);
+            final WindowProcessController app = mPidMap.get(pid);
+            if (DEBUG_CONFIGURATION) {
+                Slog.v(TAG_CONFIGURATION, "Update process config of "
+                        + app.mName + " to new config " + configCopy);
             }
+            app.onConfigurationChanged(configCopy);
         }
 
-        Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
-        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
-                | Intent.FLAG_RECEIVER_FOREGROUND
-                | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
-        mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
-                OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
-                UserHandle.USER_ALL);
-        if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
-            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
-            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
-                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
-                    | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
-            if (initLocale || !mAm.mProcessesReady) {
-                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
-            }
-            mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
-                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
-                    UserHandle.USER_ALL);
-        }
-
-        // Send a broadcast to PackageInstallers if the configuration change is interesting
-        // for the purposes of installing additional splits.
-        if (!initLocale && isSplitConfigurationChange(changes)) {
-            intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED);
-            intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
-                    | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
-
-            // Typically only app stores will have this permission.
-            String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES };
-            mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions,
-                    OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
-        }
+        final Message msg = PooledLambda.obtainMessage(
+                ActivityManagerInternal::broadcastGlobalConfigurationChanged,
+                mAmInternal, changes, initLocale);
+        mH.sendMessage(msg);
 
         // Override configuration of the default display duplicates global config, so we need to
         // update it also. This will also notify WindowManager about changes.
@@ -4620,8 +4845,12 @@
             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
                 mAppWarnings.onDensityChanged();
 
-                mAm.killAllBackgroundProcessesExcept(N,
-                        ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
+                // 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_BOUND_FOREGROUND_SERVICE);
+                mH.sendMessage(msg);
             }
         }
 
@@ -4646,6 +4875,26 @@
         mWindowManager.setEventDispatching(booted && !mShuttingDown);
     }
 
+    private void sendPutConfigurationForUserMsg(int userId, Configuration config) {
+        final ContentResolver resolver = mContext.getContentResolver();
+        Settings.System.putConfigurationForUser(resolver, config, userId);
+    }
+
+    private void sendLocaleToMountDaemonMsg(Locale l) {
+        try {
+            IBinder service = ServiceManager.getService("mount");
+            IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
+            Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
+            storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error storing locale for decryption UI", e);
+        }
+    }
+
+    boolean isActivityStartsLoggingEnabled() {
+        return mAmInternal.isActivityStartsLoggingEnabled();
+    }
+
     void enableScreenAfterBoot(boolean booted) {
         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
                 SystemClock.uptimeMillis());
@@ -4673,70 +4922,7 @@
     }
 
     private static long getInputDispatchingTimeoutLocked(WindowProcessController r) {
-        if (r != null && (r.isInstrumenting() || r.isUsingWrapper())) {
-            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
-        }
-        return KEY_DISPATCHING_TIMEOUT_MS;
-    }
-
-    long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
-        if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires permission " + FILTER_EVENTS);
-        }
-        WindowProcessController proc;
-        long timeout;
-        synchronized (mGlobalLock) {
-            proc = mPidMap.get(pid);
-            timeout = getInputDispatchingTimeoutLocked(proc);
-        }
-
-        if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
-            return -1;
-        }
-
-        return timeout;
-    }
-
-    /**
-     * Handle input dispatching timeouts.
-     * Returns whether input dispatching should be aborted or not.
-     */
-    boolean inputDispatchingTimedOut(final WindowProcessController proc,
-            final ActivityRecord activity, final ActivityRecord parent,
-            final boolean aboveSystem, String reason) {
-        if (checkCallingPermission(FILTER_EVENTS) != PackageManager.PERMISSION_GRANTED) {
-            throw new SecurityException("Requires permission " + FILTER_EVENTS);
-        }
-
-        final String annotation;
-        if (reason == null) {
-            annotation = "Input dispatching timed out";
-        } else {
-            annotation = "Input dispatching timed out (" + reason + ")";
-        }
-
-        if (proc != null) {
-            synchronized (mGlobalLock) {
-                if (proc.isDebugging()) {
-                    return false;
-                }
-
-                if (proc.isInstrumenting()) {
-                    Bundle info = new Bundle();
-                    info.putString("shortMsg", "keyDispatchingTimedOut");
-                    info.putString("longMsg", annotation);
-                    mAm.finishInstrumentationLocked(
-                            (ProcessRecord) proc.mOwner, Activity.RESULT_CANCELED, info);
-                    return true;
-                }
-            }
-            mH.post(() -> {
-                mAm.mAppErrors.appNotResponding(
-                        (ProcessRecord) proc.mOwner, activity, parent, aboveSystem, annotation);
-            });
-        }
-
-        return true;
+        return r != null ? r.getInputDispatchingTimeout() : KEY_DISPATCHING_TIMEOUT_MS;
     }
 
     /**
@@ -4846,8 +5032,7 @@
         updateResumedAppTrace(r);
         mLastResumedActivity = r;
 
-        // TODO(b/111361570): Support multiple focused apps in WM
-        mWindowManager.setFocusedApp(r.appToken, true);
+        r.getDisplay().setFocusedApp(r, true);
 
         applyUpdateLockStateLocked(r);
         applyUpdateVrModeLocked(r);
@@ -5157,6 +5342,135 @@
         return mAppWarnings;
     }
 
+    Intent getHomeIntent() {
+        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
+        intent.setComponent(mTopComponent);
+        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
+        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
+            intent.addCategory(Intent.CATEGORY_HOME);
+        }
+        return intent;
+    }
+
+    /**
+     * This starts home activity on displays that can have system decorations and only if the
+     * home activity can have multiple instances.
+     */
+    boolean startHomeActivityLocked(int userId, String reason, int displayId) {
+        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL && mTopAction == null) {
+            // We are running in factory test mode, but unable to find the factory test app, so just
+            // sit around displaying the error message and don't try to start anything.
+            return false;
+        }
+
+        final Intent intent = getHomeIntent();
+        ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
+        if (aInfo != null) {
+            intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
+            // Don't do this if the home app is currently being instrumented.
+            aInfo = new ActivityInfo(aInfo);
+            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
+            WindowProcessController app =
+                    getProcessController(aInfo.processName, aInfo.applicationInfo.uid);
+            if (app == null || !app.isInstrumenting()) {
+                intent.setFlags(intent.getFlags() | FLAG_ACTIVITY_NEW_TASK);
+                final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
+                // For ANR debugging to verify if the user activity is the one that actually
+                // launched.
+                final String myReason = reason + ":" + userId + ":" + resolvedUserId;
+                getActivityStartController().startHomeActivity(intent, aInfo, myReason, displayId);
+            }
+        } else {
+            Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
+        }
+
+        return true;
+    }
+
+    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
+        ActivityInfo ai = null;
+        final ComponentName comp = intent.getComponent();
+        try {
+            if (comp != null) {
+                // Factory test.
+                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
+            } else {
+                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
+                        intent,
+                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
+                        flags, userId);
+
+                if (info != null) {
+                    ai = info.activityInfo;
+                }
+            }
+        } catch (RemoteException e) {
+            // ignore
+        }
+
+        return ai;
+    }
+
+    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
+        if (info == null) return null;
+        ApplicationInfo newInfo = new ApplicationInfo(info);
+        newInfo.initForUser(userId);
+        return newInfo;
+    }
+
+    WindowProcessController getProcessController(String processName, int uid) {
+        if (uid == SYSTEM_UID) {
+            // The system gets to run in any process. If there are multiple processes with the same
+            // uid, just pick the first (this should never happen).
+            final SparseArray<WindowProcessController> procs =
+                    mProcessNames.getMap().get(processName);
+            if (procs == null) return null;
+            final int procCount = procs.size();
+            for (int i = 0; i < procCount; i++) {
+                final int procUid = procs.keyAt(i);
+                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
+                    // Don't use an app process or different user process for system component.
+                    continue;
+                }
+                return procs.valueAt(i);
+            }
+        }
+
+        return mProcessNames.get(processName, uid);
+    }
+
+    WindowProcessController getProcessController(IApplicationThread thread) {
+        if (thread == null) {
+            return null;
+        }
+
+        final IBinder threadBinder = thread.asBinder();
+        final ArrayMap<String, SparseArray<WindowProcessController>> pmap = mProcessNames.getMap();
+        for (int i = pmap.size()-1; i >= 0; i--) {
+            final SparseArray<WindowProcessController> procs = pmap.valueAt(i);
+            for (int j = procs.size() - 1; j >= 0; j--) {
+                final WindowProcessController proc = procs.valueAt(j);
+                if (proc.hasThread() && proc.getThread().asBinder() == threadBinder) {
+                    return proc;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    int getUidStateLocked(int uid) {
+        return mActiveUids.get(uid, PROCESS_STATE_NONEXISTENT);
+    }
+
+    /**
+     * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on
+     * the whitelist
+     */
+    String getPendingTempWhitelistTagForUidLocked(int uid) {
+        return mPendingTempWhitelist.get(uid);
+    }
+
     void logAppTooSlow(WindowProcessController app, long startTime, String msg) {
         if (true || Build.IS_USER) {
             return;
@@ -5218,6 +5532,8 @@
 
     final class H extends Handler {
         static final int REPORT_TIME_TRACKER_MSG = 1;
+        static final int FIRST_ACTIVITY_STACK_MSG = 100;
+        static final int FIRST_SUPERVISOR_STACK_MSG = 200;
 
         public H(Looper looper) {
             super(looper, null, true);
@@ -5263,7 +5579,8 @@
         @Override
         public ComponentName getHomeActivityForUser(int userId) {
             synchronized (mGlobalLock) {
-                ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
+                ActivityRecord homeActivity =
+                        mStackSupervisor.getDefaultDisplayHomeActivityForUser(userId);
                 return homeActivity == null ? null : homeActivity.realActivity;
             }
         }
@@ -5437,8 +5754,7 @@
                     throw new IllegalArgumentException(
                             "setFocusedActivity: No activity record matching token=" + token);
                 }
-                if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
-                        r, "setFocusedActivity")) {
+                if (r.moveFocusableActivityToTop("setFocusedActivity")) {
                     mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
                 }
             }
@@ -5564,6 +5880,9 @@
         @Override
         public void finishHeavyWeightApp() {
             synchronized (mGlobalLock) {
+                if (mHeavyWeightProcess != null) {
+                    mHeavyWeightProcess.finishActivities();
+                }
                 ActivityTaskManagerService.this.clearHeavyWeightProcessIfEquals(
                         mHeavyWeightProcess);
             }
@@ -5654,14 +5973,6 @@
         }
 
         @Override
-        public long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason) {
-            synchronized (mGlobalLock) {
-                return ActivityTaskManagerService.this.inputDispatchingTimedOut(
-                        pid, aboveSystem, reason);
-            }
-        }
-
-        @Override
         public void onProcessMapped(int pid, WindowProcessController proc) {
             synchronized (mGlobalLock) {
                 mPidMap.put(pid, proc);
@@ -5699,6 +6010,13 @@
         }
 
         @Override
+        public void onPackageReplaced(ApplicationInfo aInfo) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
+            }
+        }
+
+        @Override
         public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
             synchronized (mGlobalLock) {
                 return compatibilityInfoForPackageLocked(ai);
@@ -5713,7 +6031,7 @@
          * @param displayId The ID of the display showing the IME.
          */
         @Override
-        public void onImeWindowSetOnDisplay(int pid, int displayId) {
+        public void onImeWindowSetOnDisplay(final int pid, final int displayId) {
             if (pid == MY_PID || pid < 0) {
                 if (DEBUG_CONFIGURATION) {
                     Slog.w(TAG,
@@ -5723,29 +6041,28 @@
             }
             mH.post(() -> {
                 synchronized (mGlobalLock) {
-                    // Check if display is initialized in AM.
-                    if (!mStackSupervisor.isDisplayAdded(displayId)) {
-                        // Call come when display is not yet added or has already been removed.
+                    final ActivityDisplay activityDisplay =
+                            mStackSupervisor.getActivityDisplay(displayId);
+                    if (activityDisplay == null) {
+                        // Call might come when display is not yet added or has been removed.
                         if (DEBUG_CONFIGURATION) {
                             Slog.w(TAG, "Trying to update display configuration for non-existing "
-                                            + "displayId=" + displayId);
+                                    + "displayId=" + displayId);
                         }
                         return;
                     }
-                    final WindowProcessController imeProcess = mPidMap.get(pid);
-                    if (imeProcess == null) {
+                    final WindowProcessController process = mPidMap.get(pid);
+                    if (process == null) {
                         if (DEBUG_CONFIGURATION) {
-                            Slog.w(TAG, "Trying to update display configuration for invalid pid: "
-                                            + pid);
+                            Slog.w(TAG, "Trying to update display configuration for invalid "
+                                    + "process, pid=" + pid);
                         }
                         return;
                     }
-                    // Fetch the current override configuration of the display and set it to the
-                    // process global configuration.
-                    imeProcess.onConfigurationChanged(
-                            mStackSupervisor.getDisplayOverrideConfiguration(displayId));
+                    process.registerDisplayConfigurationListenerLocked(activityDisplay);
                 }
             });
+
         }
 
         @Override
@@ -5781,5 +6098,596 @@
                         resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
             }
         }
+
+        @Override
+        public ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token) {
+            synchronized (mGlobalLock) {
+                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+                if (r == null) {
+                    return null;
+                }
+                if (r.mServiceConnectionsHolder == null) {
+                    r.mServiceConnectionsHolder = new ActivityServiceConnectionsHolder(
+                            ActivityTaskManagerService.this, r);
+                }
+
+                return r.mServiceConnectionsHolder;
+            }
+        }
+
+        @Override
+        public Intent getHomeIntent() {
+            synchronized (mGlobalLock) {
+                return ActivityTaskManagerService.this.getHomeIntent();
+            }
+        }
+
+        @Override
+        public boolean startHomeActivity(int userId, String reason) {
+            synchronized (mGlobalLock) {
+                return startHomeActivityLocked(userId, reason, DEFAULT_DISPLAY);
+            }
+        }
+
+        @Override
+        public boolean isFactoryTestProcess(WindowProcessController wpc) {
+            synchronized (mGlobalLock) {
+                if (mFactoryTest == FACTORY_TEST_OFF) {
+                    return false;
+                }
+                if (mFactoryTest == FACTORY_TEST_LOW_LEVEL && mTopComponent != null
+                        && wpc.mName.equals(mTopComponent.getPackageName())) {
+                    return true;
+                }
+                return mFactoryTest == FACTORY_TEST_HIGH_LEVEL
+                        && (wpc.mInfo.flags & FLAG_FACTORY_TEST) != 0;
+            }
+        }
+
+        @Override
+        public void updateTopComponentForFactoryTest() {
+            synchronized (mGlobalLock) {
+                if (mFactoryTest != FACTORY_TEST_LOW_LEVEL) {
+                    return;
+                }
+                final ResolveInfo ri = mContext.getPackageManager()
+                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), STOCK_PM_FLAGS);
+                final CharSequence errorMsg;
+                if (ri != null) {
+                    final ActivityInfo ai = ri.activityInfo;
+                    final ApplicationInfo app = ai.applicationInfo;
+                    if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                        mTopAction = Intent.ACTION_FACTORY_TEST;
+                        mTopData = null;
+                        mTopComponent = new ComponentName(app.packageName, ai.name);
+                        errorMsg = null;
+                    } else {
+                        errorMsg = mContext.getResources().getText(
+                                com.android.internal.R.string.factorytest_not_system);
+                    }
+                } else {
+                    errorMsg = mContext.getResources().getText(
+                            com.android.internal.R.string.factorytest_no_action);
+                }
+                if (errorMsg == null) {
+                    return;
+                }
+
+                mTopAction = null;
+                mTopData = null;
+                mTopComponent = null;
+                mUiHandler.post(() -> {
+                    Dialog d = new FactoryErrorDialog(mUiContext, errorMsg);
+                    d.show();
+                    mAmInternal.ensureBootCompleted();
+                });
+            }
+        }
+
+        @Override
+        public void handleAppDied(WindowProcessController wpc, boolean restarting,
+                Runnable finishInstrumentationCallback) {
+            synchronized (mGlobalLock) {
+                // Remove this application's activities from active lists.
+                boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
+
+                wpc.clearRecentTasks();
+                wpc.clearActivities();
+
+                if (wpc.isInstrumenting()) {
+                    finishInstrumentationCallback.run();
+                }
+
+                mWindowManager.deferSurfaceLayout();
+                try {
+                    if (!restarting && hasVisibleActivities
+                            && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
+                        // If there was nothing to resume, and we are not already restarting this
+                        // process, but there is a visible activity that is hosted by the process...
+                        // then make sure all visible activities are running, taking care of
+                        // restarting this process.
+                        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+                    }
+                } finally {
+                    mWindowManager.continueSurfaceLayout();
+                }
+            }
+        }
+
+        @Override
+        public void closeSystemDialogs(String reason) {
+            enforceNotIsolatedCaller("closeSystemDialogs");
+
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                synchronized (mGlobalLock) {
+                    // Only allow this from foreground processes, so that background
+                    // applications can't abuse it to prevent system UI from being shown.
+                    if (uid >= FIRST_APPLICATION_UID) {
+                        final WindowProcessController proc = mPidMap.get(pid);
+                        if (!proc.isPerceptible()) {
+                            Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
+                                    + " from background process " + proc);
+                            return;
+                        }
+                    }
+                    mWindowManager.closeSystemDialogs(reason);
+
+                    mStackSupervisor.closeSystemDialogsLocked();
+                }
+                // Call into AM outside the synchronized block.
+                mAmInternal.broadcastCloseSystemDialogs(reason);
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+
+        @Override
+        public void cleanupDisabledPackageComponents(
+                String packageName, Set<String> disabledClasses, int userId, boolean booted) {
+            synchronized (mGlobalLock) {
+                // Clean-up disabled activities.
+                if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
+                        packageName, disabledClasses, true, false, userId) && booted) {
+                    mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
+                    mStackSupervisor.scheduleIdleLocked();
+                }
+
+                // Clean-up disabled tasks
+                getRecentTasks().cleanupDisabledPackageTasksLocked(
+                        packageName, disabledClasses, userId);
+            }
+        }
+
+        @Override
+        public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
+                int userId) {
+            synchronized (mGlobalLock) {
+
+                boolean didSomething =
+                        getActivityStartController().clearPendingActivityLaunches(packageName);
+                didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
+                        null, doit, evenPersistent, userId);
+                return didSomething;
+            }
+        }
+
+        @Override
+        public void resumeTopActivities(boolean scheduleIdle) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
+                if (scheduleIdle) {
+                    mStackSupervisor.scheduleIdleLocked();
+                }
+            }
+        }
+
+        @Override
+        public void preBindApplication(WindowProcessController wpc) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
+            }
+        }
+
+        @Override
+        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
+            synchronized (mGlobalLock) {
+                return mStackSupervisor.attachApplicationLocked(wpc);
+            }
+        }
+
+        @Override
+        public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
+            try {
+                if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
+                    throw new SecurityException("Only privileged app can call notifyLockedProfile");
+                }
+            } catch (RemoteException ex) {
+                throw new SecurityException("Fail to check is caller a privileged app", ex);
+            }
+
+            synchronized (mGlobalLock) {
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    if (mAmInternal.shouldConfirmCredentials(userId)) {
+                        if (mKeyguardController.isKeyguardLocked()) {
+                            // Showing launcher to avoid user entering credential twice.
+                            startHomeActivity(currentUserId, "notifyLockedProfile");
+                        }
+                        mStackSupervisor.lockAllProfileTasks(userId);
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
+
+        @Override
+        public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
+            mAmInternal.enforceCallingPermission(
+                    MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
+
+            synchronized (mGlobalLock) {
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
+                            FLAG_ACTIVITY_TASK_ON_HOME);
+                    ActivityOptions activityOptions = options != null
+                            ? new ActivityOptions(options) : ActivityOptions.makeBasic();
+                    activityOptions.setLaunchTaskId(
+                            mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
+                    mContext.startActivityAsUser(intent, activityOptions.toBundle(),
+                            UserHandle.CURRENT);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
+
+        @Override
+        public void writeActivitiesToProto(ProtoOutputStream proto) {
+            synchronized (mGlobalLock) {
+                // The output proto of "activity --proto activities"
+                // is ActivityManagerServiceDumpActivitiesProto
+                mStackSupervisor.writeToProto(proto,
+                        ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
+            }
+        }
+
+        @Override
+        public void saveANRState(String reason) {
+            synchronized (mGlobalLock) {
+                final StringWriter sw = new StringWriter();
+                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
+                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
+                if (reason != null) {
+                    pw.println("  Reason: " + reason);
+                }
+                pw.println();
+                getActivityStartController().dump(pw, "  ", null);
+                pw.println();
+                pw.println("-------------------------------------------------------------------------------");
+                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
+                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
+                        "" /* header */);
+                pw.println();
+                pw.close();
+
+                mLastANRState = sw.toString();
+            }
+        }
+
+        @Override
+        public void clearSavedANRState() {
+            synchronized (mGlobalLock) {
+                mLastANRState = null;
+            }
+        }
+
+        @Override
+        public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
+                boolean dumpAll, boolean dumpClient, String dumpPackage) {
+            synchronized (mGlobalLock) {
+                if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
+                    dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
+                } else if (DUMP_LASTANR_CMD.equals(cmd)) {
+                    dumpLastANRLocked(pw);
+                } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
+                    dumpLastANRTracesLocked(pw);
+                } else if (DUMP_STARTER_CMD.equals(cmd)) {
+                    dumpActivityStarterLocked(pw, dumpPackage);
+                } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
+                    dumpActivityContainersLocked(pw);
+                } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
+                    if (getRecentTasks() != null) {
+                        getRecentTasks().dump(pw, dumpAll, dumpPackage);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
+                String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
+                int wakefulness) {
+            synchronized (mGlobalLock) {
+                if (mHomeProcess != null && (dumpPackage == null
+                        || mHomeProcess.mPkgList.contains(dumpPackage))) {
+                    if (needSep) {
+                        pw.println();
+                        needSep = false;
+                    }
+                    pw.println("  mHomeProcess: " + mHomeProcess);
+                }
+                if (mPreviousProcess != null && (dumpPackage == null
+                        || mPreviousProcess.mPkgList.contains(dumpPackage))) {
+                    if (needSep) {
+                        pw.println();
+                        needSep = false;
+                    }
+                    pw.println("  mPreviousProcess: " + mPreviousProcess);
+                }
+                if (dumpAll && (mPreviousProcess == null || dumpPackage == null
+                        || mPreviousProcess.mPkgList.contains(dumpPackage))) {
+                    StringBuilder sb = new StringBuilder(128);
+                    sb.append("  mPreviousProcessVisibleTime: ");
+                    TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
+                    pw.println(sb);
+                }
+                if (mHeavyWeightProcess != null && (dumpPackage == null
+                        || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
+                    if (needSep) {
+                        pw.println();
+                        needSep = false;
+                    }
+                    pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
+                }
+                if (dumpPackage == null) {
+                    pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
+                    mStackSupervisor.dumpDisplayConfigs(pw, "  ");
+                }
+                if (dumpAll) {
+                    if (dumpPackage == null) {
+                        pw.println("  mConfigWillChange: "
+                                + getTopDisplayFocusedStack().mConfigWillChange);
+                    }
+                    if (mCompatModePackages.getPackages().size() > 0) {
+                        boolean printed = false;
+                        for (Map.Entry<String, Integer> entry
+                                : mCompatModePackages.getPackages().entrySet()) {
+                            String pkg = entry.getKey();
+                            int mode = entry.getValue();
+                            if (dumpPackage != null && !dumpPackage.equals(pkg)) {
+                                continue;
+                            }
+                            if (!printed) {
+                                pw.println("  mScreenCompatPackages:");
+                                printed = true;
+                            }
+                            pw.println("    " + pkg + ": " + mode);
+                        }
+                    }
+                }
+
+                if (dumpPackage == null) {
+                    pw.println("  mWakefulness="
+                            + PowerManagerInternal.wakefulnessToString(wakefulness));
+                    pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
+                    if (mRunningVoice != null) {
+                        pw.println("  mRunningVoice=" + mRunningVoice);
+                        pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
+                    }
+                    pw.println("  mSleeping=" + mSleeping);
+                    pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
+                    pw.println("  mVrController=" + mVrController);
+                }
+                if (mCurAppTimeTracker != null) {
+                    mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
+                }
+                if (mAllowAppSwitchUids.size() > 0) {
+                    boolean printed = false;
+                    for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
+                        ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
+                        for (int j = 0; j < types.size(); j++) {
+                            if (dumpPackage == null ||
+                                    UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
+                                if (needSep) {
+                                    pw.println();
+                                    needSep = false;
+                                }
+                                if (!printed) {
+                                    pw.println("  mAllowAppSwitchUids:");
+                                    printed = true;
+                                }
+                                pw.print("    User ");
+                                pw.print(mAllowAppSwitchUids.keyAt(i));
+                                pw.print(": Type ");
+                                pw.print(types.keyAt(j));
+                                pw.print(" = ");
+                                UserHandle.formatUid(pw, types.valueAt(j).intValue());
+                                pw.println();
+                            }
+                        }
+                    }
+                }
+                if (dumpPackage == null) {
+                    if (mController != null) {
+                        pw.println("  mController=" + mController
+                                + " mControllerIsAMonkey=" + mControllerIsAMonkey);
+                    }
+                    pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
+                    pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
+                }
+
+                return needSep;
+            }
+        }
+
+        @Override
+        public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
+            synchronized (mGlobalLock) {
+                if (dumpPackage == null) {
+                    getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
+                    proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
+                    writeSleepStateToProto(proto);
+                    if (mController != null) {
+                        final long token = proto.start(CONTROLLER);
+                        proto.write(CONTROLLER, mController.toString());
+                        proto.write(IS_A_MONKEY, mControllerIsAMonkey);
+                        proto.end(token);
+                    }
+                    mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
+                    mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
+                }
+
+                if (mHomeProcess != null && (dumpPackage == null
+                        || mHomeProcess.mPkgList.contains(dumpPackage))) {
+                    mHomeProcess.writeToProto(proto, HOME_PROC);
+                }
+
+                if (mPreviousProcess != null && (dumpPackage == null
+                        || mPreviousProcess.mPkgList.contains(dumpPackage))) {
+                    mPreviousProcess.writeToProto(proto, PREVIOUS_PROC);
+                    proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
+                }
+
+                if (mHeavyWeightProcess != null && (dumpPackage == null
+                        || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
+                    mHeavyWeightProcess.writeToProto(proto, HEAVY_WEIGHT_PROC);
+                }
+
+                for (Map.Entry<String, Integer> entry
+                        : mCompatModePackages.getPackages().entrySet()) {
+                    String pkg = entry.getKey();
+                    int mode = entry.getValue();
+                    if (dumpPackage == null || dumpPackage.equals(pkg)) {
+                        long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
+                        proto.write(PACKAGE, pkg);
+                        proto.write(MODE, mode);
+                        proto.end(compatToken);
+                    }
+                }
+
+                if (mCurAppTimeTracker != null) {
+                    mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
+                }
+
+            }
+        }
+
+        @Override
+        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);
+            }
+        }
+
+        @Override
+        public boolean canGcNow() {
+            synchronized (mGlobalLock) {
+                return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
+            }
+        }
+
+        @Override
+        public WindowProcessController getTopApp() {
+            synchronized (mGlobalLock) {
+                final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
+                return top != null ? top.app : null;
+            }
+        }
+
+        @Override
+        public void rankTaskLayersIfNeeded() {
+            synchronized (mGlobalLock) {
+                if (mStackSupervisor != null) {
+                    mStackSupervisor.rankTaskLayersIfNeeded();
+                }
+            }
+        }
+
+        @Override
+        public void scheduleDestroyAllActivities(String reason) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.scheduleDestroyAllActivities(null, reason);
+            }
+        }
+
+        @Override
+        public void removeUser(int userId) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.removeUserLocked(userId);
+            }
+        }
+
+        @Override
+        public boolean switchUser(int userId, UserState userState) {
+            synchronized (mGlobalLock) {
+                return mStackSupervisor.switchUserLocked(userId, userState);
+            }
+        }
+
+        @Override
+        public void onHandleAppCrash(WindowProcessController wpc) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.handleAppCrashLocked(wpc);
+            }
+        }
+
+        @Override
+        public int finishTopCrashedActivities(WindowProcessController crashedApp, String reason) {
+            synchronized (mGlobalLock) {
+                return mStackSupervisor.finishTopCrashedActivitiesLocked(crashedApp, reason);
+            }
+        }
+
+        @Override
+        public void onUidActive(int uid, int procState) {
+            synchronized (mGlobalLock) {
+                mActiveUids.put(uid, procState);
+            }
+        }
+
+        @Override
+        public void onUidInactive(int uid) {
+            synchronized (mGlobalLock) {
+                mActiveUids.remove(uid);
+            }
+        }
+
+        @Override
+        public void onActiveUidsCleared() {
+            synchronized (mGlobalLock) {
+                mActiveUids.clear();
+            }
+        }
+
+        @Override
+        public void onUidProcStateChanged(int uid, int procState) {
+            synchronized (mGlobalLock) {
+                if (mActiveUids.get(uid) != null) {
+                    mActiveUids.put(uid, procState);
+                }
+            }
+        }
+
+        @Override
+        public void onUidAddedToPendingTempWhitelist(int uid, String tag) {
+            synchronized (mGlobalLock) {
+                mPendingTempWhitelist.put(uid, tag);
+            }
+        }
+
+        @Override
+        public void onUidRemovedFromPendingTempWhitelist(int uid) {
+            synchronized (mGlobalLock) {
+                mPendingTempWhitelist.remove(uid);
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/am/AppErrorDialog.java b/services/core/java/com/android/server/am/AppErrorDialog.java
index cde633d..a80a5b5 100644
--- a/services/core/java/com/android/server/am/AppErrorDialog.java
+++ b/services/core/java/com/android/server/am/AppErrorDialog.java
@@ -16,6 +16,8 @@
 
 package com.android.server.am;
 
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -63,7 +65,7 @@
         mService = service;
         mProc = data.proc;
         mResult = data.result;
-        mIsRestartable = (data.task != null || data.isRestartableForService)
+        mIsRestartable = (data.taskId != INVALID_TASK_ID || data.isRestartableForService)
                 && Settings.Global.getInt(context.getContentResolver(),
                 Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG, 0) != 0;
         BidiFormatter bidi = BidiFormatter.getInstance();
@@ -209,7 +211,7 @@
 
     static class Data {
         AppErrorResult result;
-        TaskRecord task;
+        int taskId;
         boolean repeating;
         ProcessRecord proc;
         boolean isRestartableForService;
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 6a9c887..e8ec057 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -16,12 +16,13 @@
 
 package com.android.server.am;
 
-import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 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.ActivityManagerService.MY_PID;
 import static com.android.server.am.ActivityManagerService.SYSTEM_DEBUGGABLE;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
 
 import android.app.ActivityManager;
 import android.app.ActivityOptions;
@@ -46,21 +47,17 @@
 import android.util.EventLog;
 import android.util.Slog;
 import android.util.SparseArray;
-import android.util.StatsLog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.app.ProcessMap;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
-import com.android.internal.os.ProcessCpuTracker;
 import com.android.server.RescueParty;
 import com.android.server.Watchdog;
 
-import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Set;
 
@@ -124,7 +121,7 @@
                 proto.write(AppErrorsProto.ProcessCrashTime.PROCESS_NAME, pname);
                 for (int i = 0; i < uidCount; i++) {
                     final int puid = uids.keyAt(i);
-                    final ProcessRecord r = mService.mProcessNames.get(pname, puid);
+                    final ProcessRecord r = mService.getProcessNames().get(pname, puid);
                     if (dumpPackage != null && (r == null || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
                     }
@@ -151,7 +148,7 @@
                 proto.write(AppErrorsProto.BadProcess.PROCESS_NAME, pname);
                 for (int i = 0; i < uidCount; i++) {
                     final int puid = uids.keyAt(i);
-                    final ProcessRecord r = mService.mProcessNames.get(pname, puid);
+                    final ProcessRecord r = mService.getProcessNames().get(pname, puid);
                     if (dumpPackage != null && (r == null
                             || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
@@ -184,7 +181,7 @@
                 final int uidCount = uids.size();
                 for (int i = 0; i < uidCount; i++) {
                     final int puid = uids.keyAt(i);
-                    final ProcessRecord r = mService.mProcessNames.get(pname, puid);
+                    final ProcessRecord r = mService.getProcessNames().get(pname, puid);
                     if (dumpPackage != null && (r == null
                             || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
@@ -214,7 +211,7 @@
                 final int uidCount = uids.size();
                 for (int i = 0; i < uidCount; i++) {
                     final int puid = uids.keyAt(i);
-                    final ProcessRecord r = mService.mProcessNames.get(pname, puid);
+                    final ProcessRecord r = mService.getProcessNames().get(pname, puid);
                     if (dumpPackage != null && (r == null
                             || !r.pkgList.containsKey(dumpPackage))) {
                         continue;
@@ -411,11 +408,10 @@
         }
 
         final int relaunchReason = r != null
-                ? r.getWindowProcessController().computeRelaunchReason()
-                : ActivityRecord.RELAUNCH_REASON_NONE;
+                ? r.getWindowProcessController().computeRelaunchReason() : RELAUNCH_REASON_NONE;
 
         AppErrorResult result = new AppErrorResult();
-        TaskRecord task;
+        int taskId;
         synchronized (mService) {
             /**
              * If crash is handled by instance of {@link android.app.IActivityController},
@@ -428,7 +424,7 @@
 
             // Suppress crash dialog if the process is being relaunched due to a crash during a free
             // resize.
-            if (relaunchReason == ActivityRecord.RELAUNCH_REASON_FREE_RESIZE) {
+            if (relaunchReason == RELAUNCH_REASON_FREE_RESIZE) {
                 return;
             }
 
@@ -458,7 +454,7 @@
             final Message msg = Message.obtain();
             msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
 
-            task = data.task;
+            taskId = data.taskId;
             msg.obj = data;
             mService.mUiHandler.sendMessage(msg);
         }
@@ -475,25 +471,15 @@
                 stopReportingCrashesLocked(r);
             }
             if (res == AppErrorDialog.RESTART) {
-                mService.removeProcessLocked(r, false, true, "crash");
-                if (task != null) {
+                mService.mProcessList.removeProcessLocked(r, false, true, "crash");
+                if (taskId != INVALID_TASK_ID) {
                     try {
-                        mService.mActivityTaskManager.startActivityFromRecents(task.taskId,
+                        mService.mActivityTaskManager.startActivityFromRecents(taskId,
                                 ActivityOptions.makeBasic().toBundle());
                     } catch (IllegalArgumentException e) {
-                        // Hmm, that didn't work, app might have crashed before creating a
-                        // recents entry. Let's see if we have a safe-to-restart intent.
-                        final Set<String> cats = task.intent != null
-                                ? task.intent.getCategories() : null;
-                        if (cats != null && cats.contains(Intent.CATEGORY_LAUNCHER)) {
-                            mService.mActivityTaskManager.getActivityStartController().startActivityInPackage(
-                                    task.mCallingUid, callingPid, callingUid, task.mCallingPackage,
-                                    task.intent, null, null, null, 0, 0,
-                                    new SafeActivityOptions(ActivityOptions.makeBasic()),
-                                    task.userId, null,
-                                    "AppErrors", false /*validateIncomingUser*/,
-                                    null /* originatingPendingIntent */);
-                        }
+                        // Hmm...that didn't work. Task should either be in recents or associated
+                        // with a stack.
+                        Slog.e(TAG, "Could not restart taskId=" + taskId, e);
                     }
                 }
             }
@@ -501,10 +487,10 @@
                 long orig = Binder.clearCallingIdentity();
                 try {
                     // Kill it with fire!
-                    mService.mStackSupervisor.handleAppCrashLocked(r.getWindowProcessController());
+                    mService.mAtmInternal.onHandleAppCrash(r.getWindowProcessController());
                     if (!r.isPersistent()) {
-                        mService.removeProcessLocked(r, false, false, "crash");
-                        mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
+                        mService.mProcessList.removeProcessLocked(r, false, false, "crash");
+                        mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
                     }
                 } finally {
                     Binder.restoreCallingIdentity(orig);
@@ -565,7 +551,7 @@
                     } else {
                         // Huh.
                         Process.killProcess(pid);
-                        ActivityManagerService.killProcessGroup(uid, pid);
+                        ProcessList.killProcessGroup(uid, pid);
                     }
                 }
                 return true;
@@ -582,27 +568,12 @@
         app.setCrashing(true);
         app.crashingReport = generateProcessError(app,
                 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
-        startAppProblemLocked(app);
+        app.startAppProblemLocked();
         app.getWindowProcessController().stopFreezingActivities();
         return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace,
                 data);
     }
 
-    void startAppProblemLocked(ProcessRecord app) {
-        // If this app is not running under the current user, then we
-        // can't give it a report button because that would require
-        // launching the report UI under a different user.
-        app.errorReportReceiver = null;
-
-        for (int userId : mService.mUserController.getCurrentProfileIds()) {
-            if (app.userId == userId) {
-                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
-                        mContext, app.info.packageName, app.info.flags);
-            }
-        }
-        mService.skipCurrentReceiverLocked(app);
-    }
-
     /**
      * Generate a process error record, suitable for attachment to a ProcessRecord.
      *
@@ -616,7 +587,7 @@
      *
      * @return Returns a fully-formed ProcessErrorStateInfo record.
      */
-    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
+    ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
             int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
         ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
 
@@ -684,7 +655,7 @@
                 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
 
         final boolean procIsBoundForeground =
-            (app.curProcState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
+            (app.getCurProcState() == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
 
         Long crashTime;
         Long crashTimePersistent;
@@ -723,7 +694,7 @@
                     + " has crashed too many times: killing!");
             EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
                     app.userId, app.info.processName, app.uid);
-            mService.mStackSupervisor.handleAppCrashLocked(app.getWindowProcessController());
+            mService.mAtmInternal.onHandleAppCrash(app.getWindowProcessController());
             if (!app.isPersistent()) {
                 // We don't want to start this process again until the user
                 // explicitly does so...  but for persistent process, we really
@@ -743,18 +714,18 @@
                 // Don't let services in this process be restarted and potentially
                 // annoy the user repeatedly.  Unless it is persistent, since those
                 // processes run critical code.
-                mService.removeProcessLocked(app, false, tryAgain, "crash");
-                mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
+                mService.mProcessList.removeProcessLocked(app, false, tryAgain, "crash");
+                mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
                 if (!showBackground) {
                     return false;
                 }
             }
-            mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
+            mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
         } else {
-            final TaskRecord affectedTask =
-                    mService.mStackSupervisor.finishTopCrashedActivitiesLocked(app.getWindowProcessController(), reason);
+            final int affectedTaskId = mService.mAtmInternal.finishTopCrashedActivities(
+                            app.getWindowProcessController(), reason);
             if (data != null) {
-                data.task = affectedTask;
+                data.taskId = affectedTaskId;
             }
             if (data != null && crashTimePersistent != null
                     && now < crashTimePersistent + ProcessList.MIN_CRASH_INTERVAL) {
@@ -854,259 +825,13 @@
         }
     }
 
-    void stopReportingCrashesLocked(ProcessRecord proc) {
+    private void stopReportingCrashesLocked(ProcessRecord proc) {
         if (mAppsNotReportingCrashes == null) {
             mAppsNotReportingCrashes = new ArraySet<>();
         }
         mAppsNotReportingCrashes.add(proc.info.packageName);
     }
 
-    static boolean isInterestingForBackgroundTraces(ProcessRecord app) {
-        // The system_server is always considered interesting.
-        if (app.pid == MY_PID) {
-            return true;
-        }
-
-        // A package is considered interesting if any of the following is true :
-        //
-        // - It's displaying an activity.
-        // - It's the SystemUI.
-        // - It has an overlay or a top UI visible.
-        //
-        // NOTE: The check whether a given ProcessRecord belongs to the systemui
-        // process is a bit of a kludge, but the same pattern seems repeated at
-        // several places in the system server.
-        return app.isInterestingToUserLocked() ||
-            (app.info != null && "com.android.systemui".equals(app.info.packageName)) ||
-            (app.hasTopUi || app.hasOverlayUi);
-    }
-
-    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
-            ActivityRecord parent, boolean aboveSystem, final String annotation) {
-        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
-        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
-
-        if (mService.mActivityTaskManager.mController != null) {
-            try {
-                // 0 == continue, -1 = kill process immediately
-                int res = mService.mActivityTaskManager.mController.appEarlyNotResponding(
-                        app.processName, app.pid, annotation);
-                if (res < 0 && app.pid != MY_PID) {
-                    app.kill("anr", true);
-                }
-            } catch (RemoteException e) {
-                mService.mActivityTaskManager.mController = null;
-                Watchdog.getInstance().setActivityController(null);
-            }
-        }
-
-        long anrTime = SystemClock.uptimeMillis();
-        if (ActivityManagerService.MONITOR_CPU_USAGE) {
-            mService.updateCpuStatsNow();
-        }
-
-        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
-        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
-
-        boolean isSilentANR;
-
-        synchronized (mService) {
-            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
-            if (mService.mActivityTaskManager.mShuttingDown) {
-                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
-                return;
-            } else if (app.isNotResponding()) {
-                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
-                return;
-            } else if (app.isCrashing()) {
-                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
-                return;
-            } else if (app.killedByAm) {
-                Slog.i(TAG, "App already killed by AM skipping ANR: " + app + " " + annotation);
-                return;
-            } else if (app.killed) {
-                Slog.i(TAG, "Skipping died app ANR: " + app + " " + annotation);
-                return;
-            }
-
-            // In case we come through here for the same app before completing
-            // this one, mark as anring now so we will bail out.
-            app.setNotResponding(true);
-
-            // Log the ANR to the event log.
-            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
-                    app.processName, app.info.flags, annotation);
-
-            // Dump thread traces as quickly as we can, starting with "interesting" processes.
-            firstPids.add(app.pid);
-
-            // Don't dump other PIDs if it's a background ANR
-            isSilentANR = !showBackground && !isInterestingForBackgroundTraces(app);
-            if (!isSilentANR) {
-                int parentPid = app.pid;
-                if (parent != null && parent.app != null && parent.app.getPid() > 0) {
-                    parentPid = parent.app.getPid();
-                }
-                if (parentPid != app.pid) firstPids.add(parentPid);
-
-                if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
-
-                for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
-                    ProcessRecord r = mService.mLruProcesses.get(i);
-                    if (r != null && r.thread != null) {
-                        int pid = r.pid;
-                        if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
-                            if (r.isPersistent()) {
-                                firstPids.add(pid);
-                                if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
-                            } else if (r.treatLikeActivity) {
-                                firstPids.add(pid);
-                                if (DEBUG_ANR) Slog.i(TAG, "Adding likely IME: " + r);
-                            } else {
-                                lastPids.put(pid, Boolean.TRUE);
-                                if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        // Log the ANR to the main log.
-        StringBuilder info = new StringBuilder();
-        info.setLength(0);
-        info.append("ANR in ").append(app.processName);
-        if (activity != null && activity.shortComponentName != null) {
-            info.append(" (").append(activity.shortComponentName).append(")");
-        }
-        info.append("\n");
-        info.append("PID: ").append(app.pid).append("\n");
-        if (annotation != null) {
-            info.append("Reason: ").append(annotation).append("\n");
-        }
-        if (parent != null && parent != activity) {
-            info.append("Parent: ").append(parent.shortComponentName).append("\n");
-        }
-
-        ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
-
-        // don't dump native PIDs for background ANRs unless it is the process of interest
-        String[] nativeProcs = null;
-        if (isSilentANR) {
-            for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
-                if (NATIVE_STACKS_OF_INTEREST[i].equals(app.processName)) {
-                    nativeProcs = new String[] { app.processName };
-                    break;
-                }
-            }
-        } else {
-            nativeProcs = NATIVE_STACKS_OF_INTEREST;
-        }
-
-        int[] pids = nativeProcs == null ? null : Process.getPidsForCommands(nativeProcs);
-        ArrayList<Integer> nativePids = null;
-
-        if (pids != null) {
-            nativePids = new ArrayList<Integer>(pids.length);
-            for (int i : pids) {
-                nativePids.add(i);
-            }
-        }
-
-        // For background ANRs, don't pass the ProcessCpuTracker to
-        // avoid spending 1/2 second collecting stats to rank lastPids.
-        File tracesFile = ActivityManagerService.dumpStackTraces(
-                firstPids,
-                (isSilentANR) ? null : processCpuTracker,
-                (isSilentANR) ? null : lastPids,
-                nativePids);
-
-        String cpuInfo = null;
-        if (ActivityManagerService.MONITOR_CPU_USAGE) {
-            mService.updateCpuStatsNow();
-            synchronized (mService.mProcessCpuTracker) {
-                cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
-            }
-            info.append(processCpuTracker.printCurrentLoad());
-            info.append(cpuInfo);
-        }
-
-        info.append(processCpuTracker.printCurrentState(anrTime));
-
-        Slog.e(TAG, info.toString());
-        if (tracesFile == null) {
-            // There is no trace file, so dump (only) the alleged culprit's threads to the log
-            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
-        }
-
-        StatsLog.write(StatsLog.ANR_OCCURRED, app.uid, app.processName,
-                activity == null ? "unknown": activity.shortComponentName, annotation,
-                (app.info != null) ? (app.info.isInstantApp()
-                        ? StatsLog.ANROCCURRED__IS_INSTANT_APP__TRUE
-                        : StatsLog.ANROCCURRED__IS_INSTANT_APP__FALSE)
-                        : StatsLog.ANROCCURRED__IS_INSTANT_APP__UNAVAILABLE,
-                app != null ? (app.isInterestingToUserLocked()
-                        ? StatsLog.ANROCCURRED__FOREGROUND_STATE__FOREGROUND
-                        : StatsLog.ANROCCURRED__FOREGROUND_STATE__BACKGROUND)
-                        : StatsLog.ANROCCURRED__FOREGROUND_STATE__UNKNOWN);
-        mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
-                cpuInfo, tracesFile, null);
-
-        if (mService.mActivityTaskManager.mController != null) {
-            try {
-                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
-                int res = mService.mActivityTaskManager.mController.appNotResponding(
-                        app.processName, app.pid, info.toString());
-                if (res != 0) {
-                    if (res < 0 && app.pid != MY_PID) {
-                        app.kill("anr", true);
-                    } else {
-                        synchronized (mService) {
-                            mService.mServices.scheduleServiceTimeoutLocked(app);
-                        }
-                    }
-                    return;
-                }
-            } catch (RemoteException e) {
-                mService.mActivityTaskManager.mController = null;
-                Watchdog.getInstance().setActivityController(null);
-            }
-        }
-
-        synchronized (mService) {
-            mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
-
-            if (isSilentANR) {
-                app.kill("bg anr", true);
-                return;
-            }
-
-            // Set the app's notResponding state, and look up the errorReportReceiver
-            makeAppNotRespondingLocked(app,
-                    activity != null ? activity.shortComponentName : null,
-                    annotation != null ? "ANR " + annotation : "ANR",
-                    info.toString());
-
-            // Bring up the infamous App Not Responding dialog
-            Message msg = Message.obtain();
-            msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
-            msg.obj = new AppNotRespondingDialog.Data(app, activity, aboveSystem);
-
-            mService.mUiHandler.sendMessage(msg);
-        }
-    }
-
-    private void makeAppNotRespondingLocked(ProcessRecord app,
-            String activity, String shortMsg, String longMsg) {
-        app.setNotResponding(true);
-        app.notRespondingReport = generateProcessError(app,
-                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
-                activity, shortMsg, longMsg, null);
-        startAppProblemLocked(app);
-        app.getWindowProcessController().stopFreezingActivities();
-    }
-
     void handleShowAnrUi(Message msg) {
         Dialog dialogToShow = null;
         synchronized (mService) {
diff --git a/services/core/java/com/android/server/am/AppNotRespondingDialog.java b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
index 7c983ff..cb76e2f 100644
--- a/services/core/java/com/android/server/am/AppNotRespondingDialog.java
+++ b/services/core/java/com/android/server/am/AppNotRespondingDialog.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.content.pm.ApplicationInfo;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto;
 
@@ -58,8 +59,8 @@
         setCancelable(false);
 
         int resid;
-        CharSequence name1 = data.activity != null
-                ? data.activity.info.loadLabel(context.getPackageManager())
+        CharSequence name1 = data.aInfo != null
+                ? data.aInfo.loadLabel(context.getPackageManager())
                 : null;
         CharSequence name2 = null;
         if ((mProc.pkgList.size() == 1) &&
@@ -181,12 +182,12 @@
 
     static class Data {
         final ProcessRecord proc;
-        final ActivityRecord activity;
+        final ApplicationInfo aInfo;
         final boolean aboveSystem;
 
-        Data(ProcessRecord proc, ActivityRecord activity, boolean aboveSystem) {
+        Data(ProcessRecord proc, ApplicationInfo aInfo, boolean aboveSystem) {
             this.proc = proc;
-            this.activity = activity;
+            this.aInfo = aInfo;
             this.aboveSystem = aboveSystem;
         }
     }
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index e2035f6..a0977be 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -191,7 +191,7 @@
 
         @Override
         public void run() {
-            mService.mAppErrors.appNotResponding(mApp, null, null, false, mAnnotation);
+            mApp.appNotResponding(null, null, null, null, false, mAnnotation);
         }
     }
 
@@ -286,7 +286,7 @@
         r.curApp = app;
         app.curReceivers.add(r);
         app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
-        mService.updateLruProcessLocked(app, false, null);
+        mService.mProcessList.updateLruProcessLocked(app, false, null);
         if (!skipOomAdj) {
             mService.updateOomAdjLocked();
         }
@@ -892,7 +892,7 @@
                     isDead = proc == null || proc.isCrashing();
                 }
             } else {
-                final ProcessRecord proc = mService.mProcessNames.get(
+                final ProcessRecord proc = mService.mProcessList.mProcessNames.get(
                         mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
                 isDead = proc == null || !proc.pendingStart;
             }
diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java
index 536f3a9..3c4ab00 100644
--- a/services/core/java/com/android/server/am/CompatModePackages.java
+++ b/services/core/java/com/android/server/am/CompatModePackages.java
@@ -16,8 +16,11 @@
 
 package com.android.server.am;
 
-import static com.android.server.am.ActivityManagerDebugConfig.*;
 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -48,7 +51,7 @@
 import android.util.Xml;
 
 public final class CompatModePackages {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "CompatModePackages" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "CompatModePackages" : TAG_ATM;
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
 
     private final ActivityTaskManagerService mService;
@@ -61,7 +64,7 @@
 
     private final HashMap<String, Integer> mPackages = new HashMap<String, Integer>();
 
-    private static final int MSG_WRITE = ActivityManagerService.FIRST_COMPAT_MODE_MSG;
+    private static final int MSG_WRITE = 300;
 
     private final CompatHandler mHandler;
 
@@ -321,16 +324,16 @@
             ActivityRecord starting = stack.restartPackage(packageName);
 
             // Tell all processes that loaded this package about the change.
-            for (int i = mService.mAm.mLruProcesses.size() - 1; i >= 0; i--) {
-                final ProcessRecord app = mService.mAm.mLruProcesses.get(i);
-                if (!app.pkgList.containsKey(packageName)) {
+            for (int i = mService.mPidMap.size() - 1; i >= 0; i--) {
+                final WindowProcessController app = mService.mPidMap.valueAt(i);
+                if (!app.mPkgList.contains(packageName)) {
                     continue;
                 }
                 try {
-                    if (app.thread != null) {
+                    if (app.hasThread()) {
                         if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
-                                + app.processName + " new compat " + ci);
-                        app.thread.updatePackageCompatibilityInfo(packageName, ci);
+                                + app.mName + " new compat " + ci);
+                        app.getThread().updatePackageCompatibilityInfo(packageName, ci);
                     }
                 } catch (Exception e) {
                 }
diff --git a/services/core/java/com/android/server/am/ConnectionRecord.java b/services/core/java/com/android/server/am/ConnectionRecord.java
index fa8e6c4..1242ed6 100644
--- a/services/core/java/com/android/server/am/ConnectionRecord.java
+++ b/services/core/java/com/android/server/am/ConnectionRecord.java
@@ -35,7 +35,7 @@
  */
 final class ConnectionRecord {
     final AppBindRecord binding;    // The application/service binding.
-    final ActivityRecord activity;  // If non-null, the owning activity.
+    final ActivityServiceConnectionsHolder<ConnectionRecord> activity;  // If non-null, the owning activity.
     final IServiceConnection conn;  // The client connection.
     final int flags;                // Binding options.
     final int clientLabel;          // String resource labeling this client.
@@ -85,13 +85,14 @@
     void dump(PrintWriter pw, String prefix) {
         pw.println(prefix + "binding=" + binding);
         if (activity != null) {
-            pw.println(prefix + "activity=" + activity);
+            activity.dump(pw, prefix);
         }
         pw.println(prefix + "conn=" + conn.asBinder()
                 + " flags=0x" + Integer.toHexString(flags));
     }
 
-    ConnectionRecord(AppBindRecord _binding, ActivityRecord _activity,
+    ConnectionRecord(AppBindRecord _binding,
+            ActivityServiceConnectionsHolder<ConnectionRecord> _activity,
             IServiceConnection _conn, int _flags,
             int _clientLabel, PendingIntent _clientIntent,
             int _clientUid, String _clientProcessName) {
diff --git a/services/core/java/com/android/server/am/CoreSettingsObserver.java b/services/core/java/com/android/server/am/CoreSettingsObserver.java
index 160c753..48e26ed 100644
--- a/services/core/java/com/android/server/am/CoreSettingsObserver.java
+++ b/services/core/java/com/android/server/am/CoreSettingsObserver.java
@@ -55,6 +55,11 @@
         // add other system settings here...
 
         sGlobalSettingToTypeMap.put(Settings.Global.DEBUG_VIEW_ATTRIBUTES, int.class);
+        sGlobalSettingToTypeMap.put(Settings.Global.ANGLE_ENABLED_APP, String.class);
+        sGlobalSettingToTypeMap.put(Settings.Global.ENABLE_GPU_DEBUG_LAYERS, int.class);
+        sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_APP, String.class);
+        sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYERS, String.class);
+        sGlobalSettingToTypeMap.put(Settings.Global.GPU_DEBUG_LAYER_APP, String.class);
         // add other global settings here...
     }
 
@@ -121,6 +126,7 @@
                 value = Settings.Global.getString(context.getContentResolver(), setting);
             }
             if (value == null) {
+                snapshot.remove(setting);
                 continue;
             }
             Class<?> type = entry.getValue();
diff --git a/services/core/java/com/android/server/am/DeprecatedTargetSdkVersionDialog.java b/services/core/java/com/android/server/am/DeprecatedTargetSdkVersionDialog.java
index e5add58..b39873f 100644
--- a/services/core/java/com/android/server/am/DeprecatedTargetSdkVersionDialog.java
+++ b/services/core/java/com/android/server/am/DeprecatedTargetSdkVersionDialog.java
@@ -16,8 +16,8 @@
 
 package com.android.server.am;
 
-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.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.app.AlertDialog;
 import android.content.Context;
@@ -34,7 +34,7 @@
 import com.android.server.utils.AppInstallerUtil;
 
 public class DeprecatedTargetSdkVersionDialog {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "DeprecatedTargetSdkVersionDialog" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "DeprecatedTargetSdkVersionDialog" : TAG_ATM;
 
     private final AlertDialog mDialog;
     private final String mPackageName;
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index 0ef2a0a..09064f2 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -91,7 +91,7 @@
 30043 am_set_resumed_activity (User|1|5),(Component Name|3),(Reason|3)
 
 # Stack focus
-30044 am_focused_stack (User|1|5),(Focused Stack Id|1|5),(Last Focused Stack Id|1|5),(Reason|3)
+30044 am_focused_stack (User|1|5),(Display Id|1|5),(Focused Stack Id|1|5),(Last Focused Stack Id|1|5),(Reason|3)
 
 # Running pre boot receiver
 30045 am_pre_boot (User|1|5),(Package|3)
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index cfe2829..28b2a42 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -30,9 +30,9 @@
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
 import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
 
-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.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.KeyguardControllerProto.KEYGUARD_OCCLUDED_STATES;
 import static com.android.server.am.KeyguardControllerProto.KEYGUARD_SHOWING;
 import static com.android.server.am.KeyguardOccludedProto.DISPLAY_ID;
@@ -60,7 +60,7 @@
  */
 class KeyguardController {
 
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_ATM;
 
     private final ActivityStackSupervisor mStackSupervisor;
     private WindowManagerService mWindowManager;
diff --git a/services/core/java/com/android/server/am/LaunchParamsController.java b/services/core/java/com/android/server/am/LaunchParamsController.java
index 6415c3e..68e897f 100644
--- a/services/core/java/com/android/server/am/LaunchParamsController.java
+++ b/services/core/java/com/android/server/am/LaunchParamsController.java
@@ -16,6 +16,14 @@
 
 package com.android.server.am;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
+
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
+
 import android.annotation.IntDef;
 import android.app.ActivityOptions;
 import android.content.pm.ActivityInfo.WindowLayout;
@@ -26,13 +34,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
-import static android.view.Display.INVALID_DISPLAY;
-
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
-
 /**
  * {@link LaunchParamsController} calculates the {@link LaunchParams} by coordinating between
  * registered {@link LaunchParamsModifier}s.
@@ -58,11 +59,7 @@
      */
     void registerDefaultModifiers(ActivityStackSupervisor supervisor) {
         // {@link TaskLaunchParamsModifier} handles window layout preferences.
-        registerModifier(new TaskLaunchParamsModifier());
-
-        // {@link ActivityLaunchParamsModifier} is the most specific modifier and thus should be
-        // registered last (applied first) out of the defaults.
-        registerModifier(new ActivityLaunchParamsModifier(supervisor));
+        registerModifier(new TaskLaunchParamsModifier(supervisor));
     }
 
     /**
@@ -101,6 +98,15 @@
                     break;
             }
         }
+
+        if (activity != null && activity.requestedVrComponent != null) {
+            // Check if the Activity is a VR activity. If so, it should be launched in main display.
+            result.mPreferredDisplayId = DEFAULT_DISPLAY;
+        } else if (mService.mVr2dDisplayId != INVALID_DISPLAY) {
+            // Get the virtual display ID from ActivityTaskManagerService. If that's set we
+            // should always use that.
+            result.mPreferredDisplayId = mService.mVr2dDisplayId;
+        }
     }
 
     /**
@@ -226,27 +232,41 @@
         @IntDef({RESULT_SKIP, RESULT_DONE, RESULT_CONTINUE})
         @interface Result {}
 
-        // Returned when the modifier does not want to influence the bounds calculation
+        /** Returned when the modifier does not want to influence the bounds calculation */
         int RESULT_SKIP = 0;
-        // Returned when the modifier has changed the bounds and would like its results to be the
-        // final bounds applied.
+        /**
+         * Returned when the modifier has changed the bounds and would like its results to be the
+         * final bounds applied.
+         */
         int RESULT_DONE = 1;
-        // Returned when the modifier has changed the bounds but is okay with other modifiers
-        // influencing the bounds.
+        /**
+         * Returned when the modifier has changed the bounds but is okay with other modifiers
+         * influencing the bounds.
+         */
         int RESULT_CONTINUE = 2;
 
         /**
-         * Called when asked to calculate {@link LaunchParams}.
-         * @param task            The {@link TaskRecord} currently being positioned.
-         * @param layout          The specified {@link WindowLayout}.
-         * @param activity        The {@link ActivityRecord} currently being positioned.
-         * @param source          The {@link ActivityRecord} activity was started from.
-         * @param options         The {@link ActivityOptions} specified for the activity.
-         * @param currentParams   The current {@link LaunchParams}. This can differ from the initial
-         *                        params as it represents the modified params up to this point.
-         * @param outParams       The resulting {@link LaunchParams} after all calculations.
-         * @return                A {@link Result} representing the result of the
-         *                        {@link LaunchParams} calculation.
+         * Returns the launch params that the provided activity launch params should be overridden
+         * to. {@link LaunchParamsModifier} can use this for various purposes, including: 1)
+         * Providing default bounds if the launch bounds have not been provided. 2) Repositioning
+         * the task so it doesn't get placed over an existing task. 3) Resizing the task so that its
+         * dimensions match the activity's requested orientation.
+         *
+         * @param task          Can be: 1) the target task in which the source activity wants to
+         *                      launch the target activity; 2) a newly created task that Android
+         *                      gives a chance to override its launching bounds; 3) {@code null} if
+         *                      this is called to override an activity's launching bounds.
+         * @param layout        Desired layout when activity is first launched.
+         * @param activity      Activity that is being started. This can be {@code null} on
+         *                      re-parenting an activity to a new task (e.g. for
+         *                      Picture-In-Picture). Tasks being created because an activity was
+         *                      launched should have this be non-null.
+         * @param source        the Activity that launched a new task. Could be {@code null}.
+         * @param options       {@link ActivityOptions} used to start the activity with.
+         * @param currentParams launching params after the process of last {@link
+         *                      LaunchParamsModifier}.
+         * @param outParams     the result params to be set.
+         * @return see {@link LaunchParamsModifier.Result}
          */
         @Result
         int onCalculate(TaskRecord task, WindowLayout layout, ActivityRecord activity,
diff --git a/services/core/java/com/android/server/am/LockTaskController.java b/services/core/java/com/android/server/am/LockTaskController.java
index 643c922..5b31d5f 100644
--- a/services/core/java/com/android/server/am/LockTaskController.java
+++ b/services/core/java/com/android/server/am/LockTaskController.java
@@ -28,10 +28,10 @@
 import static android.telecom.TelecomManager.EMERGENCY_DIALER_COMPONENT;
 import static android.view.Display.DEFAULT_DISPLAY;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
-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.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
@@ -84,7 +84,7 @@
  * @see Activity#stopLockTask()
  */
 public class LockTaskController {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "LockTaskController" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "LockTaskController" : TAG_ATM;
     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
 
     @VisibleForTesting
diff --git a/services/core/java/com/android/server/am/MemoryStatUtil.java b/services/core/java/com/android/server/am/MemoryStatUtil.java
index a8e1ccc..85ee7e6 100644
--- a/services/core/java/com/android/server/am/MemoryStatUtil.java
+++ b/services/core/java/com/android/server/am/MemoryStatUtil.java
@@ -16,7 +16,7 @@
 
 package com.android.server.am;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_METRICS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
@@ -37,6 +37,38 @@
  * Static utility methods related to {@link MemoryStat}.
  */
 final class MemoryStatUtil {
+    /**
+     * Which native processes to create {@link MemoryStat} for.
+     *
+     * <p>Processes are matched by their cmdline in procfs. Example: cat /proc/pid/cmdline returns
+     * /system/bin/statsd for the stats daemon.
+     */
+    static final String[] MEMORY_STAT_INTERESTING_NATIVE_PROCESSES = new String[]{
+            "/system/bin/statsd",  // Stats daemon.
+            "/system/bin/surfaceflinger",
+            "/system/bin/apexd",  // APEX daemon.
+            "/system/bin/audioserver",
+            "/system/bin/cameraserver",
+            "/system/bin/drmserver",
+            "/system/bin/healthd",
+            "/system/bin/incidentd",
+            "/system/bin/installd",
+            "/system/bin/lmkd",  // Low memory killer daemon.
+            "/system/bin/logd",
+            "media.codec",
+            "media.extractor",
+            "media.metrics",
+            "/system/bin/mediadrmserver",
+            "/system/bin/mediaserver",
+            "/system/bin/performanced",
+            "/system/bin/tombstoned",
+            "/system/bin/traced",  // Perfetto.
+            "/system/bin/traced_probes",  // Perfetto.
+            "webview_zygote",
+            "zygote",
+            "zygote64",
+    };
+
     static final int BYTES_IN_KILOBYTE = 1024;
     static final int PAGE_SIZE = 4096;
 
@@ -57,6 +89,8 @@
     private static final String PROC_STAT_FILE_FMT = "/proc/%d/stat";
     /** Path to procfs status file for logging app memory state */
     private static final String PROC_STATUS_FILE_FMT = "/proc/%d/status";
+    /** Path to procfs cmdline file. Used with pid: /proc/pid/cmdline. */
+    private static final String PROC_CMDLINE_FILE_FMT = "/proc/%d/cmdline";
 
     private static final Pattern PGFAULT = Pattern.compile("total_pgfault (\\d+)");
     private static final Pattern PGMAJFAULT = Pattern.compile("total_pgmajfault (\\d+)");
@@ -119,6 +153,18 @@
         return stat;
     }
 
+    /**
+     * Reads cmdline of a process from procfs.
+     *
+     * Returns content of /proc/pid/cmdline (e.g. /system/bin/statsd) or an empty string
+     * if the file is not available.
+     */
+    static String readCmdlineFromProcfs(int pid) {
+        String path = String.format(Locale.US, PROC_CMDLINE_FILE_FMT, pid);
+        String cmdline = readFileContents(path);
+        return cmdline != null ? cmdline : "";
+    }
+
     private static String readFileContents(String path) {
         final File file = new File(path);
         if (!file.exists()) {
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index b9c6fa6..2dcddff 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -288,12 +288,19 @@
                 resolvedType = key.requestResolvedType;
             }
 
+            // Apply any launch flags from the ActivityOptions. This is to ensure that the caller
+            // can specify a consistent launch mode even if the PendingIntent is immutable
+            final ActivityOptions opts = ActivityOptions.fromBundle(options);
+            if (opts != null) {
+                finalIntent.addFlags(opts.getPendingIntentLaunchFlags());
+            }
+
             // Extract options before clearing calling identity
             mergedOptions = key.options;
             if (mergedOptions == null) {
-                mergedOptions = SafeActivityOptions.fromBundle(options);
+                mergedOptions = new SafeActivityOptions(opts);
             } else {
-                mergedOptions.setCallerOptions(ActivityOptions.fromBundle(options));
+                mergedOptions.setCallerOptions(opts);
             }
 
             if (whitelistDuration != null) {
diff --git a/services/core/java/com/android/server/am/PendingTempWhitelists.java b/services/core/java/com/android/server/am/PendingTempWhitelists.java
new file mode 100644
index 0000000..b36e3c7
--- /dev/null
+++ b/services/core/java/com/android/server/am/PendingTempWhitelists.java
@@ -0,0 +1,59 @@
+/*
+ * 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.am;
+
+import android.util.SparseArray;
+
+/** Whitelists of uids to temporarily bypass Power Save mode. */
+final class PendingTempWhitelists {
+
+    private ActivityManagerService mService;
+
+    private final SparseArray<ActivityManagerService.PendingTempWhitelist> mPendingTempWhitelist =
+            new SparseArray<>();
+
+    PendingTempWhitelists(ActivityManagerService service) {
+        mService = service;
+    }
+
+    void put(int uid, ActivityManagerService.PendingTempWhitelist value) {
+        mPendingTempWhitelist.put(uid, value);
+        mService.mAtmInternal.onUidAddedToPendingTempWhitelist(uid, value.tag);
+    }
+
+    void removeAt(int index) {
+        final int uid = mPendingTempWhitelist.keyAt(index);
+        mPendingTempWhitelist.removeAt(index);
+        mService.mAtmInternal.onUidRemovedFromPendingTempWhitelist(uid);
+    }
+
+    ActivityManagerService.PendingTempWhitelist get(int uid) {
+        return mPendingTempWhitelist.get(uid);
+    }
+
+    int size() {
+        return mPendingTempWhitelist.size();
+    }
+
+    ActivityManagerService.PendingTempWhitelist valueAt(int index) {
+        return mPendingTempWhitelist.valueAt(index);
+    }
+
+    int indexOfKey(int key) {
+        return mPendingTempWhitelist.indexOfKey(key);
+    }
+}
diff --git a/services/core/java/com/android/server/am/PersistentConnection.java b/services/core/java/com/android/server/am/PersistentConnection.java
index 080fa2a..3490b1d 100644
--- a/services/core/java/com/android/server/am/PersistentConnection.java
+++ b/services/core/java/com/android/server/am/PersistentConnection.java
@@ -59,6 +59,8 @@
  * know what to do when the service component has gone missing, for example.  If the user of this
  * class wants to restore the connection, then it should call {@link #unbind()} and {@link #bind}
  * explicitly.
+ *
+ * atest ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java
  */
 public abstract class PersistentConnection<T> {
     private final Object mLock = new Object();
@@ -76,6 +78,7 @@
     private final long mRebindBackoffMs;
     private final double mRebindBackoffIncrease;
     private final long mRebindMaxBackoffMs;
+    private final long mResetBackoffDelay;
 
     private long mReconnectTime;
 
@@ -109,6 +112,9 @@
     @GuardedBy("mLock")
     private int mNumBindingDied;
 
+    @GuardedBy("mLock")
+    private long mLastConnectedTime;
+
     private final ServiceConnection mServiceConnection = new ServiceConnection() {
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
@@ -127,7 +133,10 @@
                 mNumConnected++;
 
                 mIsConnected = true;
+                mLastConnectedTime = injectUptimeMillis();
                 mService = asInterface(service);
+
+                scheduleStableCheckLocked();
             }
         }
 
@@ -140,6 +149,9 @@
                 mNumDisconnected++;
 
                 cleanUpConnectionLocked();
+
+                // Note we won't increase the rebind timeout here, because we don't explicitly
+                // rebind in this case.
             }
         }
 
@@ -168,7 +180,8 @@
 
     public PersistentConnection(@NonNull String tag, @NonNull Context context,
             @NonNull Handler handler, int userId, @NonNull ComponentName componentName,
-            long rebindBackoffSeconds, double rebindBackoffIncrease, long rebindMaxBackoffSeconds) {
+            long rebindBackoffSeconds, double rebindBackoffIncrease, long rebindMaxBackoffSeconds,
+            long resetBackoffDelay) {
         mTag = tag;
         mContext = context;
         mHandler = handler;
@@ -178,6 +191,7 @@
         mRebindBackoffMs = rebindBackoffSeconds * 1000;
         mRebindBackoffIncrease = rebindBackoffIncrease;
         mRebindMaxBackoffMs = rebindMaxBackoffSeconds * 1000;
+        mResetBackoffDelay = resetBackoffDelay * 1000;
 
         mNextBackoffMs = mRebindBackoffMs;
     }
@@ -242,6 +256,42 @@
         }
     }
 
+    /** Return the next back-off time */
+    public long getNextBackoffMs() {
+        synchronized (mLock) {
+            return mNextBackoffMs;
+        }
+    }
+
+    /** Return the number of times the connected callback called. */
+    public int getNumConnected() {
+        synchronized (mLock) {
+            return mNumConnected;
+        }
+    }
+
+    /** Return the number of times the disconnected callback called. */
+    public int getNumDisconnected() {
+        synchronized (mLock) {
+            return mNumDisconnected;
+        }
+    }
+
+    /** Return the number of times the binding died callback called. */
+    public int getNumBindingDied() {
+        synchronized (mLock) {
+            return mNumBindingDied;
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void resetBackoffLocked() {
+        if (mNextBackoffMs != mRebindBackoffMs) {
+            mNextBackoffMs = mRebindBackoffMs;
+            Log.i(mTag, "Backoff reset to " + mNextBackoffMs);
+        }
+    }
+
     @GuardedBy("mLock")
     public final void bindInnerLocked(boolean resetBackoff) {
         unscheduleRebindLocked();
@@ -251,9 +301,10 @@
         }
         mBound = true;
 
+        unscheduleStableCheckLocked();
+
         if (resetBackoff) {
-            // Note this is the only place we reset the backoff time.
-            mNextBackoffMs = mRebindBackoffMs;
+            resetBackoffLocked();
         }
 
         final Intent service = new Intent().setComponent(mComponentName);
@@ -287,6 +338,8 @@
     private void cleanUpConnectionLocked() {
         mIsConnected = false;
         mService = null;
+
+        unscheduleStableCheckLocked();
     }
 
     /**
@@ -297,6 +350,7 @@
             mShouldBeBound = false;
 
             unbindLocked();
+            unscheduleStableCheckLocked();
         }
     }
 
@@ -338,6 +392,33 @@
         }
     }
 
+    private final Runnable mStableCheck = this::stableConnectionCheck;
+
+    private void stableConnectionCheck() {
+        synchronized (mLock) {
+            final long now = injectUptimeMillis();
+            final long timeRemaining = (mLastConnectedTime + mResetBackoffDelay) - now;
+            if (DEBUG) {
+                Log.d(mTag, "stableConnectionCheck: bound=" + mBound + " connected=" + mIsConnected
+                        + " remaining=" + timeRemaining);
+            }
+            if (mBound && mIsConnected && timeRemaining <= 0) {
+                resetBackoffLocked();
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void unscheduleStableCheckLocked() {
+        injectRemoveCallbacks(mStableCheck);
+    }
+
+    @GuardedBy("mLock")
+    private void scheduleStableCheckLocked() {
+        unscheduleStableCheckLocked();
+        injectPostAtTime(mStableCheck, injectUptimeMillis() + mResetBackoffDelay);
+    }
+
     /** Must be implemented by a subclass to convert an {@link IBinder} to a stub. */
     protected abstract T asInterface(IBinder binder);
 
@@ -367,6 +448,10 @@
             pw.print(mNumDisconnected);
             pw.print("  Died: ");
             pw.print(mNumBindingDied);
+            if (mIsConnected) {
+                pw.print("  Duration: ");
+                TimeUtils.formatDuration((injectUptimeMillis() - mLastConnectedTime), pw);
+            }
             pw.println();
         }
     }
@@ -407,6 +492,11 @@
     }
 
     @VisibleForTesting
+    Runnable getStableCheckRunnableForTest() {
+        return mStableCheck;
+    }
+
+    @VisibleForTesting
     boolean shouldBeBoundForTest() {
         return mShouldBeBound;
     }
diff --git a/services/core/java/com/android/server/am/PersisterQueue.java b/services/core/java/com/android/server/am/PersisterQueue.java
new file mode 100644
index 0000000..60ea0fa
--- /dev/null
+++ b/services/core/java/com/android/server/am/PersisterQueue.java
@@ -0,0 +1,277 @@
+/*
+ * 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.am;
+
+import android.os.Process;
+import android.os.SystemClock;
+import android.util.Slog;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.function.Predicate;
+
+/**
+ * The common threading logic for persisters to use so that they can run in the same threads.
+ * Methods in this class are synchronized on its instance, so caller could also synchronize on
+ * its instance to perform modifications in items.
+ */
+class PersisterQueue {
+    private static final String TAG = "PersisterQueue";
+    private static final boolean DEBUG = false;
+
+    /** When not flushing don't write out files faster than this */
+    private static final long INTER_WRITE_DELAY_MS = 500;
+
+    /**
+     * When not flushing delay this long before writing the first file out. This gives the next task
+     * being launched a chance to load its resources without this occupying IO bandwidth.
+     */
+    private static final long PRE_TASK_DELAY_MS = 3000;
+
+    /** The maximum number of entries to keep in the queue before draining it automatically. */
+    private static final int MAX_WRITE_QUEUE_LENGTH = 6;
+
+    /** Special value for mWriteTime to mean don't wait, just write */
+    private static final long FLUSH_QUEUE = -1;
+
+    /** An {@link WriteQueueItem} that doesn't do anything. Used to trigger {@link
+     * Listener#onPreProcessItem}. */
+    static final WriteQueueItem EMPTY_ITEM = () -> { };
+
+    private final long mInterWriteDelayMs;
+    private final long mPreTaskDelayMs;
+    private final LazyTaskWriterThread mLazyTaskWriterThread;
+    private final ArrayList<WriteQueueItem> mWriteQueue = new ArrayList<>();
+
+    private final ArrayList<Listener> mListeners = new ArrayList<>();
+
+    /**
+     * Value determines write delay mode as follows: < 0 We are Flushing. No delays between writes
+     * until the image queue is drained and all tasks needing persisting are written to disk. There
+     * is no delay between writes. == 0 We are Idle. Next writes will be delayed by
+     * #PRE_TASK_DELAY_MS. > 0 We are Actively writing. Next write will be at this time. Subsequent
+     * writes will be delayed by #INTER_WRITE_DELAY_MS.
+     */
+    private long mNextWriteTime = 0;
+
+    PersisterQueue() {
+        this(INTER_WRITE_DELAY_MS, PRE_TASK_DELAY_MS);
+    }
+
+    /** Used for tests to reduce waiting time. */
+    @VisibleForTesting
+    PersisterQueue(long interWriteDelayMs, long preTaskDelayMs) {
+        if (interWriteDelayMs < 0 || preTaskDelayMs < 0) {
+            throw new IllegalArgumentException("Both inter-write delay and pre-task delay need to"
+                    + "be non-negative. inter-write delay: " + interWriteDelayMs
+                    + "ms pre-task delay: " + preTaskDelayMs);
+        }
+        mInterWriteDelayMs = interWriteDelayMs;
+        mPreTaskDelayMs = preTaskDelayMs;
+        mLazyTaskWriterThread = new LazyTaskWriterThread("LazyTaskWriterThread");
+    }
+
+    synchronized void startPersisting() {
+        if (!mLazyTaskWriterThread.isAlive()) {
+            mLazyTaskWriterThread.start();
+        }
+    }
+
+    /** Stops persisting thread. Should only be used in tests. */
+    @VisibleForTesting
+    void stopPersisting() throws InterruptedException {
+        if (!mLazyTaskWriterThread.isAlive()) {
+            return;
+        }
+
+        synchronized (this) {
+            mLazyTaskWriterThread.interrupt();
+        }
+        mLazyTaskWriterThread.join();
+    }
+
+    synchronized void addItem(WriteQueueItem item, boolean flush) {
+        mWriteQueue.add(item);
+
+        if (flush || mWriteQueue.size() > MAX_WRITE_QUEUE_LENGTH) {
+            mNextWriteTime = FLUSH_QUEUE;
+        } else if (mNextWriteTime == 0) {
+            mNextWriteTime = SystemClock.uptimeMillis() + mPreTaskDelayMs;
+        }
+        notify();
+    }
+
+    synchronized <T extends WriteQueueItem> T findLastItem(Predicate<T> predicate, Class<T> clazz) {
+        for (int i = mWriteQueue.size() - 1; i >= 0; --i) {
+            WriteQueueItem writeQueueItem = mWriteQueue.get(i);
+            if (clazz.isInstance(writeQueueItem)) {
+                T item = clazz.cast(writeQueueItem);
+                if (predicate.test(item)) {
+                    return item;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    synchronized <T extends WriteQueueItem> void removeItems(Predicate<T> predicate,
+            Class<T> clazz) {
+        for (int i = mWriteQueue.size() - 1; i >= 0; --i) {
+            WriteQueueItem writeQueueItem = mWriteQueue.get(i);
+            if (clazz.isInstance(writeQueueItem)) {
+                T item = clazz.cast(writeQueueItem);
+                if (predicate.test(item)) {
+                    if (DEBUG) Slog.d(TAG, "Removing " + item + " from write queue.");
+                    mWriteQueue.remove(i);
+                }
+            }
+        }
+    }
+
+    synchronized void flush() {
+        mNextWriteTime = FLUSH_QUEUE;
+        notifyAll();
+        do {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+            }
+        } while (mNextWriteTime == FLUSH_QUEUE);
+    }
+
+    void yieldIfQueueTooDeep() {
+        boolean stall = false;
+        synchronized (this) {
+            if (mNextWriteTime == FLUSH_QUEUE) {
+                stall = true;
+            }
+        }
+        if (stall) {
+            Thread.yield();
+        }
+    }
+
+    void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    private void processNextItem() throws InterruptedException {
+        // This part is extracted into a method so that the GC can clearly see the end of the
+        // scope of the variable 'item'.  If this part was in the loop in LazyTaskWriterThread, the
+        // last item it processed would always "leak".
+        // See https://b.corp.google.com/issues/64438652#comment7
+
+        // If mNextWriteTime, then don't delay between each call to saveToXml().
+        final WriteQueueItem item;
+        synchronized (this) {
+            if (mNextWriteTime != FLUSH_QUEUE) {
+                // The next write we don't have to wait so long.
+                mNextWriteTime = SystemClock.uptimeMillis() + mInterWriteDelayMs;
+                if (DEBUG) {
+                    Slog.d(TAG, "Next write time may be in " + mInterWriteDelayMs
+                            + " msec. (" + mNextWriteTime + ")");
+                }
+            }
+
+            while (mWriteQueue.isEmpty()) {
+                if (mNextWriteTime != 0) {
+                    mNextWriteTime = 0; // idle.
+                    notify(); // May need to wake up flush().
+                }
+                // Make sure we exit this thread correctly when interrupted before going to
+                // indefinite wait.
+                if (Thread.currentThread().isInterrupted()) {
+                    throw new InterruptedException();
+                }
+                if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
+                wait();
+                // Invariant: mNextWriteTime is either FLUSH_QUEUE or PRE_WRITE_DELAY_MS
+                // from now.
+            }
+            item = mWriteQueue.remove(0);
+
+            long now = SystemClock.uptimeMillis();
+            if (DEBUG) {
+                Slog.d(TAG, "LazyTaskWriter: now=" + now + " mNextWriteTime=" + mNextWriteTime
+                        + " mWriteQueue.size=" + mWriteQueue.size());
+            }
+            while (now < mNextWriteTime) {
+                if (DEBUG) {
+                    Slog.d(TAG, "LazyTaskWriter: waiting " + (mNextWriteTime - now));
+                }
+                wait(mNextWriteTime - now);
+                now = SystemClock.uptimeMillis();
+            }
+
+            // Got something to do.
+        }
+
+        item.process();
+    }
+
+    interface WriteQueueItem {
+        void process();
+    }
+
+    interface Listener {
+        /**
+         * Called before {@link PersisterQueue} tries to process next item.
+         *
+         * Note if the queue is empty, this callback will be called before the indefinite wait. This
+         * will be called once when {@link PersisterQueue} starts the internal thread before the
+         * indefinite wait.
+         *
+         * This callback is called w/o locking the instance of {@link PersisterQueue}.
+         *
+         * @param queueEmpty {@code true} if the queue is empty, which indicates {@link
+         * PersisterQueue} is likely to enter indefinite wait; or {@code false} if there is still
+         * item to process.
+         */
+        void onPreProcessItem(boolean queueEmpty);
+    }
+
+    private class LazyTaskWriterThread extends Thread {
+
+        private LazyTaskWriterThread(String name) {
+            super(name);
+        }
+
+        @Override
+        public void run() {
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+            try {
+                while (true) {
+                    final boolean probablyDone;
+                    synchronized (PersisterQueue.this) {
+                        probablyDone = mWriteQueue.isEmpty();
+                    }
+
+                    for (int i = mListeners.size() - 1; i >= 0; --i) {
+                        mListeners.get(i).onPreProcessItem(probablyDone);
+                    }
+
+                    processNextItem();
+                }
+            } catch (InterruptedException e) {
+                Slog.e(TAG, "Persister thread is exiting. Should never happen in prod, but"
+                        + "it's OK in tests.");
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 3ac7885..805b979b 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -16,28 +16,94 @@
 
 package com.android.server.am;
 
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+import static android.app.ActivityThread.PROC_START_SEQ_IDENT;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO;
+import static android.os.Process.FIRST_ISOLATED_UID;
+import static android.os.Process.LAST_ISOLATED_UID;
+import static android.os.Process.SYSTEM_UID;
+import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
+import static android.os.Process.getFreeMemory;
+import static android.os.Process.getTotalMemory;
+import static android.os.Process.killProcessQuiet;
+import static android.os.Process.startWebView;
+import static android.os.storage.StorageManager.PROP_ISOLATED_STORAGE;
+
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
 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.ActivityManagerService.PERSISTENT_MASK;
+import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT;
+import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG;
+import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER;
+import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
+import static com.android.server.am.ActivityManagerService.TAG_LRU;
+import static com.android.server.am.ActivityManagerService.TAG_PROCESSES;
+import static com.android.server.am.ActivityManagerService.TAG_PSS;
+import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS;
 
+import android.app.ActivityManager;
+import android.app.AppGlobals;
+import android.app.AppProtoEnums;
+import android.app.IApplicationThread;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.StrictMode;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.os.storage.StorageManagerInternal;
+import android.text.TextUtils;
+import android.util.EventLog;
+import android.util.LongSparseArray;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.StatsLog;
+import android.view.Display;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.ProcessMap;
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.os.Zygote;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.MemInfoReader;
+import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
+import com.android.server.Watchdog;
+import com.android.server.pm.dex.DexManager;
+import com.android.server.wm.WindowManagerService;
+
+import dalvik.system.VMRuntime;
+
+import java.io.File;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.nio.ByteBuffer;
-
-import android.app.ActivityManager;
-import android.app.AppProtoEnums;
-import android.os.Build;
-import android.os.SystemClock;
-import com.android.internal.util.MemInfoReader;
-import com.android.server.wm.WindowManagerService;
-
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.os.SystemProperties;
-import android.net.LocalSocketAddress;
-import android.net.LocalSocket;
-import android.util.Slog;
-import android.view.Display;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Activity manager code dealing with processes.
@@ -47,7 +113,7 @@
 
     // The minimum time we allow between crashes, for us to consider this
     // application to be bad and stop and its services and reject broadcasts.
-    static final int MIN_CRASH_INTERVAL = 60*1000;
+    static final int MIN_CRASH_INTERVAL = 60 * 1000;
 
     // OOM adjustments for processes in various states:
 
@@ -129,7 +195,7 @@
     static final int NATIVE_ADJ = -1000;
 
     // Memory pages are 4K.
-    static final int PAGE_SIZE = 4*1024;
+    static final int PAGE_SIZE = 4 * 1024;
 
     // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE
     static final int SCHED_GROUP_BACKGROUND = 0;
@@ -148,7 +214,7 @@
     static final int MIN_CACHED_APPS = 2;
 
     // We allow empty processes to stick around for at most 30 minutes.
-    static final long MAX_EMPTY_TIME = 30*60*1000;
+    static final long MAX_EMPTY_TIME = 30 * 60 * 1000;
 
     // Threshold of number of cached+empty where we consider memory critical.
     static final int TRIM_CRITICAL_THRESHOLD = 3;
@@ -162,9 +228,17 @@
     // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs)
     // LMK_PROCPRIO <pid> <uid> <prio>
     // LMK_PROCREMOVE <pid>
+    // LMK_PROCPURGE
     static final byte LMK_TARGET = 0;
     static final byte LMK_PROCPRIO = 1;
     static final byte LMK_PROCREMOVE = 2;
+    static final byte LMK_PROCPURGE = 3;
+
+    ActivityManagerService mService = null;
+
+    // To kill process groups asynchronously
+    static KillHandler sKillHandler = null;
+    static ServiceThread sKillThread = null;
 
     // These are the various interesting memory levels that we will give to
     // the OOM killer.  Note that the OOM killer only supports 6 slots, so we
@@ -197,6 +271,123 @@
     private static LocalSocket sLmkdSocket;
     private static OutputStream sLmkdOutputStream;
 
+    /**
+     * Temporary to avoid allocations.  Protected by main lock.
+     */
+    @GuardedBy("mService")
+    final StringBuilder mStringBuilder = new StringBuilder(256);
+
+    /**
+     * A global counter for generating sequence numbers.
+     * This value will be used when incrementing sequence numbers in individual uidRecords.
+     *
+     * Having a global counter ensures that seq numbers are monotonically increasing for a
+     * particular uid even when the uidRecord is re-created.
+     */
+    @GuardedBy("mService")
+    @VisibleForTesting
+    long mProcStateSeqCounter = 0;
+
+    /**
+     * A global counter for generating sequence numbers to uniquely identify pending process starts.
+     */
+    @GuardedBy("mService")
+    private long mProcStartSeqCounter = 0;
+
+    /**
+     * Contains {@link ProcessRecord} objects for pending process starts.
+     *
+     * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord}
+     */
+    @GuardedBy("mService")
+    final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>();
+
+    /**
+     * List of running applications, sorted by recent usage.
+     * The first entry in the list is the least recently used.
+     */
+    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
+
+    /**
+     * Where in mLruProcesses that the processes hosting activities start.
+     */
+    int mLruProcessActivityStart = 0;
+
+    /**
+     * Where in mLruProcesses that the processes hosting services start.
+     * This is after (lower index) than mLruProcessesActivityStart.
+     */
+    int mLruProcessServiceStart = 0;
+
+    /**
+     * Current sequence id for process LRU updating.
+     */
+    int mLruSeq = 0;
+
+    /**
+     * The currently running isolated processes.
+     */
+    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>();
+
+    /**
+     * Counter for assigning isolated process uids, to avoid frequently reusing the
+     * same ones.
+     */
+    int mNextIsolatedProcessUid = 0;
+
+    /**
+     * Processes that are being forcibly torn down.
+     */
+    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
+
+    /**
+     * All of the applications we currently have running organized by name.
+     * The keys are strings of the application package name (as
+     * returned by the package manager), and the keys are ApplicationRecord
+     * objects.
+     */
+    final MyProcessMap mProcessNames = new MyProcessMap();
+
+    final class MyProcessMap extends ProcessMap<ProcessRecord> {
+        @Override
+        public ProcessRecord put(String name, int uid, ProcessRecord value) {
+            final ProcessRecord r = super.put(name, uid, value);
+            mService.mAtmInternal.onProcessAdded(r.getWindowProcessController());
+            return r;
+        }
+
+        @Override
+        public ProcessRecord remove(String name, int uid) {
+            final ProcessRecord r = super.remove(name, uid);
+            mService.mAtmInternal.onProcessRemoved(name, uid);
+            return r;
+        }
+    }
+
+    final class KillHandler extends Handler {
+        static final int KILL_PROCESS_GROUP_MSG = 4000;
+
+        public KillHandler(Looper looper) {
+            super(looper, null, true);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case KILL_PROCESS_GROUP_MSG:
+                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
+                    Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
+                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+                    break;
+
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    }
+
+    ////////////////////  END FIELDS  ////////////////////
+
     ProcessList() {
         MemInfoReader minfo = new MemInfoReader();
         minfo.readMemInfo();
@@ -204,6 +395,16 @@
         updateOomLevels(0, 0, false);
     }
 
+    void init(ActivityManagerService service) {
+        mService = service;
+        if (sKillHandler == null) {
+            sKillThread = new ServiceThread(TAG + ":kill",
+                    THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
+            sKillThread.start();
+            sKillHandler = new KillHandler(sKillThread.getLooper());
+        }
+    }
+
     void applyDisplaySize(WindowManagerService wm) {
         if (!mHaveDisplaySize) {
             Point p = new Point();
@@ -219,12 +420,12 @@
     private void updateOomLevels(int displayWidth, int displayHeight, boolean write) {
         // Scale buckets from avail memory: at 300MB we use the lowest values to
         // 700MB or more for the top values.
-        float scaleMem = ((float)(mTotalMemMb-350))/(700-350);
+        float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350);
 
         // Scale buckets from screen size.
-        int minSize = 480*800;  //  384000
-        int maxSize = 1280*800; // 1024000  230400 870400  .264
-        float scaleDisp = ((float)(displayWidth*displayHeight)-minSize)/(maxSize-minSize);
+        int minSize = 480 * 800;  //  384000
+        int maxSize = 1280 * 800; // 1024000  230400 870400  .264
+        float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize);
         if (false) {
             Slog.i("XXXXXX", "scaleMem=" + scaleMem);
             Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth
@@ -244,27 +445,27 @@
 
         final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0;
 
-        for (int i=0; i<mOomAdj.length; i++) {
+        for (int i = 0; i < mOomAdj.length; i++) {
             int low = mOomMinFreeLow[i];
             int high = mOomMinFreeHigh[i];
             if (is64bit) {
                 // Increase the high min-free levels for cached processes for 64-bit
-                if (i == 4) high = (high*3)/2;
-                else if (i == 5) high = (high*7)/4;
+                if (i == 4) high = (high * 3) / 2;
+                else if (i == 5) high = (high * 7) / 4;
             }
-            mOomMinFree[i] = (int)(low + ((high-low)*scale));
+            mOomMinFree[i] = (int)(low + ((high - low) * scale));
         }
 
         if (minfree_abs >= 0) {
-            for (int i=0; i<mOomAdj.length; i++) {
+            for (int i = 0; i < mOomAdj.length; i++) {
                 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i]
                         / mOomMinFree[mOomAdj.length - 1]);
             }
         }
 
         if (minfree_adj != 0) {
-            for (int i=0; i<mOomAdj.length; i++) {
-                mOomMinFree[i] += (int)((float)minfree_adj * mOomMinFree[i]
+            for (int i = 0; i < mOomAdj.length; i++) {
+                mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i]
                         / mOomMinFree[mOomAdj.length - 1]);
                 if (mOomMinFree[i] < 0) {
                     mOomMinFree[i] = 0;
@@ -275,13 +476,15 @@
         // The maximum size we will restore a process from cached to background, when under
         // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead
         // before killing background processes.
-        mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024) / 3;
+        mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3;
 
         // Ask the kernel to try to keep enough memory free to allocate 3 full
         // screen 32bpp buffers without entering direct reclaim.
         int reserve = displayWidth * displayHeight * 4 * 3 / 1024;
-        int reserve_adj = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAdjust);
-        int reserve_abs = Resources.getSystem().getInteger(com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
+        int reserve_adj = Resources.getSystem().getInteger(
+                com.android.internal.R.integer.config_extraFreeKbytesAdjust);
+        int reserve_abs = Resources.getSystem().getInteger(
+                com.android.internal.R.integer.config_extraFreeKbytesAbsolute);
 
         if (reserve_abs >= 0) {
             reserve = reserve_abs;
@@ -295,10 +498,10 @@
         }
 
         if (write) {
-            ByteBuffer buf = ByteBuffer.allocate(4 * (2*mOomAdj.length + 1));
+            ByteBuffer 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);
+            for (int i = 0; i < mOomAdj.length; i++) {
+                buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE);
                 buf.putInt(mOomAdj[i]);
             }
 
@@ -318,7 +521,7 @@
             if (space == null) return prefix;
             return prefix + "  ";
         }
-        return prefix + "+" + Integer.toString(val-base);
+        return prefix + "+" + Integer.toString(val - base);
     }
 
     public static String makeOomAdjString(int setAdj) {
@@ -475,7 +678,7 @@
     }
 
     public static void appendRamKb(StringBuilder sb, long ramKb) {
-        for (int j=0, fact=10; j<6; j++, fact*=10) {
+        for (int j = 0, fact = 10; j < 6; j++, fact *= 10) {
             if (ramKb < fact) {
                 sb.append(' ');
             }
@@ -735,12 +938,12 @@
     }
 
     long getMemLevel(int adjustment) {
-        for (int i=0; i<mOomAdj.length; i++) {
+        for (int i = 0; i < mOomAdj.length; i++) {
             if (adjustment <= mOomAdj[i]) {
                 return mOomMinFree[i] * 1024;
             }
         }
-        return mOomMinFree[mOomAdj.length-1] * 1024;
+        return mOomMinFree[mOomAdj.length - 1] * 1024;
     }
 
     /**
@@ -813,31 +1016,1563 @@
         return true;
     }
 
+    // Never call directly, use writeLmkd() instead
+    private static boolean writeLmkdCommand(ByteBuffer buf) {
+        try {
+            sLmkdOutputStream.write(buf.array(), 0, buf.position());
+        } catch (IOException ex) {
+            Slog.w(TAG, "Error writing to lowmemorykiller socket");
+
+            try {
+                sLmkdSocket.close();
+            } catch (IOException ex2) {
+            }
+
+            sLmkdSocket = null;
+            return false;
+        }
+        return true;
+    }
+
     private static void writeLmkd(ByteBuffer buf) {
 
         for (int i = 0; i < 3; i++) {
             if (sLmkdSocket == null) {
-                    if (openLmkdSocket() == false) {
-                        try {
-                            Thread.sleep(1000);
-                        } catch (InterruptedException ie) {
-                        }
-                        continue;
+                if (openLmkdSocket() == false) {
+                    try {
+                        Thread.sleep(1000);
+                    } catch (InterruptedException ie) {
                     }
-            }
-
-            try {
-                sLmkdOutputStream.write(buf.array(), 0, buf.position());
-                return;
-            } catch (IOException ex) {
-                Slog.w(TAG, "Error writing to lowmemorykiller socket");
-
-                try {
-                    sLmkdSocket.close();
-                } catch (IOException ex2) {
+                    continue;
                 }
 
-                sLmkdSocket = null;
+                // Purge any previously registered pids
+                ByteBuffer purge_buf = ByteBuffer.allocate(4);
+                purge_buf.putInt(LMK_PROCPURGE);
+                if (writeLmkdCommand(purge_buf) == false) {
+                    // Write failed, skip the rest and retry
+                    continue;
+                }
+            }
+            if (writeLmkdCommand(buf)) {
+                return;
+            }
+        }
+    }
+
+    static void killProcessGroup(int uid, int pid) {
+        /* static; one-time init here */
+        if (sKillHandler != null) {
+            sKillHandler.sendMessage(
+                    sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
+        } else {
+            Slog.w(TAG, "Asked to kill process group before system bringup!");
+            Process.killProcessGroup(uid, pid);
+        }
+    }
+
+    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean
+            keepIfLarge) {
+        if (uid == SYSTEM_UID) {
+            // The system gets to run in any process.  If there are multiple
+            // processes with the same uid, just pick the first (this
+            // should never happen).
+            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
+            if (procs == null) return null;
+            final int procCount = procs.size();
+            for (int i = 0; i < procCount; i++) {
+                final int procUid = procs.keyAt(i);
+                if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
+                    // Don't use an app process or different user process for system component.
+                    continue;
+                }
+                return procs.valueAt(i);
+            }
+        }
+        ProcessRecord proc = mProcessNames.get(processName, uid);
+        if (false && proc != null && !keepIfLarge
+                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
+                && proc.lastCachedPss >= 4000) {
+            // Turn this condition on to cause killing to happen regularly, for testing.
+            if (proc.baseProcessTracker != null) {
+                proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss);
+                for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
+                    ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
+                    StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
+                            proc.info.uid,
+                            holder.state.getName(),
+                            holder.state.getPackage(),
+                            proc.lastCachedPss, holder.appVersion);
+                }
+            }
+            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
+        } else if (proc != null && !keepIfLarge
+                && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
+                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
+            if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc
+                    .lastCachedPss);
+            if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) {
+                if (proc.baseProcessTracker != null) {
+                    proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList,
+                            proc.lastCachedPss);
+                    for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) {
+                        ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg);
+                        StatsLog.write(StatsLog.CACHED_KILL_REPORTED,
+                                proc.info.uid,
+                                holder.state.getName(),
+                                holder.state.getPackage(),
+                                proc.lastCachedPss, holder.appVersion);
+                    }
+                }
+                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
+            }
+        }
+        return proc;
+    }
+
+    void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
+        final long homeAppMem = getMemLevel(HOME_APP_ADJ);
+        final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ);
+        outInfo.availMem = getFreeMemory();
+        outInfo.totalMem = getTotalMemory();
+        outInfo.threshold = homeAppMem;
+        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
+        outInfo.hiddenAppThreshold = cachedAppMem;
+        outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ);
+        outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ);
+        outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ);
+    }
+
+    ProcessRecord findAppProcessLocked(IBinder app, String reason) {
+        final int NP = mProcessNames.getMap().size();
+        for (int ip = 0; ip < NP; ip++) {
+            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
+            final int NA = apps.size();
+            for (int ia = 0; ia < NA; ia++) {
+                ProcessRecord p = apps.valueAt(ia);
+                if (p.thread != null && p.thread.asBinder() == app) {
+                    return p;
+                }
+            }
+        }
+
+        Slog.w(TAG, "Can't find mystery application for " + reason
+                + " from pid=" + Binder.getCallingPid()
+                + " uid=" + Binder.getCallingUid() + ": " + app);
+        return null;
+    }
+
+    private void checkSlow(long startTime, String where) {
+        long now = SystemClock.uptimeMillis();
+        if ((now - startTime) > 50) {
+            // If we are taking more than 50ms, log about it.
+            Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where);
+        }
+    }
+
+    /**
+     * @return {@code true} if process start is successful, false otherwise.
+     * @param app
+     * @param hostingType
+     * @param hostingNameStr
+     * @param disableHiddenApiChecks
+     * @param abiOverride
+     */
+    @GuardedBy("mService")
+    boolean startProcessLocked(ProcessRecord app, String hostingType,
+            String hostingNameStr, boolean disableHiddenApiChecks, boolean mountExtStorageFull,
+            String abiOverride) {
+        if (app.pendingStart) {
+            return true;
+        }
+        long startTime = SystemClock.elapsedRealtime();
+        if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) {
+            checkSlow(startTime, "startProcess: removing from pids map");
+            synchronized (mService.mPidsSelfLocked) {
+                mService.mPidsSelfLocked.remove(app.pid);
+                mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
+            }
+            checkSlow(startTime, "startProcess: done removing from pids map");
+            app.setPid(0);
+        }
+
+        if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v(
+                TAG_PROCESSES,
+                "startProcessLocked removing on hold: " + app);
+        mService.mProcessesOnHold.remove(app);
+
+        checkSlow(startTime, "startProcess: starting to update cpu stats");
+        mService.updateCpuStats();
+        checkSlow(startTime, "startProcess: done updating cpu stats");
+
+        try {
+            try {
+                final int userId = UserHandle.getUserId(app.uid);
+                AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
+            } catch (RemoteException e) {
+                throw e.rethrowAsRuntimeException();
+            }
+
+            int uid = app.uid;
+            int[] gids = null;
+            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
+            if (!app.isolated) {
+                int[] permGids = null;
+                try {
+                    checkSlow(startTime, "startProcess: getting gids from package manager");
+                    final IPackageManager pm = AppGlobals.getPackageManager();
+                    permGids = pm.getPackageGids(app.info.packageName,
+                            MATCH_DIRECT_BOOT_AUTO, app.userId);
+                    if (SystemProperties.getBoolean(PROP_ISOLATED_STORAGE, false)
+                            && mountExtStorageFull) {
+                        mountExternal = Zygote.MOUNT_EXTERNAL_FULL;
+                    } else {
+                        StorageManagerInternal storageManagerInternal = LocalServices.getService(
+                                StorageManagerInternal.class);
+                        mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
+                                app.info.packageName);
+                    }
+                } catch (RemoteException e) {
+                    throw e.rethrowAsRuntimeException();
+                }
+
+                /*
+                 * Add shared application and profile GIDs so applications can share some
+                 * resources like shared libraries and access user-wide resources
+                 */
+                if (ArrayUtils.isEmpty(permGids)) {
+                    gids = new int[3];
+                } else {
+                    gids = new int[permGids.length + 3];
+                    System.arraycopy(permGids, 0, gids, 3, permGids.length);
+                }
+                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
+                gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
+                gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
+
+                // Replace any invalid GIDs
+                if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
+                if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
+            }
+            checkSlow(startTime, "startProcess: building args");
+            if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) {
+                uid = 0;
+            }
+            int runtimeFlags = 0;
+            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+                runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
+                runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
+                // Also turn on CheckJNI for debuggable apps. It's quite
+                // awkward to turn on otherwise.
+                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
+            }
+            // Run the app in safe mode if its manifest requests so or the
+            // system is booted in safe mode.
+            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
+                    mService.mSafeMode == true) {
+                runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
+            }
+            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
+                runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
+            }
+            String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
+            if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) {
+                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
+            }
+            String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo");
+            if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) {
+                runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO;
+            }
+            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
+                runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
+            }
+            if ("1".equals(SystemProperties.get("debug.assert"))) {
+                runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
+            }
+            if (mService.mNativeDebuggingApp != null
+                    && mService.mNativeDebuggingApp.equals(app.processName)) {
+                // Enable all debug flags required by the native debugger.
+                runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
+                runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
+                runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
+                mService.mNativeDebuggingApp = null;
+            }
+
+            if (app.info.isPrivilegedApp() &&
+                    DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet())) {
+                runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
+            }
+
+            if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) {
+                app.info.maybeUpdateHiddenApiEnforcementPolicy(
+                        mService.mHiddenApiBlacklist.getPolicyForPrePApps(),
+                        mService.mHiddenApiBlacklist.getPolicyForPApps());
+                @ApplicationInfo.HiddenApiEnforcementPolicy int policy =
+                        app.info.getHiddenApiEnforcementPolicy();
+                int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
+                if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) {
+                    throw new IllegalStateException("Invalid API policy: " + policy);
+                }
+                runtimeFlags |= policyBits;
+            }
+
+            String invokeWith = null;
+            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
+                // Debuggable apps may include a wrapper script with their library directory.
+                String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
+                StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
+                try {
+                    if (new File(wrapperFileName).exists()) {
+                        invokeWith = "/system/bin/logwrapper " + wrapperFileName;
+                    }
+                } finally {
+                    StrictMode.setThreadPolicy(oldPolicy);
+                }
+            }
+
+            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
+            if (requiredAbi == null) {
+                requiredAbi = Build.SUPPORTED_ABIS[0];
+            }
+
+            String instructionSet = null;
+            if (app.info.primaryCpuAbi != null) {
+                instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
+            }
+
+            app.gids = gids;
+            app.setRequiredAbi(requiredAbi);
+            app.instructionSet = instructionSet;
+
+            // the per-user SELinux context must be set
+            if (TextUtils.isEmpty(app.info.seInfoUser)) {
+                Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined",
+                        new IllegalStateException("SELinux tag not defined for "
+                                + app.info.packageName + " (uid " + app.uid + ")"));
+            }
+            final String seInfo = app.info.seInfo
+                    + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
+            // Start the process.  It will either succeed and return a result containing
+            // the PID of the new process, or else throw a RuntimeException.
+            final String entryPoint = "android.app.ActivityThread";
+
+            return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
+                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
+                    startTime);
+        } catch (RuntimeException e) {
+            Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e);
+
+            // Something went very wrong while trying to start this process; one
+            // common case is when the package is frozen due to an active
+            // upgrade. To recover, clean up any active bookkeeping related to
+            // starting this process. (We already invoked this method once when
+            // the package was initially frozen through KILL_APPLICATION_MSG, so
+            // it doesn't hurt to use it again.)
+            mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
+                    false, false, true, false, false, app.userId, "start failure");
+            return false;
+        }
+    }
+
+    @GuardedBy("mService")
+    boolean startProcessLocked(String hostingType, String hostingNameStr,
+            String entryPoint,
+            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
+            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
+            long startTime) {
+        app.pendingStart = true;
+        app.killedByAm = false;
+        app.removed = false;
+        app.killed = false;
+        final long startSeq = app.startSeq = ++mProcStartSeqCounter;
+        app.setStartParams(uid, hostingType, hostingNameStr, seInfo, startTime);
+        if (mService.mConstants.FLAG_PROCESS_START_ASYNC) {
+            if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES,
+                    "Posting procStart msg for " + app.toShortString());
+            mService.mProcStartHandler.post(() -> {
+                try {
+                    synchronized (mService) {
+                        final String reason = isProcStartValidLocked(app, startSeq);
+                        if (reason != null) {
+                            Slog.w(TAG_PROCESSES, app + " not valid anymore,"
+                                    + " don't start process, " + reason);
+                            app.pendingStart = false;
+                            return;
+                        }
+                        app.setUsingWrapper(invokeWith != null
+                                || SystemProperties.get("wrap." + app.processName) != null);
+                        mPendingStarts.put(startSeq, app);
+                    }
+                    final Process.ProcessStartResult startResult = startProcess(app.hostingType,
+                            entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal,
+                            app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime);
+                    synchronized (mService) {
+                        handleProcessStartedLocked(app, startResult, startSeq);
+                    }
+                } catch (RuntimeException e) {
+                    synchronized (mService) {
+                        Slog.e(ActivityManagerService.TAG, "Failure starting process "
+                                + app.processName, e);
+                        mPendingStarts.remove(startSeq);
+                        app.pendingStart = false;
+                        mService.forceStopPackageLocked(app.info.packageName,
+                                UserHandle.getAppId(app.uid),
+                                false, false, true, false, false, app.userId, "start failure");
+                    }
+                }
+            });
+            return true;
+        } else {
+            try {
+                final Process.ProcessStartResult startResult = startProcess(hostingType,
+                        entryPoint, app,
+                        uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet,
+                        invokeWith, startTime);
+                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
+                        startSeq, false);
+            } catch (RuntimeException e) {
+                Slog.e(ActivityManagerService.TAG, "Failure starting process "
+                        + app.processName, e);
+                app.pendingStart = false;
+                mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid),
+                        false, false, true, false, false, app.userId, "start failure");
+            }
+            return app.pid > 0;
+        }
+    }
+
+    private Process.ProcessStartResult startProcess(String hostingType, String entryPoint,
+            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
+            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
+            long startTime) {
+        try {
+            final String[] packageNames = mService.mContext.getPackageManager()
+                    .getPackagesForUid(uid);
+            final String[] visibleVolIds = LocalServices.getService(StorageManagerInternal.class)
+                    .getVisibleVolumesForUser(UserHandle.getUserId(uid));
+            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
+                    app.processName);
+            checkSlow(startTime, "startProcess: asking zygote to start proc");
+            final Process.ProcessStartResult startResult;
+            if (hostingType.equals("webview_service")) {
+                startResult = startWebView(entryPoint,
+                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
+                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
+                        app.info.dataDir, null, app.info.packageName,
+                        packageNames, visibleVolIds,
+                        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,
+                        packageNames, visibleVolIds,
+                        new String[] {PROC_START_SEQ_IDENT + app.startSeq});
+            }
+            checkSlow(startTime, "startProcess: returned from zygote!");
+            return startResult;
+        } finally {
+            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+        }
+    }
+
+    @GuardedBy("mService")
+    final void startProcessLocked(ProcessRecord app,
+            String hostingType, String hostingNameStr) {
+        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */);
+    }
+
+    @GuardedBy("mService")
+    final boolean startProcessLocked(ProcessRecord app,
+            String hostingType, String hostingNameStr, String abiOverride) {
+        return startProcessLocked(app, hostingType, hostingNameStr,
+                false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride);
+    }
+
+    @GuardedBy("mService")
+    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
+            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
+            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
+            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
+        long startTime = SystemClock.elapsedRealtime();
+        ProcessRecord app;
+        if (!isolated) {
+            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
+            checkSlow(startTime, "startProcess: after getProcessRecord");
+
+            if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
+                // If we are in the background, then check to see if this process
+                // is bad.  If so, we will just silently fail.
+                if (mService.mAppErrors.isBadProcessLocked(info)) {
+                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
+                            + "/" + info.processName);
+                    return null;
+                }
+            } else {
+                // When the user is explicitly starting a process, then clear its
+                // crash count so that we won't make it bad until they see at
+                // least one crash dialog again, and make the process good again
+                // if it had been bad.
+                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
+                        + "/" + info.processName);
+                mService.mAppErrors.resetProcessCrashTimeLocked(info);
+                if (mService.mAppErrors.isBadProcessLocked(info)) {
+                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
+                            UserHandle.getUserId(info.uid), info.uid,
+                            info.processName);
+                    mService.mAppErrors.clearBadProcessLocked(info);
+                    if (app != null) {
+                        app.bad = false;
+                    }
+                }
+            }
+        } else {
+            // If this is an isolated process, it can't re-use an existing process.
+            app = null;
+        }
+
+        // We don't have to do anything more if:
+        // (1) There is an existing application record; and
+        // (2) The caller doesn't think it is dead, OR there is no thread
+        //     object attached to it so we know it couldn't have crashed; and
+        // (3) There is a pid assigned to it, so it is either starting or
+        //     already running.
+        if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
+                + " app=" + app + " knownToBeDead=" + knownToBeDead
+                + " thread=" + (app != null ? app.thread : null)
+                + " pid=" + (app != null ? app.pid : -1));
+        if (app != null && app.pid > 0) {
+            if ((!knownToBeDead && !app.killed) || app.thread == null) {
+                // We already have the app running, or are waiting for it to
+                // come up (we have a pid but not yet its thread), so keep it.
+                if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
+                // If this is a new package in the process, add the package to the list
+                app.addPackage(info.packageName, info.versionCode, mService.mProcessStats);
+                checkSlow(startTime, "startProcess: done, added package to proc");
+                return app;
+            }
+
+            // An application record is attached to a previous process,
+            // clean it up now.
+            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app);
+            checkSlow(startTime, "startProcess: bad proc running, killing");
+            ProcessList.killProcessGroup(app.uid, app.pid);
+            mService.handleAppDiedLocked(app, true, true);
+            checkSlow(startTime, "startProcess: done killing old proc");
+        }
+
+        String hostingNameStr = hostingName != null
+                ? hostingName.flattenToShortString() : null;
+
+        if (app == null) {
+            checkSlow(startTime, "startProcess: creating new process record");
+            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
+            if (app == null) {
+                Slog.w(TAG, "Failed making new process record for "
+                        + processName + "/" + info.uid + " isolated=" + isolated);
+                return null;
+            }
+            app.crashHandler = crashHandler;
+            app.isolatedEntryPoint = entryPoint;
+            app.isolatedEntryPointArgs = entryPointArgs;
+            checkSlow(startTime, "startProcess: done creating new process record");
+        } else {
+            // If this is a new package in the process, add the package to the list
+            app.addPackage(info.packageName, info.versionCode, mService.mProcessStats);
+            checkSlow(startTime, "startProcess: added package to existing proc");
+        }
+
+        // If the system is not ready yet, then hold off on starting this
+        // process until it is.
+        if (!mService.mProcessesReady
+                && !mService.isAllowedWhileBooting(info)
+                && !allowWhileBooting) {
+            if (!mService.mProcessesOnHold.contains(app)) {
+                mService.mProcessesOnHold.add(app);
+            }
+            if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
+                    "System not ready, putting on hold: " + app);
+            checkSlow(startTime, "startProcess: returning with proc on hold");
+            return app;
+        }
+
+        checkSlow(startTime, "startProcess: stepping in to startProcess");
+        final boolean success = startProcessLocked(app, hostingType, hostingNameStr,
+                abiOverride);
+        checkSlow(startTime, "startProcess: done starting proc!");
+        return success ? app : null;
+    }
+
+    @GuardedBy("mService")
+    private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) {
+        StringBuilder sb = null;
+        if (app.killedByAm) {
+            if (sb == null) sb = new StringBuilder();
+            sb.append("killedByAm=true;");
+        }
+        if (mProcessNames.get(app.processName, app.uid) != app) {
+            if (sb == null) sb = new StringBuilder();
+            sb.append("No entry in mProcessNames;");
+        }
+        if (!app.pendingStart) {
+            if (sb == null) sb = new StringBuilder();
+            sb.append("pendingStart=false;");
+        }
+        if (app.startSeq > expectedStartSeq) {
+            if (sb == null) sb = new StringBuilder();
+            sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";");
+        }
+        return sb == null ? null : sb.toString();
+    }
+
+    @GuardedBy("mService")
+    private boolean handleProcessStartedLocked(ProcessRecord pending,
+            Process.ProcessStartResult startResult, long expectedStartSeq) {
+        // Indicates that this process start has been taken care of.
+        if (mPendingStarts.get(expectedStartSeq) == null) {
+            if (pending.pid == startResult.pid) {
+                pending.setUsingWrapper(startResult.usingWrapper);
+                // TODO: Update already existing clients of usingWrapper
+            }
+            return false;
+        }
+        return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper,
+                expectedStartSeq, false);
+    }
+
+    @GuardedBy("mService")
+    boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper,
+            long expectedStartSeq, boolean procAttached) {
+        mPendingStarts.remove(expectedStartSeq);
+        final String reason = isProcStartValidLocked(app, expectedStartSeq);
+        if (reason != null) {
+            Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" +
+                    pid
+                    + ", " + reason);
+            app.pendingStart = false;
+            killProcessQuiet(pid);
+            Process.killProcessGroup(app.uid, app.pid);
+            return false;
+        }
+        mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
+        checkSlow(app.startTime, "startProcess: done updating battery stats");
+
+        EventLog.writeEvent(EventLogTags.AM_PROC_START,
+                UserHandle.getUserId(app.startUid), pid, app.startUid,
+                app.processName, app.hostingType,
+                app.hostingNameStr != null ? app.hostingNameStr : "");
+
+        try {
+            AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
+                    app.seInfo, app.info.sourceDir, pid);
+        } catch (RemoteException ex) {
+            // Ignore
+        }
+
+        if (app.isPersistent()) {
+            Watchdog.getInstance().processStarted(app.processName, pid);
+        }
+
+        checkSlow(app.startTime, "startProcess: building log message");
+        StringBuilder buf = mStringBuilder;
+        buf.setLength(0);
+        buf.append("Start proc ");
+        buf.append(pid);
+        buf.append(':');
+        buf.append(app.processName);
+        buf.append('/');
+        UserHandle.formatUid(buf, app.startUid);
+        if (app.isolatedEntryPoint != null) {
+            buf.append(" [");
+            buf.append(app.isolatedEntryPoint);
+            buf.append("]");
+        }
+        buf.append(" for ");
+        buf.append(app.hostingType);
+        if (app.hostingNameStr != null) {
+            buf.append(" ");
+            buf.append(app.hostingNameStr);
+        }
+        mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid);
+        app.setPid(pid);
+        app.setUsingWrapper(usingWrapper);
+        app.pendingStart = false;
+        checkSlow(app.startTime, "startProcess: starting to update pids map");
+        ProcessRecord oldApp;
+        synchronized (mService.mPidsSelfLocked) {
+            oldApp = mService.mPidsSelfLocked.get(pid);
+        }
+        // If there is already an app occupying that pid that hasn't been cleaned up
+        if (oldApp != null && !app.isolated) {
+            // Clean up anything relating to this pid first
+            Slog.w(TAG, "Reusing pid " + pid
+                    + " while app is still mapped to it");
+            mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1,
+                    true /*replacingPid*/);
+        }
+        synchronized (mService.mPidsSelfLocked) {
+            mService.mPidsSelfLocked.put(pid, app);
+            if (!procAttached) {
+                Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
+                msg.obj = app;
+                mService.mHandler.sendMessageDelayed(msg, usingWrapper
+                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
+            }
+        }
+        checkSlow(app.startTime, "startProcess: done updating pids map");
+        return true;
+    }
+
+    final void removeLruProcessLocked(ProcessRecord app) {
+        int lrui = mLruProcesses.lastIndexOf(app);
+        if (lrui >= 0) {
+            if (!app.killed) {
+                if (app.isPersistent()) {
+                    Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app);
+                } else {
+                    Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
+                    if (app.pid > 0) {
+                        killProcessQuiet(app.pid);
+                        ProcessList.killProcessGroup(app.uid, app.pid);
+                    } else {
+                        app.pendingStart = false;
+                    }
+                }
+            }
+            if (lrui <= mLruProcessActivityStart) {
+                mLruProcessActivityStart--;
+            }
+            if (lrui <= mLruProcessServiceStart) {
+                mLruProcessServiceStart--;
+            }
+            mLruProcesses.remove(lrui);
+        }
+    }
+
+    void killAllBackgroundProcessesLocked() {
+        final ArrayList<ProcessRecord> procs = new ArrayList<>();
+        final int NP = mProcessNames.getMap().size();
+        for (int ip = 0; ip < NP; ip++) {
+            final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
+            final int NA = apps.size();
+            for (int ia = 0; ia < NA; ia++) {
+                final ProcessRecord app = apps.valueAt(ia);
+                if (app.isPersistent()) {
+                    // We don't kill persistent processes.
+                    continue;
+                }
+                if (app.removed) {
+                    procs.add(app);
+                } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
+                    app.removed = true;
+                    procs.add(app);
+                }
+            }
+        }
+
+        final int N = procs.size();
+        for (int i = 0; i < N; i++) {
+            removeProcessLocked(procs.get(i), false, true, "kill all background");
+        }
+    }
+
+    @GuardedBy("mService")
+    final boolean killPackageProcessesLocked(String packageName, int appId,
+            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
+            boolean doit, boolean evenPersistent, String reason) {
+        ArrayList<ProcessRecord> procs = new ArrayList<>();
+
+        // Remove all processes this package may have touched: all with the
+        // same UID (except for the system or root user), and all whose name
+        // matches the package name.
+        final int NP = mProcessNames.getMap().size();
+        for (int ip = 0; ip < NP; ip++) {
+            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
+            final int NA = apps.size();
+            for (int ia = 0; ia < NA; ia++) {
+                ProcessRecord app = apps.valueAt(ia);
+                if (app.isPersistent() && !evenPersistent) {
+                    // we don't kill persistent processes
+                    continue;
+                }
+                if (app.removed) {
+                    if (doit) {
+                        procs.add(app);
+                    }
+                    continue;
+                }
+
+                // Skip process if it doesn't meet our oom adj requirement.
+                if (app.setAdj < minOomAdj) {
+                    continue;
+                }
+
+                // If no package is specified, we call all processes under the
+                // give user id.
+                if (packageName == null) {
+                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
+                        continue;
+                    }
+                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
+                        continue;
+                    }
+                    // Package has been specified, we want to hit all processes
+                    // that match it.  We need to qualify this by the processes
+                    // that are running under the specified app and user ID.
+                } else {
+                    final boolean isDep = app.pkgDeps != null
+                            && app.pkgDeps.contains(packageName);
+                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
+                        continue;
+                    }
+                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
+                        continue;
+                    }
+                    if (!app.pkgList.containsKey(packageName) && !isDep) {
+                        continue;
+                    }
+                }
+
+                // Process has passed all conditions, kill it!
+                if (!doit) {
+                    return true;
+                }
+                app.removed = true;
+                procs.add(app);
+            }
+        }
+
+        int N = procs.size();
+        for (int i=0; i<N; i++) {
+            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
+        }
+        mService.updateOomAdjLocked();
+        return N > 0;
+    }
+    @GuardedBy("mService")
+    boolean removeProcessLocked(ProcessRecord app,
+            boolean callerWillRestart, boolean allowRestart, String reason) {
+        final String name = app.processName;
+        final int uid = app.uid;
+        if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
+                "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
+
+        ProcessRecord old = mProcessNames.get(name, uid);
+        if (old != app) {
+            // This process is no longer active, so nothing to do.
+            Slog.w(TAG, "Ignoring remove of inactive process: " + app);
+            return false;
+        }
+        removeProcessNameLocked(name, uid);
+        mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController());
+
+        boolean needRestart = false;
+        if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app
+                .pendingStart)) {
+            int pid = app.pid;
+            if (pid > 0) {
+                synchronized (mService.mPidsSelfLocked) {
+                    mService.mPidsSelfLocked.remove(pid);
+                    mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
+                }
+                mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
+                if (app.isolated) {
+                    mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+                    mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
+                }
+            }
+            boolean willRestart = false;
+            if (app.isPersistent() && !app.isolated) {
+                if (!callerWillRestart) {
+                    willRestart = true;
+                } else {
+                    needRestart = true;
+                }
+            }
+            app.kill(reason, true);
+            mService.handleAppDiedLocked(app, willRestart, allowRestart);
+            if (willRestart) {
+                removeLruProcessLocked(app);
+                mService.addAppLocked(app.info, null, false, null /* ABI override */);
+            }
+        } else {
+            mRemovedProcesses.add(app);
+        }
+
+        return needRestart;
+    }
+
+    @GuardedBy("mService")
+    final void addProcessNameLocked(ProcessRecord proc) {
+        // We shouldn't already have a process under this name, but just in case we
+        // need to clean up whatever may be there now.
+        ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
+        if (old == proc && proc.isPersistent()) {
+            // We are re-adding a persistent process.  Whatevs!  Just leave it there.
+            Slog.w(TAG, "Re-adding persistent process " + proc);
+        } else if (old != null) {
+            Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
+        }
+        UidRecord uidRec = mService.mActiveUids.get(proc.uid);
+        if (uidRec == null) {
+            uidRec = new UidRecord(proc.uid, mService.mAtmInternal);
+            // This is the first appearance of the uid, report it now!
+            if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+                    "Creating new process uid: " + uidRec);
+            if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist,
+                    UserHandle.getAppId(proc.uid)) >= 0
+                    || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
+                uidRec.setWhitelist = uidRec.curWhitelist = true;
+            }
+            uidRec.updateHasInternetPermission();
+            mService.mActiveUids.put(proc.uid, uidRec);
+            EventLogTags.writeAmUidRunning(uidRec.uid);
+            mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
+        }
+        proc.uidRecord = uidRec;
+
+        // Reset render thread tid if it was already set, so new process can set it again.
+        proc.renderThreadTid = 0;
+        uidRec.numProcs++;
+        mProcessNames.put(proc.processName, proc.uid, proc);
+        if (proc.isolated) {
+            mIsolatedProcesses.put(proc.uid, proc);
+        }
+    }
+
+    @GuardedBy("mService")
+    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
+            boolean isolated, int isolatedUid) {
+        String proc = customProcess != null ? customProcess : info.processName;
+        final int userId = UserHandle.getUserId(info.uid);
+        int uid = info.uid;
+        if (isolated) {
+            if (isolatedUid == 0) {
+                int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
+                while (true) {
+                    if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
+                            || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
+                        mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
+                    }
+                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
+                    mNextIsolatedProcessUid++;
+                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
+                        // No process for this uid, use it.
+                        break;
+                    }
+                    stepsLeft--;
+                    if (stepsLeft <= 0) {
+                        return null;
+                    }
+                }
+            } else {
+                // Special case for startIsolatedProcess (internal only), where
+                // the uid of the isolated process is specified by the caller.
+                uid = isolatedUid;
+            }
+            mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
+
+            // Register the isolated UID with this application so BatteryStats knows to
+            // attribute resource usage to the application.
+            //
+            // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
+            // about the process state of the isolated UID *before* it is registered with the
+            // owning application.
+            mService.mBatteryStatsService.addIsolatedUid(uid, info.uid);
+            StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid,
+                    StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED);
+        }
+        final ProcessRecord r = new ProcessRecord(mService, info, proc, uid,
+                mService.getGlobalConfiguration());
+
+        if (!mService.mBooted && !mService.mBooting
+                && userId == UserHandle.USER_SYSTEM
+                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
+            // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc.
+            r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
+            r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
+            r.setPersistent(true);
+            r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
+        }
+        if (isolated && isolatedUid != 0) {
+            // Special case for startIsolatedProcess (internal only) - assume the process
+            // is required by the system server to prevent it being killed.
+            r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ;
+        }
+        addProcessNameLocked(r);
+        return r;
+    }
+
+    @GuardedBy("mService")
+    final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
+        return removeProcessNameLocked(name, uid, null);
+    }
+
+    @GuardedBy("mService")
+    final ProcessRecord removeProcessNameLocked(final String name, final int uid,
+            final ProcessRecord expecting) {
+        ProcessRecord old = mProcessNames.get(name, uid);
+        // Only actually remove when the currently recorded value matches the
+        // record that we expected; if it doesn't match then we raced with a
+        // newly created process and we don't want to destroy the new one.
+        if ((expecting == null) || (old == expecting)) {
+            mProcessNames.remove(name, uid);
+        }
+        if (old != null && old.uidRecord != null) {
+            old.uidRecord.numProcs--;
+            if (old.uidRecord.numProcs == 0) {
+                // No more processes using this uid, tell clients it is gone.
+                if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
+                        "No more processes in " + old.uidRecord);
+                mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
+                EventLogTags.writeAmUidStopped(uid);
+                mService.mActiveUids.remove(uid);
+                mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
+            }
+            old.uidRecord = null;
+        }
+        mIsolatedProcesses.remove(uid);
+        return old;
+    }
+
+    /** Call setCoreSettings on all LRU processes, with the new settings. */
+    @GuardedBy("mService")
+    void updateCoreSettingsLocked(Bundle settings) {
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            ProcessRecord processRecord = mLruProcesses.get(i);
+            try {
+                if (processRecord.thread != null) {
+                    processRecord.thread.setCoreSettings(settings);
+                }
+            } catch (RemoteException re) {
+                /* ignore */
+            }
+        }
+    }
+
+    /**
+     * Kill all background processes except for ones with targetSdk lower than minTargetSdk and
+     * procstate lower than maxProcState.
+     * @param minTargetSdk
+     * @param maxProcState
+     */
+    @GuardedBy("mService")
+    void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) {
+        final ArrayList<ProcessRecord> procs = new ArrayList<>();
+        final int NP = mProcessNames.getMap().size();
+        for (int ip = 0; ip < NP; ip++) {
+            final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
+            final int NA = apps.size();
+            for (int ia = 0; ia < NA; ia++) {
+                final ProcessRecord app = apps.valueAt(ia);
+                if (app.removed) {
+                    procs.add(app);
+                } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
+                        && (maxProcState < 0 || app.setProcState > maxProcState)) {
+                    app.removed = true;
+                    procs.add(app);
+                }
+            }
+        }
+
+        final int N = procs.size();
+        for (int i = 0; i < N; i++) {
+            removeProcessLocked(procs.get(i), false, true, "kill all background except");
+        }
+    }
+
+    /**
+     * Call updateTimePrefs on all LRU processes
+     * @param timePref The time pref to pass to each process
+     */
+    @GuardedBy("mService")
+    void updateAllTimePrefsLocked(int timePref) {
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            ProcessRecord r = mLruProcesses.get(i);
+            if (r.thread != null) {
+                try {
+                    r.thread.updateTimePrefs(timePref);
+                } catch (RemoteException ex) {
+                    Slog.w(TAG, "Failed to update preferences for: "
+                            + r.info.processName);
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mService")
+    void setAllHttpProxyLocked(String host, String port, String exclList, Uri pacFileUrl) {
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            ProcessRecord r = mLruProcesses.get(i);
+            // Don't dispatch to isolated processes as they can't access
+            // ConnectivityManager and don't have network privileges anyway.
+            if (r.thread != null && !r.isolated) {
+                try {
+                    r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
+                } catch (RemoteException ex) {
+                    Slog.w(TAG, "Failed to update http proxy for: " +
+                            r.info.processName);
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mService")
+    void clearAllDnsCacheLocked() {
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            ProcessRecord r = mLruProcesses.get(i);
+            if (r.thread != null) {
+                try {
+                    r.thread.clearDnsCache();
+                } catch (RemoteException ex) {
+                    Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mService")
+    void handleAllTrustStorageUpdateLocked() {
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            ProcessRecord r = mLruProcesses.get(i);
+            if (r.thread != null) {
+                try {
+                    r.thread.handleTrustStorageUpdate();
+                } catch (RemoteException ex) {
+                    Slog.w(TAG, "Failed to handle trust storage update for: " +
+                            r.info.processName);
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mService")
+    int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
+            String what, Object obj, ProcessRecord srcApp) {
+        app.lastActivityTime = now;
+
+        if (app.hasActivitiesOrRecentTasks()) {
+            // Don't want to touch dependent processes that are hosting activities.
+            return index;
+        }
+
+        int lrui = mLruProcesses.lastIndexOf(app);
+        if (lrui < 0) {
+            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
+                    + what + " " + obj + " from " + srcApp);
+            return index;
+        }
+
+        if (lrui >= index) {
+            // Don't want to cause this to move dependent processes *back* in the
+            // list as if they were less frequently used.
+            return index;
+        }
+
+        if (lrui >= mLruProcessActivityStart) {
+            // Don't want to touch dependent processes that are hosting activities.
+            return index;
+        }
+
+        mLruProcesses.remove(lrui);
+        if (index > 0) {
+            index--;
+        }
+        if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
+                + " in LRU list: " + app);
+        mLruProcesses.add(index, app);
+        return index;
+    }
+
+    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
+            ProcessRecord client) {
+        final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities()
+                || app.treatLikeActivity;
+        final boolean hasService = false; // not impl yet. app.services.size() > 0;
+        if (!activityChange && hasActivity) {
+            // The process has activities, so we are only allowing activity-based adjustments
+            // to move it.  It should be kept in the front of the list with other
+            // processes that have activities, and we don't want those to change their
+            // order except due to activity operations.
+            return;
+        }
+
+        mLruSeq++;
+        final long now = SystemClock.uptimeMillis();
+        app.lastActivityTime = now;
+
+        // First a quick reject: if the app is already at the position we will
+        // put it, then there is nothing to do.
+        if (hasActivity) {
+            final int N = mLruProcesses.size();
+            if (N > 0 && mLruProcesses.get(N - 1) == app) {
+                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
+                return;
+            }
+        } else {
+            if (mLruProcessServiceStart > 0
+                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
+                if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
+                return;
+            }
+        }
+
+        int lrui = mLruProcesses.lastIndexOf(app);
+
+        if (app.isPersistent() && lrui >= 0) {
+            // We don't care about the position of persistent processes, as long as
+            // they are in the list.
+            if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
+            return;
+        }
+
+        /* In progress: compute new position first, so we can avoid doing work
+           if the process is not actually going to move.  Not yet working.
+        int addIndex;
+        int nextIndex;
+        boolean inActivity = false, inService = false;
+        if (hasActivity) {
+            // Process has activities, put it at the very tipsy-top.
+            addIndex = mLruProcesses.size();
+            nextIndex = mLruProcessServiceStart;
+            inActivity = true;
+        } else if (hasService) {
+            // Process has services, put it at the top of the service list.
+            addIndex = mLruProcessActivityStart;
+            nextIndex = mLruProcessServiceStart;
+            inActivity = true;
+            inService = true;
+        } else  {
+            // Process not otherwise of interest, it goes to the top of the non-service area.
+            addIndex = mLruProcessServiceStart;
+            if (client != null) {
+                int clientIndex = mLruProcesses.lastIndexOf(client);
+                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
+                        + app);
+                if (clientIndex >= 0 && addIndex > clientIndex) {
+                    addIndex = clientIndex;
+                }
+            }
+            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
+        }
+
+        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
+                + mLruProcessActivityStart + "): " + app);
+        */
+
+        if (lrui >= 0) {
+            if (lrui < mLruProcessActivityStart) {
+                mLruProcessActivityStart--;
+            }
+            if (lrui < mLruProcessServiceStart) {
+                mLruProcessServiceStart--;
+            }
+            /*
+            if (addIndex > lrui) {
+                addIndex--;
+            }
+            if (nextIndex > lrui) {
+                nextIndex--;
+            }
+            */
+            mLruProcesses.remove(lrui);
+        }
+
+        /*
+        mLruProcesses.add(addIndex, app);
+        if (inActivity) {
+            mLruProcessActivityStart++;
+        }
+        if (inService) {
+            mLruProcessActivityStart++;
+        }
+        */
+
+        int nextIndex;
+        if (hasActivity) {
+            final int N = mLruProcesses.size();
+            if ((!app.hasActivities() || app.hasRecentTasks())
+                    && mLruProcessActivityStart < (N - 1)) {
+                // Process doesn't have activities, but has clients with
+                // activities...  move it up, but one below the top (the top
+                // should always have a real activity).
+                if (DEBUG_LRU) Slog.d(TAG_LRU,
+                        "Adding to second-top of LRU activity list: " + app);
+                mLruProcesses.add(N - 1, app);
+                // To keep it from spamming the LRU list (by making a bunch of clients),
+                // we will push down any other entries owned by the app.
+                final int uid = app.info.uid;
+                for (int i = N - 2; i > mLruProcessActivityStart; i--) {
+                    ProcessRecord subProc = mLruProcesses.get(i);
+                    if (subProc.info.uid == uid) {
+                        // We want to push this one down the list.  If the process after
+                        // it is for the same uid, however, don't do so, because we don't
+                        // want them internally to be re-ordered.
+                        if (mLruProcesses.get(i - 1).info.uid != uid) {
+                            if (DEBUG_LRU) Slog.d(TAG_LRU,
+                                    "Pushing uid " + uid + " swapping at " + i + ": "
+                                            + mLruProcesses.get(i) + " : "
+                                            + mLruProcesses.get(i - 1));
+                            ProcessRecord tmp = mLruProcesses.get(i);
+                            mLruProcesses.set(i, mLruProcesses.get(i - 1));
+                            mLruProcesses.set(i - 1, tmp);
+                            i--;
+                        }
+                    } else {
+                        // A gap, we can stop here.
+                        break;
+                    }
+                }
+            } else {
+                // Process has activities, put it at the very tipsy-top.
+                if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
+                mLruProcesses.add(app);
+            }
+            nextIndex = mLruProcessServiceStart;
+        } else if (hasService) {
+            // Process has services, put it at the top of the service list.
+            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
+            mLruProcesses.add(mLruProcessActivityStart, app);
+            nextIndex = mLruProcessServiceStart;
+            mLruProcessActivityStart++;
+        } else  {
+            // Process not otherwise of interest, it goes to the top of the non-service area.
+            int index = mLruProcessServiceStart;
+            if (client != null) {
+                // If there is a client, don't allow the process to be moved up higher
+                // in the list than that client.
+                int clientIndex = mLruProcesses.lastIndexOf(client);
+                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
+                        + " when updating " + app);
+                if (clientIndex <= lrui) {
+                    // Don't allow the client index restriction to push it down farther in the
+                    // list than it already is.
+                    clientIndex = lrui;
+                }
+                if (clientIndex >= 0 && index > clientIndex) {
+                    index = clientIndex;
+                }
+            }
+            if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
+            mLruProcesses.add(index, app);
+            nextIndex = index - 1;
+            mLruProcessActivityStart++;
+            mLruProcessServiceStart++;
+        }
+
+        // If the app is currently using a content provider or service,
+        // bump those processes as well.
+        for (int j = app.connections.size() - 1; j >= 0; j--) {
+            ConnectionRecord cr = app.connections.valueAt(j);
+            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
+                    && cr.binding.service.app != null
+                    && cr.binding.service.app.lruSeq != mLruSeq
+                    && !cr.binding.service.app.isPersistent()) {
+                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app,
+                        now,
+                        nextIndex,
+                        "service connection", cr, app);
+            }
+        }
+        for (int j = app.conProviders.size() - 1; j >= 0; j--) {
+            ContentProviderRecord cpr = app.conProviders.get(j).provider;
+            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) {
+                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
+                        "provider reference", cpr, app);
+            }
+        }
+    }
+
+    final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) {
+        final IBinder threadBinder = thread.asBinder();
+        // Find the application record.
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            final ProcessRecord rec = mLruProcesses.get(i);
+            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
+                return rec;
+            }
+        }
+        return null;
+    }
+
+    boolean haveBackgroundProcessLocked() {
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            final ProcessRecord rec = mLruProcesses.get(i);
+            if (rec.thread != null
+                    && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static int procStateToImportance(int procState, int memAdj,
+            ActivityManager.RunningAppProcessInfo currApp,
+            int clientTargetSdk) {
+        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
+                procState, clientTargetSdk);
+        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
+            currApp.lru = memAdj;
+        } else {
+            currApp.lru = 0;
+        }
+        return imp;
+    }
+
+    @GuardedBy("mService")
+    void fillInProcMemInfoLocked(ProcessRecord app,
+            ActivityManager.RunningAppProcessInfo outInfo,
+            int clientTargetSdk) {
+        outInfo.pid = app.pid;
+        outInfo.uid = app.info.uid;
+        if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) {
+            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
+        }
+        if (app.isPersistent()) {
+            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
+        }
+        if (app.hasActivities()) {
+            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
+        }
+        outInfo.lastTrimLevel = app.trimMemoryLevel;
+        int adj = app.curAdj;
+        int procState = app.getCurProcState();
+        outInfo.importance = procStateToImportance(procState, adj, outInfo,
+                clientTargetSdk);
+        outInfo.importanceReasonCode = app.adjTypeCode;
+        outInfo.processState = app.getCurProcState();
+        outInfo.isFocused = (app == mService.getTopAppLocked());
+        outInfo.lastActivityTime = app.lastActivityTime;
+    }
+
+    @GuardedBy("mService")
+    List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers,
+            int userId, boolean allUids, int callingUid, int clientTargetSdk) {
+        // Lazy instantiation of list
+        List<ActivityManager.RunningAppProcessInfo> runList = null;
+
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            ProcessRecord app = mLruProcesses.get(i);
+            if ((!allUsers && app.userId != userId)
+                    || (!allUids && app.uid != callingUid)) {
+                continue;
+            }
+            if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) {
+                // Generate process state info for running application
+                ActivityManager.RunningAppProcessInfo currApp =
+                        new ActivityManager.RunningAppProcessInfo(app.processName,
+                                app.pid, app.getPackageList());
+                fillInProcMemInfoLocked(app, currApp, clientTargetSdk);
+                if (app.adjSource instanceof ProcessRecord) {
+                    currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
+                    currApp.importanceReasonImportance =
+                            ActivityManager.RunningAppProcessInfo.procStateToImportance(
+                                    app.adjSourceProcState);
+                } else if (app.adjSource instanceof ActivityRecord) {
+                    ActivityRecord r = (ActivityRecord)app.adjSource;
+                    if (r.app != null) currApp.importanceReasonPid = r.app.getPid();
+                }
+                if (app.adjTarget instanceof ComponentName) {
+                    currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
+                }
+                //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
+                //        + " lru=" + currApp.lru);
+                if (runList == null) {
+                    runList = new ArrayList<>();
+                }
+                runList.add(currApp);
+            }
+        }
+        return runList;
+    }
+
+    @GuardedBy("mService")
+    int getLruSizeLocked() {
+        return mLruProcesses.size();
+    }
+
+    @GuardedBy("mService")
+    void dumpLruListHeaderLocked(PrintWriter pw) {
+        pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
+        pw.print(" total, non-act at ");
+        pw.print(mLruProcesses.size() - mLruProcessActivityStart);
+        pw.print(", non-svc at ");
+        pw.print(mLruProcesses.size() - mLruProcessServiceStart);
+        pw.println("):");
+    }
+
+    @GuardedBy("mService")
+    ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) {
+        ArrayList<ProcessRecord> procs;
+        if (args != null && args.length > start
+                && args[start].charAt(0) != '-') {
+            procs = new ArrayList<ProcessRecord>();
+            int pid = -1;
+            try {
+                pid = Integer.parseInt(args[start]);
+            } catch (NumberFormatException e) {
+            }
+            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+                ProcessRecord proc = mLruProcesses.get(i);
+                if (proc.pid > 0 && proc.pid == pid) {
+                    procs.add(proc);
+                } else if (allPkgs && proc.pkgList != null
+                        && proc.pkgList.containsKey(args[start])) {
+                    procs.add(proc);
+                } else if (proc.processName.equals(args[start])) {
+                    procs.add(proc);
+                }
+            }
+            if (procs.size() <= 0) {
+                return null;
+            }
+        } else {
+            procs = new ArrayList<ProcessRecord>(mLruProcesses);
+        }
+        return procs;
+    }
+
+    @GuardedBy("mService")
+    void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId,
+            boolean updateFrameworkRes) {
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            final ProcessRecord app = mLruProcesses.get(i);
+            if (app.thread == null) {
+                continue;
+            }
+
+            if (userId != UserHandle.USER_ALL && app.userId != userId) {
+                continue;
+            }
+
+            final int packageCount = app.pkgList.size();
+            for (int j = 0; j < packageCount; j++) {
+                final String packageName = app.pkgList.keyAt(j);
+                if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
+                    try {
+                        final ApplicationInfo ai = AppGlobals.getPackageManager()
+                                .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
+                        if (ai != null) {
+                            app.thread.scheduleApplicationInfoChanged(ai);
+                        }
+                    } catch (RemoteException e) {
+                        Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
+                                packageName, app));
+                    }
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mService")
+    void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
+        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
+            ProcessRecord r = mLruProcesses.get(i);
+            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
+                try {
+                    r.thread.dispatchPackageBroadcast(cmd, packages);
+                } catch (RemoteException ex) {
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index 667d3fa..fa7a08b 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -18,12 +18,17 @@
 
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
 
+import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
 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.ActivityManagerService.MY_PID;
 
 import android.app.ActivityManager;
+import android.app.ApplicationErrorReport;
 import android.app.Dialog;
 import android.app.IApplicationThread;
+import android.app.ProfilerInfo;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -32,16 +37,19 @@
 import android.os.Binder;
 import android.os.Debug;
 import android.os.IBinder;
+import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.DebugUtils;
 import android.util.EventLog;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.StatsLog;
 import android.util.TimeUtils;
 import android.util.proto.ProtoOutputStream;
@@ -49,7 +57,11 @@
 import com.android.internal.app.procstats.ProcessState;
 import com.android.internal.app.procstats.ProcessStats;
 import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.ProcessCpuTracker;
+import com.android.server.Watchdog;
 
+import java.io.File;
+import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -128,7 +140,7 @@
     long lastCachedPss;         // Last computed pss when in cached state.
     long lastCachedSwapPss;     // Last computed SwapPss when in cached state.
     int maxAdj;                 // Maximum OOM adjustment for this process
-    int curRawAdj;              // Current OOM unlimited adjustment for this process
+    private int mCurRawAdj;     // Current OOM unlimited adjustment for this process
     int setRawAdj;              // Last set OOM unlimited adjustment for this process
     int curAdj;                 // Current OOM adjustment for this process
     int setAdj;                 // Last set OOM adjustment for this process
@@ -136,7 +148,7 @@
     private int mCurSchedGroup; // Currently desired scheduling class
     int setSchedGroup;          // Last set to background scheduling class
     int trimMemoryLevel;        // Last selected memory trimming level
-    int curProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state
+    private int mCurProcState = PROCESS_STATE_NONEXISTENT; // Currently computed process state
     private int mRepProcState = PROCESS_STATE_NONEXISTENT; // Last reported process state
     int setProcState = PROCESS_STATE_NONEXISTENT; // Last set process state in process tracker
     int pssProcState = PROCESS_STATE_NONEXISTENT; // Currently requesting pss for
@@ -146,19 +158,19 @@
     boolean serviceb;           // Process currently is on the service B list
     boolean serviceHighRam;     // We are forcing to service B list due to its RAM use
     boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle?
-    boolean hasClientActivities;  // Are there any client services with activities?
+    private boolean mHasClientActivities;  // Are there any client services with activities?
     boolean hasStartedServices; // Are there any started services running in this process?
     private boolean mHasForegroundServices; // Running any services that are foreground?
-    boolean foregroundActivities; // Running any activities that are foreground?
+    private boolean mHasForegroundActivities; // Running any activities that are foreground?
     boolean repForegroundActivities; // Last reported foreground activities.
     boolean systemNoUi;         // This is a system process, but not currently showing UI.
     boolean hasShownUi;         // Has UI been shown in this process since it was started?
-    boolean hasTopUi;           // Is this process currently showing a non-activity UI that the user
+    private boolean mHasTopUi;  // Is this process currently showing a non-activity UI that the user
                                 // is interacting with? E.g. The status bar when it is expanded, but
                                 // not when it is minimized. When true the
                                 // process will be set to use the ProcessList#SCHED_GROUP_TOP_APP
                                 // scheduling group to boost performance.
-    boolean hasOverlayUi;       // Is the process currently showing a non-activity UI that
+    private boolean mHasOverlayUi; // Is the process currently showing a non-activity UI that
                                 // overlays on-top of activity UIs on screen. E.g. display a window
                                 // of type
                                 // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
@@ -171,7 +183,7 @@
                                 // performance, as well as oom adj score will be set to
                                 // ProcessList#VISIBLE_APP_ADJ at minimum to reduce the chance
                                 // of the process getting killed.
-    boolean pendingUiClean;     // Want to clean up resources from showing UI?
+    private boolean mPendingUiClean; // Want to clean up resources from showing UI?
     boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
     boolean treatLikeActivity;  // Bound using BIND_TREAT_LIKE_ACTIVITY
     boolean bad;                // True if disabled in the bad process list
@@ -180,8 +192,8 @@
     boolean procStateChanged;   // Keep track of whether we changed 'setAdj'.
     boolean reportedInteraction;// Whether we have told usage stats about it being an interaction
     boolean unlocked;           // True when proc was started in user unlocked state
-    long interactionEventTime;  // The time we sent the last interaction event
-    long fgInteractionTime;     // When we became foreground for interaction purposes
+    private long mInteractionEventTime; // The time we sent the last interaction event
+    private long mFgInteractionTime; // When we became foreground for interaction purposes
     String waitingToKill;       // Process is waiting to be killed when in the bg, and reason
     Object forcingToImportant;  // Token that is forcing this process to be important
     int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
@@ -194,7 +206,7 @@
                                           // process.
     private boolean mUsingWrapper; // Set to true when process was launched with a wrapper attached
     final ArraySet<BroadcastRecord> curReceivers = new ArraySet<BroadcastRecord>();// receivers currently running in the app
-    long whenUnimportant;       // When (uptime) the process last became unimportant
+    private long mWhenUnimportant; // When (uptime) the process last became unimportant
     long lastCpuTime;           // How long proc has run CPU at last check
     long curCpuTime;            // How long proc has run CPU most recently
     long lastRequestedGc;       // When we last asked the app to do a gc
@@ -362,7 +374,7 @@
                     pw.print(" initialIdlePss="); pw.println(initialIdlePss);
         }
         pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
-                pw.print(" curRaw="); pw.print(curRawAdj);
+                pw.print(" curRaw="); pw.print(mCurRawAdj);
                 pw.print(" setRaw="); pw.print(setRawAdj);
                 pw.print(" cur="); pw.print(curAdj);
                 pw.print(" set="); pw.println(setAdj);
@@ -370,38 +382,38 @@
                 pw.print(" setSchedGroup="); pw.print(setSchedGroup);
                 pw.print(" systemNoUi="); pw.print(systemNoUi);
                 pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
-        pw.print(prefix); pw.print("curProcState="); pw.print(curProcState);
+        pw.print(prefix); pw.print("curProcState="); pw.print(getCurProcState());
                 pw.print(" mRepProcState="); pw.print(mRepProcState);
                 pw.print(" pssProcState="); pw.print(pssProcState);
                 pw.print(" setProcState="); pw.print(setProcState);
                 pw.print(" lastStateTime=");
                 TimeUtils.formatDuration(lastStateTime, nowUptime, pw);
                 pw.println();
-        if (hasShownUi || pendingUiClean || hasAboveClient || treatLikeActivity) {
+        if (hasShownUi || mPendingUiClean || hasAboveClient || treatLikeActivity) {
             pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
-                    pw.print(" pendingUiClean="); pw.print(pendingUiClean);
+                    pw.print(" pendingUiClean="); pw.print(mPendingUiClean);
                     pw.print(" hasAboveClient="); pw.print(hasAboveClient);
                     pw.print(" treatLikeActivity="); pw.println(treatLikeActivity);
         }
-        if (hasTopUi || hasOverlayUi || runningRemoteAnimation) {
-            pw.print(prefix); pw.print("hasTopUi="); pw.print(hasTopUi);
-                    pw.print(" hasOverlayUi="); pw.print(hasOverlayUi);
+        if (hasTopUi() || hasOverlayUi() || runningRemoteAnimation) {
+            pw.print(prefix); pw.print("hasTopUi="); pw.print(hasTopUi());
+                    pw.print(" hasOverlayUi="); pw.print(hasOverlayUi());
                     pw.print(" runningRemoteAnimation="); pw.println(runningRemoteAnimation);
         }
         if (mHasForegroundServices || forcingToImportant != null) {
             pw.print(prefix); pw.print("mHasForegroundServices="); pw.print(mHasForegroundServices);
                     pw.print(" forcingToImportant="); pw.println(forcingToImportant);
         }
-        if (reportedInteraction || fgInteractionTime != 0) {
+        if (reportedInteraction || mFgInteractionTime != 0) {
             pw.print(prefix); pw.print("reportedInteraction=");
             pw.print(reportedInteraction);
-            if (interactionEventTime != 0) {
+            if (mInteractionEventTime != 0) {
                 pw.print(" time=");
-                TimeUtils.formatDuration(interactionEventTime, SystemClock.elapsedRealtime(), pw);
+                TimeUtils.formatDuration(mInteractionEventTime, SystemClock.elapsedRealtime(), pw);
             }
-            if (fgInteractionTime != 0) {
+            if (mFgInteractionTime != 0) {
                 pw.print(" fgInteractionTime=");
-                TimeUtils.formatDuration(fgInteractionTime, SystemClock.elapsedRealtime(), pw);
+                TimeUtils.formatDuration(mFgInteractionTime, SystemClock.elapsedRealtime(), pw);
             }
             pw.println();
         }
@@ -409,9 +421,9 @@
             pw.print(prefix); pw.print("persistent="); pw.print(mPersistent);
                     pw.print(" removed="); pw.println(removed);
         }
-        if (hasClientActivities || foregroundActivities || repForegroundActivities) {
-            pw.print(prefix); pw.print("hasClientActivities="); pw.print(hasClientActivities);
-                    pw.print(" foregroundActivities="); pw.print(foregroundActivities);
+        if (mHasClientActivities || mHasForegroundActivities || repForegroundActivities) {
+            pw.print(prefix); pw.print("hasClientActivities="); pw.print(mHasClientActivities);
+                    pw.print(" foregroundActivities="); pw.print(mHasForegroundActivities);
                     pw.print(" (rep="); pw.print(repForegroundActivities); pw.println(")");
         }
         if (lastProviderTime > 0) {
@@ -438,7 +450,7 @@
                         TimeUtils.formatDuration(curCpuTime - lastCpuTime, pw);
                     }
                     pw.print(" whenUnimportant=");
-                    TimeUtils.formatDuration(whenUnimportant - nowUptime, pw);
+                    TimeUtils.formatDuration(mWhenUnimportant - nowUptime, pw);
                     pw.println();
         }
         pw.print(prefix); pw.print("lastRequestedGc=");
@@ -531,7 +543,7 @@
         userId = UserHandle.getUserId(_uid);
         processName = _processName;
         maxAdj = ProcessList.UNKNOWN_ADJ;
-        curRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
+        mCurRawAdj = setRawAdj = ProcessList.INVALID_ADJ;
         curAdj = setAdj = verifiedAdj = ProcessList.INVALID_ADJ;
         mPersistent = false;
         removed = false;
@@ -723,7 +735,7 @@
             if (pid > 0) {
                 EventLog.writeEvent(EventLogTags.AM_KILL, userId, pid, processName, setAdj, reason);
                 Process.killProcessQuiet(pid);
-                ActivityManagerService.killProcessGroup(uid, pid);
+                ProcessList.killProcessGroup(uid, pid);
             } else {
                 pendingStart = false;
             }
@@ -735,6 +747,7 @@
         }
     }
 
+    @Override
     public void writeToProto(ProtoOutputStream proto, long fieldId) {
         long token = proto.start(fieldId);
         proto.write(ProcessRecordProto.PID, pid);
@@ -825,6 +838,13 @@
         return null;
     }
 
+    @Override
+    public void addPackage(String pkg, long versionCode) {
+        synchronized (mService) {
+            addPackage(pkg, versionCode, mService.mProcessStats);
+        }
+    }
+
     /*
      *  Return true if package has been added false if not
      */
@@ -857,7 +877,8 @@
 
     public void forceProcessStateUpTo(int newState) {
         if (mRepProcState > newState) {
-            curProcState = mRepProcState = newState;
+            mRepProcState = newState;
+            setCurProcState(newState);
             for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
                 StatsLog.write(StatsLog.PROCESS_STATE_CHANGED,
                         uid, processName, pkgList.keyAt(ipkg),
@@ -931,6 +952,15 @@
         return mCurSchedGroup;
     }
 
+    void setCurProcState(int curProcState) {
+        mCurProcState = curProcState;
+        mWindowProcessController.setCurrentProcState(mCurProcState);
+    }
+
+    int getCurProcState() {
+        return mCurProcState;
+    }
+
     void setReportedProcState(int repProcState) {
         mRepProcState = repProcState;
         for (int ipkg = pkgList.size() - 1; ipkg >= 0; ipkg--) {
@@ -991,6 +1021,69 @@
         return mHasForegroundServices;
     }
 
+    void setHasForegroundActivities(boolean hasForegroundActivities) {
+        mHasForegroundActivities = hasForegroundActivities;
+        mWindowProcessController.setHasForegroundActivities(hasForegroundActivities);
+    }
+
+    boolean hasForegroundActivities() {
+        return mHasForegroundActivities;
+    }
+
+    void setHasClientActivities(boolean hasClientActivities) {
+        mHasClientActivities = hasClientActivities;
+        mWindowProcessController.setHasClientActivities(hasClientActivities);
+    }
+
+    boolean hasClientActivities() {
+        return mHasClientActivities;
+    }
+
+    void setHasTopUi(boolean hasTopUi) {
+        mHasTopUi = hasTopUi;
+        mWindowProcessController.setHasTopUi(hasTopUi);
+    }
+
+    boolean hasTopUi() {
+        return mHasTopUi;
+    }
+
+    void setHasOverlayUi(boolean hasOverlayUi) {
+        mHasOverlayUi = hasOverlayUi;
+        mWindowProcessController.setHasOverlayUi(hasOverlayUi);
+    }
+
+    boolean hasOverlayUi() {
+        return mHasOverlayUi;
+    }
+
+    void setInteractionEventTime(long interactionEventTime) {
+        mInteractionEventTime = interactionEventTime;
+        mWindowProcessController.setInteractionEventTime(interactionEventTime);
+    }
+
+    long getInteractionEventTime() {
+        return mInteractionEventTime;
+    }
+
+    void setFgInteractionTime(long fgInteractionTime) {
+        mFgInteractionTime = fgInteractionTime;
+        mWindowProcessController.setFgInteractionTime(fgInteractionTime);
+    }
+
+    long getFgInteractionTime() {
+        return mFgInteractionTime;
+    }
+
+    void setWhenUnimportant(long whenUnimportant) {
+        mWhenUnimportant = whenUnimportant;
+        mWindowProcessController.setWhenUnimportant(whenUnimportant);
+    }
+
+    long getWhenUnimportant() {
+        return mWhenUnimportant;
+    }
+
     void setDebugging(boolean debugging) {
         mDebugging = debugging;
         mWindowProcessController.setDebugging(debugging);
@@ -1018,6 +1111,15 @@
         return mInstr;
     }
 
+    void setCurRawAdj(int curRawAdj) {
+        mCurRawAdj = curRawAdj;
+        mWindowProcessController.setPerceptible(curRawAdj <= ProcessList.PERCEPTIBLE_APP_ADJ);
+    }
+
+    int getCurRawAdj() {
+        return mCurRawAdj;
+    }
+
     @Override
     public void clearProfilerIfNeeded() {
         synchronized (mService) {
@@ -1039,14 +1141,19 @@
     @Override
     public void setPendingUiClean(boolean pendingUiClean) {
         synchronized (mService) {
-            this.pendingUiClean = true;
+            mPendingUiClean = pendingUiClean;
+            mWindowProcessController.setPendingUiClean(pendingUiClean);
         }
     }
 
+    boolean hasPendingUiClean() {
+        return mPendingUiClean;
+    }
+
     @Override
     public void setPendingUiCleanAndForceProcessStateUpTo(int newState) {
         synchronized (mService) {
-            pendingUiClean = true;
+            setPendingUiClean(true);
             forceProcessStateUpTo(newState);
         }
     }
@@ -1059,7 +1166,7 @@
                 mService.mServices.updateServiceConnectionActivitiesLocked(this);
             }
             if (updateLru) {
-                mService.updateLruProcessLocked(this, activityChange, null);
+                mService.mProcessList.updateLruProcessLocked(this, activityChange, null);
             }
             if (updateOomAdj) {
                 mService.updateOomAdjLocked();
@@ -1078,7 +1185,315 @@
      * Returns the total time (in milliseconds) spent executing in both user and system code.
      * Safe to call without lock held.
      */
+    @Override
     public long getCpuTime() {
         return mService.mProcessCpuTracker.getCpuTimeForPid(pid);
     }
+
+    @Override
+    public void clearWaitingToKill() {
+        synchronized (mService) {
+            waitingToKill = null;
+        }
+    }
+
+    @Override
+    public ProfilerInfo onStartActivity(int topProcessState) {
+        synchronized (mService) {
+            ProfilerInfo profilerInfo = null;
+            if (mService.mProfileApp != null && mService.mProfileApp.equals(processName)) {
+                if (mService.mProfileProc == null || mService.mProfileProc == this) {
+                    mService.mProfileProc = this;
+                    final ProfilerInfo profilerInfoSvc = mService.mProfilerInfo;
+                    if (profilerInfoSvc != null && profilerInfoSvc.profileFile != null) {
+                        if (profilerInfoSvc.profileFd != null) {
+                            try {
+                                profilerInfoSvc.profileFd = profilerInfoSvc.profileFd.dup();
+                            } catch (IOException e) {
+                                profilerInfoSvc.closeFd();
+                            }
+                        }
+
+                        profilerInfo = new ProfilerInfo(profilerInfoSvc);
+                    }
+                }
+            }
+
+            hasShownUi = true;
+            setPendingUiClean(true);
+            forceProcessStateUpTo(topProcessState);
+
+            return profilerInfo;
+        }
+    }
+
+    @Override
+    public void appDied() {
+        synchronized (mService) {
+            mService.appDiedLocked(this);
+        }
+    }
+
+    public long getInputDispatchingTimeout() {
+        return mWindowProcessController.getInputDispatchingTimeout();
+    }
+
+    void appNotResponding(String activityShortComponentName, ApplicationInfo aInfo,
+            String parentShortComponentName, WindowProcessController parentProcess,
+            boolean aboveSystem, String annotation) {
+        ArrayList<Integer> firstPids = new ArrayList<>(5);
+        SparseArray<Boolean> lastPids = new SparseArray<>(20);
+
+        if (mService.mActivityTaskManager.mController != null) {
+            try {
+                // 0 == continue, -1 = kill process immediately
+                int res = mService.mActivityTaskManager.mController.appEarlyNotResponding(
+                        processName, pid, annotation);
+                if (res < 0 && pid != MY_PID) {
+                    kill("anr", true);
+                }
+            } catch (RemoteException e) {
+                mService.mActivityTaskManager.mController = null;
+                Watchdog.getInstance().setActivityController(null);
+            }
+        }
+
+        long anrTime = SystemClock.uptimeMillis();
+        if (ActivityManagerService.MONITOR_CPU_USAGE) {
+            mService.updateCpuStatsNow();
+        }
+
+        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
+        boolean showBackground = Settings.Secure.getInt(mService.mContext.getContentResolver(),
+                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
+
+        boolean isSilentANR;
+
+        synchronized (mService) {
+            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
+            if (mService.mActivityTaskManager.mShuttingDown) {
+                Slog.i(TAG, "During shutdown skipping ANR: " + this + " " + annotation);
+                return;
+            } else if (isNotResponding()) {
+                Slog.i(TAG, "Skipping duplicate ANR: " + this + " " + annotation);
+                return;
+            } else if (isCrashing()) {
+                Slog.i(TAG, "Crashing app skipping ANR: " + this + " " + annotation);
+                return;
+            } else if (killedByAm) {
+                Slog.i(TAG, "App already killed by AM skipping ANR: " + this + " " + annotation);
+                return;
+            } else if (killed) {
+                Slog.i(TAG, "Skipping died app ANR: " + this + " " + annotation);
+                return;
+            }
+
+            // In case we come through here for the same app before completing
+            // this one, mark as anring now so we will bail out.
+            setNotResponding(true);
+
+            // Log the ANR to the event log.
+            EventLog.writeEvent(EventLogTags.AM_ANR, userId, pid, processName, info.flags,
+                    annotation);
+
+            // Dump thread traces as quickly as we can, starting with "interesting" processes.
+            firstPids.add(pid);
+
+            // Don't dump other PIDs if it's a background ANR
+            isSilentANR = !showBackground && !isInterestingForBackgroundTraces();
+            if (!isSilentANR) {
+                int parentPid = pid;
+                if (parentProcess != null && parentProcess.getPid() > 0) {
+                    parentPid = parentProcess.getPid();
+                }
+                if (parentPid != pid) firstPids.add(parentPid);
+
+                if (MY_PID != pid && MY_PID != parentPid) firstPids.add(MY_PID);
+
+                for (int i = mService.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
+                    ProcessRecord r = mService.mProcessList.mLruProcesses.get(i);
+                    if (r != null && r.thread != null) {
+                        int myPid = r.pid;
+                        if (myPid > 0 && myPid != pid && myPid != parentPid && myPid != MY_PID) {
+                            if (r.isPersistent()) {
+                                firstPids.add(myPid);
+                                if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
+                            } else if (r.treatLikeActivity) {
+                                firstPids.add(myPid);
+                                if (DEBUG_ANR) Slog.i(TAG, "Adding likely IME: " + r);
+                            } else {
+                                lastPids.put(myPid, Boolean.TRUE);
+                                if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // Log the ANR to the main log.
+        StringBuilder info = new StringBuilder();
+        info.setLength(0);
+        info.append("ANR in ").append(processName);
+        if (activityShortComponentName != null) {
+            info.append(" (").append(activityShortComponentName).append(")");
+        }
+        info.append("\n");
+        info.append("PID: ").append(pid).append("\n");
+        if (annotation != null) {
+            info.append("Reason: ").append(annotation).append("\n");
+        }
+        if (parentShortComponentName != null
+                && parentShortComponentName.equals(activityShortComponentName)) {
+            info.append("Parent: ").append(parentShortComponentName).append("\n");
+        }
+
+        ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
+
+        // don't dump native PIDs for background ANRs unless it is the process of interest
+        String[] nativeProcs = null;
+        if (isSilentANR) {
+            for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
+                if (NATIVE_STACKS_OF_INTEREST[i].equals(processName)) {
+                    nativeProcs = new String[] { processName };
+                    break;
+                }
+            }
+        } else {
+            nativeProcs = NATIVE_STACKS_OF_INTEREST;
+        }
+
+        int[] pids = nativeProcs == null ? null : Process.getPidsForCommands(nativeProcs);
+        ArrayList<Integer> nativePids = null;
+
+        if (pids != null) {
+            nativePids = new ArrayList<>(pids.length);
+            for (int i : pids) {
+                nativePids.add(i);
+            }
+        }
+
+        // For background ANRs, don't pass the ProcessCpuTracker to
+        // avoid spending 1/2 second collecting stats to rank lastPids.
+        File tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
+                (isSilentANR) ? null : processCpuTracker, (isSilentANR) ? null : lastPids,
+                nativePids);
+
+        String cpuInfo = null;
+        if (ActivityManagerService.MONITOR_CPU_USAGE) {
+            mService.updateCpuStatsNow();
+            synchronized (mService.mProcessCpuTracker) {
+                cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
+            }
+            info.append(processCpuTracker.printCurrentLoad());
+            info.append(cpuInfo);
+        }
+
+        info.append(processCpuTracker.printCurrentState(anrTime));
+
+        Slog.e(TAG, info.toString());
+        if (tracesFile == null) {
+            // There is no trace file, so dump (only) the alleged culprit's threads to the log
+            Process.sendSignal(pid, Process.SIGNAL_QUIT);
+        }
+
+        StatsLog.write(StatsLog.ANR_OCCURRED, uid, processName,
+                activityShortComponentName == null ? "unknown": activityShortComponentName,
+                annotation,
+                (this.info != null) ? (this.info.isInstantApp()
+                        ? StatsLog.ANROCCURRED__IS_INSTANT_APP__TRUE
+                        : StatsLog.ANROCCURRED__IS_INSTANT_APP__FALSE)
+                        : StatsLog.ANROCCURRED__IS_INSTANT_APP__UNAVAILABLE,
+                isInterestingToUserLocked()
+                        ? StatsLog.ANROCCURRED__FOREGROUND_STATE__FOREGROUND
+                        : StatsLog.ANROCCURRED__FOREGROUND_STATE__BACKGROUND);
+        final ProcessRecord parentPr = parentProcess != null
+                ? (ProcessRecord) parentProcess.mOwner : null;
+        mService.addErrorToDropBox("anr", this, processName, activityShortComponentName,
+                parentShortComponentName, parentPr, annotation, cpuInfo, tracesFile, null);
+
+        if (mService.mActivityTaskManager.mController != null) {
+            try {
+                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
+                int res = mService.mActivityTaskManager.mController.appNotResponding(
+                        processName, pid, info.toString());
+                if (res != 0) {
+                    if (res < 0 && pid != MY_PID) {
+                        kill("anr", true);
+                    } else {
+                        synchronized (mService) {
+                            mService.mServices.scheduleServiceTimeoutLocked(this);
+                        }
+                    }
+                    return;
+                }
+            } catch (RemoteException e) {
+                mService.mActivityTaskManager.mController = null;
+                Watchdog.getInstance().setActivityController(null);
+            }
+        }
+
+        synchronized (mService) {
+            mService.mBatteryStatsService.noteProcessAnr(processName, uid);
+
+            if (isSilentANR) {
+                kill("bg anr", true);
+                return;
+            }
+
+            // Set the app's notResponding state, and look up the errorReportReceiver
+            makeAppNotRespondingLocked(activityShortComponentName,
+                    annotation != null ? "ANR " + annotation : "ANR", info.toString());
+
+            // Bring up the infamous App Not Responding dialog
+            Message msg = Message.obtain();
+            msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
+            msg.obj = new AppNotRespondingDialog.Data(this, aInfo, aboveSystem);
+
+            mService.mUiHandler.sendMessage(msg);
+        }
+    }
+
+    private void makeAppNotRespondingLocked(String activity, String shortMsg, String longMsg) {
+        setNotResponding(true);
+        notRespondingReport = mService.mAppErrors.generateProcessError(this,
+                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
+                activity, shortMsg, longMsg, null);
+        startAppProblemLocked();
+        getWindowProcessController().stopFreezingActivities();
+    }
+
+    void startAppProblemLocked() {
+        // If this app is not running under the current user, then we can't give it a report button
+        // because that would require launching the report UI under a different user.
+        errorReportReceiver = null;
+
+        for (int userId : mService.mUserController.getCurrentProfileIds()) {
+            if (this.userId == userId) {
+                errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
+                        mService.mContext, info.packageName, info.flags);
+            }
+        }
+        mService.skipCurrentReceiverLocked(this);
+    }
+
+    private boolean isInterestingForBackgroundTraces() {
+        // The system_server is always considered interesting.
+        if (pid == MY_PID) {
+            return true;
+        }
+
+        // A package is considered interesting if any of the following is true :
+        //
+        // - It's displaying an activity.
+        // - It's the SystemUI.
+        // - It has an overlay or a top UI visible.
+        //
+        // NOTE: The check whether a given ProcessRecord belongs to the systemui
+        // process is a bit of a kludge, but the same pattern seems repeated at
+        // several places in the system server.
+        return isInterestingToUserLocked() ||
+                (info != null && "com.android.systemui".equals(info.packageName))
+                || (hasTopUi() || hasOverlayUi());
+    }
 }
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index e11e003..57f939f 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -30,17 +30,18 @@
 import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-
 import static android.os.Process.SYSTEM_UID;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS_TRIM_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RECENTS_TRIM_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
-import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
@@ -55,7 +56,6 @@
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
-import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.IBinder;
@@ -103,7 +103,7 @@
  *                                  // 'X' tasks are trimmed.
  */
 class RecentTasks {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "RecentTasks" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "RecentTasks" : TAG_ATM;
     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
     private static final String TAG_TASKS = TAG + POSTFIX_TASKS;
 
@@ -431,7 +431,7 @@
     void onSystemReadyLocked() {
         loadRecentsComponent(mService.mContext.getResources());
         mTasks.clear();
-        mTaskPersister.startPersisting();
+        mTaskPersister.onSystemReady();
     }
 
     Bitmap getTaskDescriptionIcon(String path) {
@@ -755,7 +755,7 @@
             boolean getTasksAllowed, boolean getDetailedTasks, int userId, int callingUid) {
         final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0;
 
-        if (!mService.mAm.isUserRunning(userId, FLAG_AND_UNLOCKED)) {
+        if (!mService.mAmInternal.isUserRunning(userId, FLAG_AND_UNLOCKED)) {
             Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
             return new ArrayList<>();
         }
@@ -1244,7 +1244,6 @@
      */
     protected boolean isTrimmable(TaskRecord task) {
         final ActivityStack stack = task.getStack();
-        final ActivityStack homeStack = mSupervisor.mHomeStack;
 
         // No stack for task, just trim it
         if (stack == null) {
@@ -1252,13 +1251,14 @@
         }
 
         // Ignore tasks from different displays
-        if (stack.getDisplay() != homeStack.getDisplay()) {
+        // TODO (b/115289124): No Recents on non-default displays.
+        if (stack.mDisplayId != DEFAULT_DISPLAY) {
             return false;
         }
 
         // Trim tasks that are in stacks that are behind the home stack
         final ActivityDisplay display = stack.getDisplay();
-        return display.getIndexOf(stack) < display.getIndexOf(homeStack);
+        return display.getIndexOf(stack) < display.getIndexOf(display.getHomeStack());
     }
 
     /**
diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java
index fa0cb47..1152165 100644
--- a/services/core/java/com/android/server/am/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/am/SafeActivityOptions.java
@@ -21,9 +21,9 @@
 import static android.content.pm.PackageManager.PERMISSION_DENIED;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.view.Display.INVALID_DISPLAY;
-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.TaskRecord.INVALID_TASK_ID;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
 import android.annotation.Nullable;
 import android.app.ActivityOptions;
@@ -46,7 +46,7 @@
  */
 public class SafeActivityOptions {
 
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "SafeActivityOptions" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "SafeActivityOptions" : TAG_ATM;
 
     private final int mOriginalCallingPid;
     private final int mOriginalCallingUid;
diff --git a/services/core/java/com/android/server/am/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/am/TaskLaunchParamsModifier.java
index 92f1cc3..111adec 100644
--- a/services/core/java/com/android/server/am/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/am/TaskLaunchParamsModifier.java
@@ -16,304 +16,788 @@
 
 package com.android.server.am;
 
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
-import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT;
+import static android.util.DisplayMetrics.DENSITY_DEFAULT;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
 
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.app.ActivityOptions;
+import android.app.WindowConfiguration;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.graphics.Rect;
+import android.os.Build;
 import android.util.Slog;
 import android.view.Gravity;
-import com.android.internal.annotations.VisibleForTesting;
+
 import com.android.server.am.LaunchParamsController.LaunchParams;
 import com.android.server.am.LaunchParamsController.LaunchParamsModifier;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
- * Determines where a launching task should be positioned and sized on the display.
- *
- * The modifier is fairly simple. For the new task it tries default position based on the gravity
- * and compares corners of the task with corners of existing tasks. If some two pairs of corners are
- * sufficiently close enough, it shifts the bounds of the new task and tries again. When it exhausts
- * all possible shifts, it gives up and puts the task in the original position.
- *
- * Note that the only gravities of concern are the corners and the center.
+ * The class that defines the default launch params for tasks.
  */
 class TaskLaunchParamsModifier implements LaunchParamsModifier {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskLaunchParamsModifier" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskLaunchParamsModifier" : TAG_ATM;
+    private static final boolean DEBUG = false;
 
-    // Determines how close window frames/corners have to be to call them colliding.
-    private static final int BOUNDS_CONFLICT_MIN_DISTANCE = 4;
+    // A mask for SUPPORTS_SCREEN that indicates the activity supports resize.
+    private static final int SUPPORTS_SCREEN_RESIZEABLE_MASK =
+            ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES
+                    | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS
+                    | ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
+                    | ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS
+                    | ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES
+                    | ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS;
 
-    // Task will receive dimensions based on available dimensions divided by this.
-    private static final int WINDOW_SIZE_DENOMINATOR = 2;
+    // Screen size of Nexus 5x
+    private static final int DEFAULT_PORTRAIT_PHONE_WIDTH_DP = 412;
+    private static final int DEFAULT_PORTRAIT_PHONE_HEIGHT_DP = 732;
 
-    // Task will receive margins based on available dimensions divided by this.
-    private static final int MARGIN_SIZE_DENOMINATOR = 4;
+    // Allowance of size matching.
+    private static final int EPSILON = 2;
 
-    // If task bounds collide with some other, we will step and try again until we find a good
-    // position. The step will be determined by using dimensions and dividing it by this.
+    // Cascade window offset.
+    private static final int CASCADING_OFFSET_DP = 75;
+
+    // Threshold how close window corners have to be to call them colliding.
+    private static final int BOUNDS_CONFLICT_THRESHOLD = 4;
+
+    // Divide display size by this number to get each step to adjust bounds to avoid conflict.
     private static final int STEP_DENOMINATOR = 16;
 
     // We always want to step by at least this.
     private static final int MINIMAL_STEP = 1;
 
-    // Used to indicate if positioning algorithm is allowed to restart from the beginning, when it
-    // reaches the end of stack bounds.
-    private static final boolean ALLOW_RESTART = true;
+    private final ActivityStackSupervisor mSupervisor;
+    private final Rect mTmpBounds = new Rect();
+    private final int[] mTmpDirections = new int[2];
 
-    private static final int SHIFT_POLICY_DIAGONAL_DOWN = 1;
-    private static final int SHIFT_POLICY_HORIZONTAL_RIGHT = 2;
-    private static final int SHIFT_POLICY_HORIZONTAL_LEFT = 3;
+    private StringBuilder mLogBuilder;
 
-    private final Rect mAvailableRect = new Rect();
-    private final Rect mTmpProposal = new Rect();
-    private final Rect mTmpOriginal = new Rect();
+    TaskLaunchParamsModifier(ActivityStackSupervisor supervisor) {
+        mSupervisor = supervisor;
+    }
 
-    /**
-     * Tries to set task's bound in a way that it won't collide with any other task. By colliding
-     * we mean that two tasks have left-top corner very close to each other, so one might get
-     * obfuscated by the other one.
-     */
     @Override
     public int onCalculate(TaskRecord task, ActivityInfo.WindowLayout layout,
                            ActivityRecord activity, ActivityRecord source, ActivityOptions options,
                            LaunchParams currentParams, LaunchParams outParams) {
-        // We can only apply positioning if we're in a freeform stack.
-        if (task == null || task.getStack() == null || !task.inFreeformWindowingMode()) {
+        initLogBuilder(task, activity);
+        final int result = calculate(task, layout, activity, source, options, currentParams,
+                outParams);
+        outputLog();
+        return result;
+    }
+
+    private int calculate(TaskRecord task, ActivityInfo.WindowLayout layout,
+            ActivityRecord activity, ActivityRecord source, ActivityOptions options,
+            LaunchParams currentParams, LaunchParams outParams) {
+        final ActivityRecord root;
+        if (task != null) {
+            root = task.getRootActivity() == null ? activity : task.getRootActivity();
+        } else {
+            root = activity;
+        }
+
+        // TODO: Investigate whether we can safely ignore all cases where we don't have root
+        // activity available. Note we can't know if the bounds are valid if we're not sure of the
+        // requested orientation of the root activity. Therefore if we found such a case we may need
+        // to pass the activity into this modifier in that case.
+        if (root == null) {
+            // There is a case that can lead us here. The caller is moving the top activity that is
+            // in a task that has multiple activities to PIP mode. For that the caller is creating a
+            // new task to host the activity so that we only move the top activity to PIP mode and
+            // keep other activities in the previous task. There is no point to apply the launch
+            // logic in this case.
             return RESULT_SKIP;
         }
 
-        final ArrayList<TaskRecord> tasks = task.getStack().getAllTasks();
-
-        mAvailableRect.set(task.getParent().getBounds());
-
-        final Rect resultBounds = outParams.mBounds;
-
-        if (layout == null) {
-            positionCenter(tasks, mAvailableRect, getFreeformWidth(mAvailableRect),
-                    getFreeformHeight(mAvailableRect), resultBounds);
-            return RESULT_CONTINUE;
+        // STEP 1: Determine the display to launch the activity/task.
+        final int displayId = getPreferredLaunchDisplay(options, source, currentParams);
+        outParams.mPreferredDisplayId = displayId;
+        ActivityDisplay display = mSupervisor.getActivityDisplay(displayId);
+        if (DEBUG) {
+            appendLog("display-id=" + outParams.mPreferredDisplayId + " display-windowing-mode="
+                    + display.getWindowingMode());
         }
 
-        int width = getFinalWidth(layout, mAvailableRect);
-        int height = getFinalHeight(layout, mAvailableRect);
-        int verticalGravity = layout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
-        int horizontalGravity = layout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
-        if (verticalGravity == Gravity.TOP) {
-            if (horizontalGravity == Gravity.RIGHT) {
-                positionTopRight(tasks, mAvailableRect, width, height, resultBounds);
+        // STEP 2: Resolve launch windowing mode.
+        // STEP 2.1: Determine if any parameter has specified initial bounds. That might be the
+        // launch bounds from activity options, or size/gravity passed in layout. It also treats the
+        // launch windowing mode in options as a suggestion for future resolution.
+        int launchMode = options != null ? options.getLaunchWindowingMode()
+                : WINDOWING_MODE_UNDEFINED;
+        // hasInitialBounds is set if either activity options or layout has specified bounds. If
+        // that's set we'll skip some adjustments later to avoid overriding the initial bounds.
+        boolean hasInitialBounds = false;
+        final boolean canApplyFreeformPolicy = canApplyFreeformWindowPolicy(display, launchMode);
+        if (mSupervisor.canUseActivityOptionsLaunchBounds(options)
+                && (canApplyFreeformPolicy || canApplyPipWindowPolicy(launchMode))) {
+            hasInitialBounds = true;
+            launchMode = launchMode == WINDOWING_MODE_UNDEFINED
+                    ? WINDOWING_MODE_FREEFORM
+                    : launchMode;
+            outParams.mBounds.set(options.getLaunchBounds());
+            if (DEBUG) appendLog("activity-options-bounds=" + outParams.mBounds);
+        } else if (launchMode == WINDOWING_MODE_PINNED) {
+            // System controls PIP window's bounds, so don't apply launch bounds.
+            if (DEBUG) appendLog("empty-window-layout-for-pip");
+        } else if (launchMode == WINDOWING_MODE_FULLSCREEN) {
+            if (DEBUG) appendLog("activity-options-fullscreen=" + outParams.mBounds);
+        } else if (layout != null && canApplyFreeformPolicy) {
+            getLayoutBounds(display, root, layout, mTmpBounds);
+            if (!mTmpBounds.isEmpty()) {
+                launchMode = WINDOWING_MODE_FREEFORM;
+                outParams.mBounds.set(mTmpBounds);
+                hasInitialBounds = true;
+                if (DEBUG) appendLog("bounds-from-layout=" + outParams.mBounds);
             } else {
-                positionTopLeft(tasks, mAvailableRect, width, height, resultBounds);
+                if (DEBUG) appendLog("empty-window-layout");
             }
-        } else if (verticalGravity == Gravity.BOTTOM) {
-            if (horizontalGravity == Gravity.RIGHT) {
-                positionBottomRight(tasks, mAvailableRect, width, height, resultBounds);
-            } else {
-                positionBottomLeft(tasks, mAvailableRect, width, height, resultBounds);
+        }
+
+        // STEP 2.2: Check if previous modifier or the controller (referred as "callers" below) has
+        // some opinions on launch mode and launch bounds. If they have opinions and there is no
+        // initial bounds set in parameters. Note the check on display ID is also input param
+        // related because we always defer to callers' suggestion if there is no specific display ID
+        // in options or from source activity.
+        //
+        // If opinions from callers don't need any further resolution, we try to honor that as is as
+        // much as possible later.
+
+        // Flag to indicate if current param needs no further resolution. It's true it current
+        // param isn't freeform mode, or it already has launch bounds.
+        boolean fullyResolvedCurrentParam = false;
+        // We inherit launch params from previous modifiers or LaunchParamsController if options,
+        // layout and display conditions are not contradictory to their suggestions. It's important
+        // to carry over their values because LaunchParamsController doesn't automatically do that.
+        if (!currentParams.isEmpty() && !hasInitialBounds
+                && (!currentParams.hasPreferredDisplay()
+                    || displayId == currentParams.mPreferredDisplayId)) {
+            if (currentParams.hasWindowingMode()) {
+                launchMode = currentParams.mWindowingMode;
+                fullyResolvedCurrentParam = (launchMode != WINDOWING_MODE_FREEFORM);
+                if (DEBUG) {
+                    appendLog("inherit-" + WindowConfiguration.windowingModeToString(launchMode));
+                }
+            }
+
+            if (!currentParams.mBounds.isEmpty()) {
+                outParams.mBounds.set(currentParams.mBounds);
+                fullyResolvedCurrentParam = true;
+                if (DEBUG) appendLog("inherit-bounds=" + outParams.mBounds);
+            }
+        }
+
+        // STEP 2.3: Adjust launch parameters as needed for freeform display. We enforce the policy
+        // that legacy (pre-D) apps and those apps that can't handle multiple screen density well
+        // are forced to be maximized. The rest of this step is to define the default policy when
+        // there is no initial bounds or a fully resolved current params from callers. Right now we
+        // launch all possible tasks/activities that can handle freeform into freeform mode.
+        if (display.inFreeformWindowingMode()) {
+            if (launchMode == WINDOWING_MODE_PINNED) {
+                if (DEBUG) appendLog("picture-in-picture");
+            } else if (isTaskForcedMaximized(root)) {
+                // We're launching an activity that probably can't handle resizing nicely, so force
+                // it to be maximized even someone suggests launching it in freeform using launch
+                // options.
+                launchMode = WINDOWING_MODE_FULLSCREEN;
+                outParams.mBounds.setEmpty();
+                if (DEBUG) appendLog("forced-maximize");
+            } else if (fullyResolvedCurrentParam) {
+                // Don't adjust launch mode if that's inherited, except when we're launching an
+                // activity that should be forced to maximize.
+                if (DEBUG) appendLog("skip-adjustment-fully-resolved-params");
+            } else if (launchMode != WINDOWING_MODE_FREEFORM
+                    && (isNOrGreater(root) || isPreNResizeable(root))) {
+                // We're launching a pre-N and post-D activity that supports resizing, or a post-N
+                // activity. They can handle freeform nicely so launch them in freeform.
+                // Use undefined because we know we're in a freeform display.
+                launchMode = WINDOWING_MODE_UNDEFINED;
+                if (DEBUG) appendLog("should-be-freeform");
             }
         } else {
-            // Some fancy gravity setting that we don't support yet. We just put the activity in the
-            // center.
-            Slog.w(TAG, "Received unsupported gravity: " + layout.gravity
-                    + ", positioning in the center instead.");
-            positionCenter(tasks, mAvailableRect, width, height, resultBounds);
+            if (DEBUG) appendLog("non-freeform-display");
+        }
+        // If launch mode matches display windowing mode, let it inherit from display.
+        outParams.mWindowingMode = launchMode == display.getWindowingMode()
+                ? WINDOWING_MODE_UNDEFINED : launchMode;
+
+        // STEP 3: Determine final launch bounds based on resolved windowing mode and activity
+        // requested orientation. We set bounds to empty for fullscreen mode and keep bounds as is
+        // for all other windowing modes that's not freeform mode. One can read comments in
+        // relevant methods to further understand this step.
+        //
+        // We skip making adjustments if the params are fully resolved from previous results and
+        // trust that they are valid.
+        if (!fullyResolvedCurrentParam) {
+            final int resolvedMode = (launchMode != WINDOWING_MODE_UNDEFINED) ? launchMode
+                    : display.getWindowingMode();
+            if (source != null && source.inFreeformWindowingMode()
+                    && resolvedMode == WINDOWING_MODE_FREEFORM
+                    && outParams.mBounds.isEmpty()
+                    && source.getDisplayId() == display.mDisplayId) {
+                // Set bounds to be not very far from source activity.
+                cascadeBounds(source.getBounds(), display, outParams.mBounds);
+            }
+            getTaskBounds(root, display, layout, resolvedMode, hasInitialBounds, outParams.mBounds);
         }
 
         return RESULT_CONTINUE;
     }
 
-    @VisibleForTesting
-    static int getFreeformStartLeft(Rect bounds) {
-        return bounds.left + bounds.width() / MARGIN_SIZE_DENOMINATOR;
-    }
-
-    @VisibleForTesting
-    static int getFreeformStartTop(Rect bounds) {
-        return bounds.top + bounds.height() / MARGIN_SIZE_DENOMINATOR;
-    }
-
-    @VisibleForTesting
-    static int getFreeformWidth(Rect bounds) {
-        return bounds.width() / WINDOW_SIZE_DENOMINATOR;
-    }
-
-    @VisibleForTesting
-    static int getFreeformHeight(Rect bounds) {
-        return bounds.height() / WINDOW_SIZE_DENOMINATOR;
-    }
-
-    @VisibleForTesting
-    static int getHorizontalStep(Rect bounds) {
-        return Math.max(bounds.width() / STEP_DENOMINATOR, MINIMAL_STEP);
-    }
-
-    @VisibleForTesting
-    static int getVerticalStep(Rect bounds) {
-        return Math.max(bounds.height() / STEP_DENOMINATOR, MINIMAL_STEP);
-    }
-
-
-
-    private int getFinalWidth(ActivityInfo.WindowLayout windowLayout, Rect availableRect) {
-        int width = getFreeformWidth(availableRect);
-        if (windowLayout.width > 0) {
-            width = windowLayout.width;
+    private int getPreferredLaunchDisplay(@Nullable ActivityOptions options,
+            ActivityRecord source, LaunchParams currentParams) {
+        int displayId = INVALID_DISPLAY;
+        final int optionLaunchId = options != null ? options.getLaunchDisplayId() : INVALID_DISPLAY;
+        if (optionLaunchId != INVALID_DISPLAY) {
+            if (DEBUG) appendLog("display-from-option=" + optionLaunchId);
+            displayId = optionLaunchId;
         }
-        if (windowLayout.widthFraction > 0) {
-            width = (int) (availableRect.width() * windowLayout.widthFraction);
+
+        if (displayId == INVALID_DISPLAY && source != null) {
+            final int sourceDisplayId = source.getDisplayId();
+            if (DEBUG) appendLog("display-from-source=" + sourceDisplayId);
+            displayId = sourceDisplayId;
         }
-        return width;
-    }
 
-    private int getFinalHeight(ActivityInfo.WindowLayout windowLayout, Rect availableRect) {
-        int height = getFreeformHeight(availableRect);
-        if (windowLayout.height > 0) {
-            height = windowLayout.height;
+        if (displayId != INVALID_DISPLAY && mSupervisor.getActivityDisplay(displayId) == null) {
+            displayId = INVALID_DISPLAY;
         }
-        if (windowLayout.heightFraction > 0) {
-            height = (int) (availableRect.height() * windowLayout.heightFraction);
+        displayId = (displayId == INVALID_DISPLAY) ? currentParams.mPreferredDisplayId : displayId;
+
+        displayId = (displayId == INVALID_DISPLAY) ? DEFAULT_DISPLAY : displayId;
+
+        return displayId;
+    }
+
+    private boolean canApplyFreeformWindowPolicy(@NonNull ActivityDisplay display, int launchMode) {
+        return mSupervisor.mService.mSupportsFreeformWindowManagement
+                && (display.inFreeformWindowingMode() || launchMode == WINDOWING_MODE_FREEFORM);
+    }
+
+    private boolean canApplyPipWindowPolicy(int launchMode) {
+        return mSupervisor.mService.mSupportsPictureInPicture
+                && launchMode == WINDOWING_MODE_PINNED;
+    }
+
+    private void getLayoutBounds(@NonNull ActivityDisplay display, @NonNull ActivityRecord root,
+            @NonNull ActivityInfo.WindowLayout windowLayout, @NonNull Rect outBounds) {
+        final int verticalGravity = windowLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
+        final int horizontalGravity = windowLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
+        if (!windowLayout.hasSpecifiedSize() && verticalGravity == 0 && horizontalGravity == 0) {
+            outBounds.setEmpty();
+            return;
         }
-        return height;
-    }
 
-    private void positionBottomLeft(ArrayList<TaskRecord> tasks, Rect availableRect, int width,
-            int height, Rect result) {
-        mTmpProposal.set(availableRect.left, availableRect.bottom - height,
-                availableRect.left + width, availableRect.bottom);
-        position(tasks, availableRect, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_RIGHT,
-                result);
-    }
+        final Rect bounds = display.getBounds();
+        final int defaultWidth = bounds.width();
+        final int defaultHeight = bounds.height();
 
-    private void positionBottomRight(ArrayList<TaskRecord> tasks, Rect availableRect, int width,
-            int height, Rect result) {
-        mTmpProposal.set(availableRect.right - width, availableRect.bottom - height,
-                availableRect.right, availableRect.bottom);
-        position(tasks, availableRect, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_LEFT,
-                result);
-    }
-
-    private void positionTopLeft(ArrayList<TaskRecord> tasks, Rect availableRect, int width,
-            int height, Rect result) {
-        mTmpProposal.set(availableRect.left, availableRect.top,
-                availableRect.left + width, availableRect.top + height);
-        position(tasks, availableRect, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_RIGHT,
-                result);
-    }
-
-    private void positionTopRight(ArrayList<TaskRecord> tasks, Rect availableRect, int width,
-            int height, Rect result) {
-        mTmpProposal.set(availableRect.right - width, availableRect.top,
-                availableRect.right, availableRect.top + height);
-        position(tasks, availableRect, mTmpProposal, !ALLOW_RESTART, SHIFT_POLICY_HORIZONTAL_LEFT,
-                result);
-    }
-
-    private void positionCenter(ArrayList<TaskRecord> tasks, Rect availableRect, int width,
-            int height, Rect result) {
-        final int defaultFreeformLeft = getFreeformStartLeft(availableRect);
-        final int defaultFreeformTop = getFreeformStartTop(availableRect);
-        mTmpProposal.set(defaultFreeformLeft, defaultFreeformTop,
-                defaultFreeformLeft + width, defaultFreeformTop + height);
-        position(tasks, availableRect, mTmpProposal, ALLOW_RESTART, SHIFT_POLICY_DIAGONAL_DOWN,
-                result);
-    }
-
-    private void position(ArrayList<TaskRecord> tasks, Rect availableRect,
-            Rect proposal, boolean allowRestart, int shiftPolicy, Rect result) {
-        mTmpOriginal.set(proposal);
-        boolean restarted = false;
-        while (boundsConflict(proposal, tasks)) {
-            // Unfortunately there is already a task at that spot, so we need to look for some
-            // other place.
-            shiftStartingPoint(proposal, availableRect, shiftPolicy);
-            if (shiftedTooFar(proposal, availableRect, shiftPolicy)) {
-                // We don't want the task to go outside of the stack, because it won't look
-                // nice. Depending on the starting point we either restart, or immediately give up.
-                if (!allowRestart) {
-                    proposal.set(mTmpOriginal);
-                    break;
-                }
-                // We must have started not from the top. Let's restart from there because there
-                // might be some space there.
-                proposal.set(availableRect.left, availableRect.top,
-                        availableRect.left + proposal.width(),
-                        availableRect.top + proposal.height());
-                restarted = true;
+        int width;
+        int height;
+        if (!windowLayout.hasSpecifiedSize()) {
+            outBounds.setEmpty();
+            getTaskBounds(root, display, windowLayout, WINDOWING_MODE_FREEFORM,
+                    /* hasInitialBounds */ false, outBounds);
+            width = outBounds.width();
+            height = outBounds.height();
+        } else {
+            width = defaultWidth;
+            if (windowLayout.width > 0 && windowLayout.width < defaultWidth) {
+                width = windowLayout.width;
+            } else if (windowLayout.widthFraction > 0 && windowLayout.widthFraction < 1.0f) {
+                width = (int) (width * windowLayout.widthFraction);
             }
-            if (restarted && (proposal.left > getFreeformStartLeft(availableRect)
-                    || proposal.top > getFreeformStartTop(availableRect))) {
-                // If we restarted and crossed the initial position, let's not struggle anymore.
-                // The user already must have ton of tasks visible, we can just smack the new
-                // one in the center.
-                proposal.set(mTmpOriginal);
-                break;
+
+            height = defaultHeight;
+            if (windowLayout.height > 0 && windowLayout.height < defaultHeight) {
+                height = windowLayout.height;
+            } else if (windowLayout.heightFraction > 0 && windowLayout.heightFraction < 1.0f) {
+                height = (int) (height * windowLayout.heightFraction);
             }
         }
-        result.set(proposal);
-    }
 
-    private boolean shiftedTooFar(Rect start, Rect availableRect, int shiftPolicy) {
-        switch (shiftPolicy) {
-            case SHIFT_POLICY_HORIZONTAL_LEFT:
-                return start.left < availableRect.left;
-            case SHIFT_POLICY_HORIZONTAL_RIGHT:
-                return start.right > availableRect.right;
-            default: // SHIFT_POLICY_DIAGONAL_DOWN
-                return start.right > availableRect.right || start.bottom > availableRect.bottom;
+        final float fractionOfHorizontalOffset;
+        switch (horizontalGravity) {
+            case Gravity.LEFT:
+                fractionOfHorizontalOffset = 0f;
+                break;
+            case Gravity.RIGHT:
+                fractionOfHorizontalOffset = 1f;
+                break;
+            default:
+                fractionOfHorizontalOffset = 0.5f;
         }
-    }
 
-    private void shiftStartingPoint(Rect posposal, Rect availableRect, int shiftPolicy) {
-        final int defaultFreeformStepHorizontal = getHorizontalStep(availableRect);
-        final int defaultFreeformStepVertical = getVerticalStep(availableRect);
-
-        switch (shiftPolicy) {
-            case SHIFT_POLICY_HORIZONTAL_LEFT:
-                posposal.offset(-defaultFreeformStepHorizontal, 0);
+        final float fractionOfVerticalOffset;
+        switch (verticalGravity) {
+            case Gravity.TOP:
+                fractionOfVerticalOffset = 0f;
                 break;
-            case SHIFT_POLICY_HORIZONTAL_RIGHT:
-                posposal.offset(defaultFreeformStepHorizontal, 0);
+            case Gravity.BOTTOM:
+                fractionOfVerticalOffset = 1f;
                 break;
-            default: // SHIFT_POLICY_DIAGONAL_DOWN:
-                posposal.offset(defaultFreeformStepHorizontal, defaultFreeformStepVertical);
-                break;
+            default:
+                fractionOfVerticalOffset = 0.5f;
         }
+
+        outBounds.set(0, 0, width, height);
+        final int xOffset = (int) (fractionOfHorizontalOffset * (defaultWidth - width));
+        final int yOffset = (int) (fractionOfVerticalOffset * (defaultHeight - height));
+        outBounds.offset(xOffset, yOffset);
     }
 
-    private static boolean boundsConflict(Rect proposal, ArrayList<TaskRecord> tasks) {
-        for (int i = tasks.size() - 1; i >= 0; i--) {
-            final TaskRecord task = tasks.get(i);
-            if (!task.mActivities.isEmpty() && !task.matchParentBounds()) {
-                final Rect bounds = task.getOverrideBounds();
-                if (closeLeftTopCorner(proposal, bounds) || closeRightTopCorner(proposal, bounds)
-                        || closeLeftBottomCorner(proposal, bounds)
-                        || closeRightBottomCorner(proposal, bounds)) {
-                    return true;
-                }
+    /**
+     * Returns if task is forced to maximize.
+     *
+     * There are several cases where we force a task to maximize:
+     * 1) Root activity is targeting pre-Donut, which by default can't handle multiple screen
+     *    densities, so resizing will likely cause issues;
+     * 2) Root activity doesn't declare any flag that it supports any screen density, so resizing
+     *    may also cause issues;
+     * 3) Root activity is not resizeable, for which we shouldn't allow user resize it.
+     *
+     * @param root the root activity to check against.
+     * @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) {
+            return true;
+        }
+
+        return !root.isResizeable();
+    }
+
+    private boolean isNOrGreater(@NonNull ActivityRecord root) {
+        return root.appInfo.targetSdkVersion >= Build.VERSION_CODES.N;
+    }
+
+    /**
+     * Resolves activity requested orientation to 4 categories:
+     * 1) {@link ActivityInfo#SCREEN_ORIENTATION_LOCKED} indicating app wants to lock down
+     *    orientation;
+     * 2) {@link ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE} indicating app wants to be in landscape;
+     * 3) {@link ActivityInfo#SCREEN_ORIENTATION_PORTRAIT} indicating app wants to be in portrait;
+     * 4) {@link ActivityInfo#SCREEN_ORIENTATION_UNSPECIFIED} indicating app can handle any
+     *    orientation.
+     *
+     * @param activity the activity to check
+     * @return corresponding resolved orientation value.
+     */
+    private int resolveOrientation(@NonNull ActivityRecord activity) {
+        int orientation = activity.info.screenOrientation;
+        switch (orientation) {
+            case SCREEN_ORIENTATION_NOSENSOR:
+            case SCREEN_ORIENTATION_LOCKED:
+                orientation = SCREEN_ORIENTATION_LOCKED;
+                break;
+            case SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+            case SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+            case SCREEN_ORIENTATION_USER_LANDSCAPE:
+            case SCREEN_ORIENTATION_LANDSCAPE:
+                if (DEBUG) appendLog("activity-requested-landscape");
+                orientation = SCREEN_ORIENTATION_LANDSCAPE;
+                break;
+            case SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+            case SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+            case SCREEN_ORIENTATION_USER_PORTRAIT:
+            case SCREEN_ORIENTATION_PORTRAIT:
+                if (DEBUG) appendLog("activity-requested-portrait");
+                orientation = SCREEN_ORIENTATION_PORTRAIT;
+                break;
+            default:
+                orientation = SCREEN_ORIENTATION_UNSPECIFIED;
+        }
+
+        return orientation;
+    }
+
+    private boolean isPreNResizeable(ActivityRecord root) {
+        return root.appInfo.targetSdkVersion < Build.VERSION_CODES.N && root.isResizeable();
+    }
+
+    private void cascadeBounds(@NonNull Rect srcBounds, @NonNull ActivityDisplay display,
+            @NonNull Rect outBounds) {
+        outBounds.set(srcBounds);
+        float density = (float) display.getConfiguration().densityDpi / DENSITY_DEFAULT;
+        final int defaultOffset = (int) (CASCADING_OFFSET_DP * density + 0.5f);
+
+        display.getBounds(mTmpBounds);
+        final int dx = Math.min(defaultOffset, Math.max(0, mTmpBounds.right - srcBounds.right));
+        final int dy = Math.min(defaultOffset, Math.max(0, mTmpBounds.bottom - srcBounds.bottom));
+        outBounds.offset(dx, dy);
+    }
+
+    private void getTaskBounds(@NonNull ActivityRecord root, @NonNull ActivityDisplay display,
+            @NonNull ActivityInfo.WindowLayout layout, int resolvedMode, boolean hasInitialBounds,
+            @NonNull Rect inOutBounds) {
+        if (resolvedMode == WINDOWING_MODE_FULLSCREEN) {
+            // We don't handle letterboxing here. Letterboxing will be handled by valid checks
+            // later.
+            inOutBounds.setEmpty();
+            if (DEBUG) appendLog("maximized-bounds");
+            return;
+        }
+
+        if (resolvedMode != WINDOWING_MODE_FREEFORM) {
+            // We don't apply freeform bounds adjustment to other windowing modes.
+            if (DEBUG) {
+                appendLog("skip-bounds-" + WindowConfiguration.windowingModeToString(resolvedMode));
+            }
+            return;
+        }
+
+        final int orientation = resolveOrientation(root, display, inOutBounds);
+        if (orientation != SCREEN_ORIENTATION_PORTRAIT
+                && orientation != SCREEN_ORIENTATION_LANDSCAPE) {
+            throw new IllegalStateException(
+                    "Orientation must be one of portrait or landscape, but it's "
+                    + ActivityInfo.screenOrientationToString(orientation));
+        }
+
+        // First we get the default size we want.
+        getDefaultFreeformSize(display, layout, orientation, mTmpBounds);
+        if (hasInitialBounds || sizeMatches(inOutBounds, mTmpBounds)) {
+            // We're here because either input parameters specified initial bounds, or the suggested
+            // bounds have the same size of the default freeform size. We should use the suggested
+            // bounds if possible -- so if app can handle the orientation we just use it, and if not
+            // we transpose the suggested bounds in-place.
+            if (orientation == orientationFromBounds(inOutBounds)) {
+                if (DEBUG) appendLog("freeform-size-orientation-match=" + inOutBounds);
+            } else {
+                // Meh, orientation doesn't match. Let's rotate inOutBounds in-place.
+                centerBounds(display, inOutBounds.height(), inOutBounds.width(), inOutBounds);
+                if (DEBUG) appendLog("freeform-orientation-mismatch=" + inOutBounds);
+            }
+        } else {
+            // We are here either because there is no suggested bounds, or the suggested bounds is
+            // a cascade from source activity. We should use the default freeform size and center it
+            // to the center of suggested bounds (or the display if no suggested bounds). The
+            // default size might be too big to center to source activity bounds in display, so we
+            // may need to move it back to the display.
+            centerBounds(display, mTmpBounds.width(), mTmpBounds.height(), inOutBounds);
+            adjustBoundsToFitInDisplay(display, inOutBounds);
+            if (DEBUG) appendLog("freeform-size-mismatch=" + inOutBounds);
+        }
+
+        // Lastly we adjust bounds to avoid conflicts with other tasks as much as possible.
+        adjustBoundsToAvoidConflict(display, inOutBounds);
+    }
+
+    private int resolveOrientation(@NonNull ActivityRecord root, @NonNull ActivityDisplay display,
+            @NonNull Rect bounds) {
+        int orientation = resolveOrientation(root);
+
+        if (orientation == SCREEN_ORIENTATION_LOCKED) {
+            orientation = bounds.isEmpty() ? display.getConfiguration().orientation
+                    : orientationFromBounds(bounds);
+            if (DEBUG) {
+                appendLog(bounds.isEmpty() ? "locked-orientation-from-display=" + orientation
+                        : "locked-orientation-from-bounds=" + bounds);
             }
         }
+
+        if (orientation == SCREEN_ORIENTATION_UNSPECIFIED) {
+            orientation = bounds.isEmpty() ? SCREEN_ORIENTATION_PORTRAIT
+                    : orientationFromBounds(bounds);
+            if (DEBUG) {
+                appendLog(bounds.isEmpty() ? "default-portrait"
+                        : "orientation-from-bounds=" + bounds);
+            }
+        }
+
+        return orientation;
+    }
+
+    private void getDefaultFreeformSize(@NonNull ActivityDisplay display,
+            @NonNull ActivityInfo.WindowLayout layout, int orientation, @NonNull Rect bounds) {
+        // Default size, which is letterboxing/pillarboxing in display. That's to say the large
+        // dimension of default size is the small dimension of display size, and the small dimension
+        // of default size is calculated to keep the same aspect ratio as the display's.
+        Rect displayBounds = display.getBounds();
+        final int portraitHeight = Math.min(displayBounds.width(), displayBounds.height());
+        final int otherDimension = Math.max(displayBounds.width(), displayBounds.height());
+        final int portraitWidth = (portraitHeight * portraitHeight) / otherDimension;
+        final int defaultWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitHeight
+                : portraitWidth;
+        final int defaultHeight = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? portraitWidth
+                : portraitHeight;
+
+        // Get window size based on Nexus 5x screen, we assume that this is enough to show content
+        // of activities.
+        final float density = (float) display.getConfiguration().densityDpi / DENSITY_DEFAULT;
+        final int phonePortraitWidth = (int) (DEFAULT_PORTRAIT_PHONE_WIDTH_DP * density + 0.5f);
+        final int phonePortraitHeight = (int) (DEFAULT_PORTRAIT_PHONE_HEIGHT_DP * density + 0.5f);
+        final int phoneWidth = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? phonePortraitHeight
+                : phonePortraitWidth;
+        final int phoneHeight = (orientation == SCREEN_ORIENTATION_LANDSCAPE) ? phonePortraitWidth
+                : phonePortraitHeight;
+
+        // Minimum layout requirements.
+        final int layoutMinWidth = (layout == null) ? -1 : layout.minWidth;
+        final int layoutMinHeight = (layout == null) ? -1 : layout.minHeight;
+
+        // Final result.
+        final int width = Math.min(defaultWidth, Math.max(phoneWidth, layoutMinWidth));
+        final int height = Math.min(defaultHeight, Math.max(phoneHeight, layoutMinHeight));
+
+        bounds.set(0, 0, width, height);
+    }
+
+    /**
+     * Gets centered bounds of width x height. If inOutBounds is not empty, the result bounds
+     * centers at its center or display's center if inOutBounds is empty.
+     */
+    private void centerBounds(@NonNull ActivityDisplay display, int width, int height,
+            @NonNull Rect inOutBounds) {
+        if (inOutBounds.isEmpty()) {
+            display.getBounds(inOutBounds);
+        }
+        final int left = inOutBounds.centerX() - width / 2;
+        final int top = inOutBounds.centerY() - height / 2;
+        inOutBounds.set(left, top, left + width, top + height);
+    }
+
+    private void adjustBoundsToFitInDisplay(@NonNull ActivityDisplay display,
+            @NonNull Rect inOutBounds) {
+        final Rect displayBounds = display.getBounds();
+
+        if (displayBounds.width() < inOutBounds.width()
+                || displayBounds.height() < inOutBounds.height()) {
+            // There is no way for us to fit the bounds in the display without changing width
+            // or height. Don't even try it.
+            return;
+        }
+
+        final int dx;
+        if (inOutBounds.right > displayBounds.right) {
+            // Right edge is out of display.
+            dx = displayBounds.right - inOutBounds.right;
+        } else if (inOutBounds.left < displayBounds.left) {
+            // Left edge is out of display.
+            dx = displayBounds.left - inOutBounds.left;
+        } else {
+            // Vertical edges are all in display.
+            dx = 0;
+        }
+
+        final int dy;
+        if (inOutBounds.top < displayBounds.top) {
+            // Top edge is out of display.
+            dy = displayBounds.top - inOutBounds.top;
+        } else if (inOutBounds.bottom > displayBounds.bottom) {
+            // Bottom edge is out of display.
+            dy = displayBounds.bottom - inOutBounds.bottom;
+        } else {
+            // Horizontal edges are all in display.
+            dy = 0;
+        }
+        inOutBounds.offset(dx, dy);
+    }
+
+    /**
+     * Adjusts input bounds to avoid conflict with existing tasks in the display.
+     *
+     * If the input bounds conflict with existing tasks, this method scans the bounds in a series of
+     * directions to find a location where the we can put the bounds in display without conflict
+     * with any other tasks.
+     *
+     * It doesn't try to adjust bounds that's not fully in the given display.
+     *
+     * @param display the display which tasks are to check
+     * @param inOutBounds the bounds used to input initial bounds and output result bounds
+     */
+    private void adjustBoundsToAvoidConflict(@NonNull ActivityDisplay display,
+            @NonNull Rect inOutBounds) {
+        final Rect displayBounds = display.getBounds();
+        if (!displayBounds.contains(inOutBounds)) {
+            // The initial bounds are already out of display. The scanning algorithm below doesn't
+            // work so well with them.
+            return;
+        }
+
+        final List<TaskRecord> tasksToCheck = new ArrayList<>();
+        for (int i = 0; i < display.getChildCount(); ++i) {
+            ActivityStack<?> stack = display.getChildAt(i);
+            if (!stack.inFreeformWindowingMode()) {
+                continue;
+            }
+
+            for (int j = 0; j < stack.getChildCount(); ++j) {
+                tasksToCheck.add(stack.getChildAt(j));
+            }
+        }
+
+        if (!boundsConflict(tasksToCheck, inOutBounds)) {
+            // Current proposal doesn't conflict with any task. Early return to avoid unnecessary
+            // calculation.
+            return;
+        }
+
+        calculateCandidateShiftDirections(displayBounds, inOutBounds);
+        for (int direction : mTmpDirections) {
+            if (direction == Gravity.NO_GRAVITY) {
+                // We exhausted candidate directions, give up.
+                break;
+            }
+
+            mTmpBounds.set(inOutBounds);
+            while (boundsConflict(tasksToCheck, mTmpBounds) && displayBounds.contains(mTmpBounds)) {
+                shiftBounds(direction, displayBounds, mTmpBounds);
+            }
+
+            if (!boundsConflict(tasksToCheck, mTmpBounds) && displayBounds.contains(mTmpBounds)) {
+                // Found a candidate. Just use this.
+                inOutBounds.set(mTmpBounds);
+                if (DEBUG) appendLog("avoid-bounds-conflict=" + inOutBounds);
+                return;
+            }
+
+            // Didn't find a conflict free bounds here. Try the next candidate direction.
+        }
+
+        // We failed to find a conflict free location. Just keep the original result.
+    }
+
+    /**
+     * Determines scanning directions and their priorities to avoid bounds conflict.
+     *
+     * @param availableBounds bounds that the result must be in
+     * @param initialBounds initial bounds when start scanning
+     */
+    private void calculateCandidateShiftDirections(@NonNull Rect availableBounds,
+            @NonNull Rect initialBounds) {
+        for (int i = 0; i < mTmpDirections.length; ++i) {
+            mTmpDirections[i] = Gravity.NO_GRAVITY;
+        }
+
+        final int oneThirdWidth = (2 * availableBounds.left + availableBounds.right) / 3;
+        final int twoThirdWidth = (availableBounds.left + 2 * availableBounds.right) / 3;
+        final int centerX = initialBounds.centerX();
+        if (centerX < oneThirdWidth) {
+            // Too close to left, just scan to the right.
+            mTmpDirections[0] = Gravity.RIGHT;
+            return;
+        } else if (centerX > twoThirdWidth) {
+            // Too close to right, just scan to the left.
+            mTmpDirections[0] = Gravity.LEFT;
+            return;
+        }
+
+        final int oneThirdHeight = (2 * availableBounds.top + availableBounds.bottom) / 3;
+        final int twoThirdHeight = (availableBounds.top + 2 * availableBounds.bottom) / 3;
+        final int centerY = initialBounds.centerY();
+        if (centerY < oneThirdHeight || centerY > twoThirdHeight) {
+            // Too close to top or bottom boundary and we're in the middle horizontally, scan
+            // horizontally in both directions.
+            mTmpDirections[0] = Gravity.RIGHT;
+            mTmpDirections[1] = Gravity.LEFT;
+            return;
+        }
+
+        // We're in the center region both horizontally and vertically. Scan in both directions of
+        // primary diagonal.
+        mTmpDirections[0] = Gravity.BOTTOM | Gravity.RIGHT;
+        mTmpDirections[1] = Gravity.TOP | Gravity.LEFT;
+    }
+
+    private boolean boundsConflict(@NonNull List<TaskRecord> tasks, @NonNull Rect bounds) {
+        for (TaskRecord task : tasks) {
+            final Rect taskBounds = task.getBounds();
+            final boolean leftClose = Math.abs(taskBounds.left - bounds.left)
+                    < BOUNDS_CONFLICT_THRESHOLD;
+            final boolean topClose = Math.abs(taskBounds.top - bounds.top)
+                    < BOUNDS_CONFLICT_THRESHOLD;
+            final boolean rightClose = Math.abs(taskBounds.right - bounds.right)
+                    < BOUNDS_CONFLICT_THRESHOLD;
+            final boolean bottomClose = Math.abs(taskBounds.bottom - bounds.bottom)
+                    < BOUNDS_CONFLICT_THRESHOLD;
+
+            if ((leftClose && topClose) || (leftClose && bottomClose) || (rightClose && topClose)
+                    || (rightClose && bottomClose)) {
+                return true;
+            }
+        }
+
         return false;
     }
 
-    private static final boolean closeLeftTopCorner(Rect first, Rect second) {
-        return Math.abs(first.left - second.left) < BOUNDS_CONFLICT_MIN_DISTANCE
-                && Math.abs(first.top - second.top) < BOUNDS_CONFLICT_MIN_DISTANCE;
+    private void shiftBounds(int direction, @NonNull Rect availableRect,
+            @NonNull Rect inOutBounds) {
+        final int horizontalOffset;
+        switch (direction & Gravity.HORIZONTAL_GRAVITY_MASK) {
+            case Gravity.LEFT:
+                horizontalOffset = -Math.max(MINIMAL_STEP,
+                        availableRect.width() / STEP_DENOMINATOR);
+                break;
+            case Gravity.RIGHT:
+                horizontalOffset = Math.max(MINIMAL_STEP, availableRect.width() / STEP_DENOMINATOR);
+                break;
+            default:
+                horizontalOffset = 0;
+        }
+
+        final int verticalOffset;
+        switch (direction & Gravity.VERTICAL_GRAVITY_MASK) {
+            case Gravity.TOP:
+                verticalOffset = -Math.max(MINIMAL_STEP, availableRect.height() / STEP_DENOMINATOR);
+                break;
+            case Gravity.BOTTOM:
+                verticalOffset = Math.max(MINIMAL_STEP, availableRect.height() / STEP_DENOMINATOR);
+                break;
+            default:
+                verticalOffset = 0;
+        }
+
+        inOutBounds.offset(horizontalOffset, verticalOffset);
     }
 
-    private static final boolean closeRightTopCorner(Rect first, Rect second) {
-        return Math.abs(first.right - second.right) < BOUNDS_CONFLICT_MIN_DISTANCE
-                && Math.abs(first.top - second.top) < BOUNDS_CONFLICT_MIN_DISTANCE;
+    private void initLogBuilder(TaskRecord task, ActivityRecord activity) {
+        if (DEBUG) {
+            mLogBuilder = new StringBuilder("TaskLaunchParamsModifier:task=" + task
+                    + " activity=" + activity);
+        }
     }
 
-    private static final boolean closeLeftBottomCorner(Rect first, Rect second) {
-        return Math.abs(first.left - second.left) < BOUNDS_CONFLICT_MIN_DISTANCE
-                && Math.abs(first.bottom - second.bottom) < BOUNDS_CONFLICT_MIN_DISTANCE;
+    private void appendLog(String log) {
+        if (DEBUG) mLogBuilder.append(" ").append(log);
     }
 
-    private static final boolean closeRightBottomCorner(Rect first, Rect second) {
-        return Math.abs(first.right - second.right) < BOUNDS_CONFLICT_MIN_DISTANCE
-                && Math.abs(first.bottom - second.bottom) < BOUNDS_CONFLICT_MIN_DISTANCE;
+    private void outputLog() {
+        if (DEBUG) Slog.d(TAG, mLogBuilder.toString());
+    }
+
+    private static int orientationFromBounds(Rect bounds) {
+        return bounds.width() > bounds.height() ? SCREEN_ORIENTATION_LANDSCAPE
+                : SCREEN_ORIENTATION_PORTRAIT;
+    }
+
+    private static boolean sizeMatches(Rect left, Rect right) {
+        return (Math.abs(right.width() - left.width()) < EPSILON)
+                && (Math.abs(right.height() - left.height()) < EPSILON);
     }
 }
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 481bb2b..fc5dfb4 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -16,13 +16,14 @@
 
 package com.android.server.am;
 
+import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
+
 import android.annotation.NonNull;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Debug;
 import android.os.Environment;
 import android.os.FileUtils;
-import android.os.Process;
 import android.os.SystemClock;
 import android.util.ArraySet;
 import android.util.AtomicFile;
@@ -34,6 +35,7 @@
 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;
@@ -54,32 +56,18 @@
 import java.util.Comparator;
 import java.util.List;
 
-import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS;
-
-public class TaskPersister {
+/**
+ * Persister that saves recent tasks into disk.
+ */
+public class TaskPersister implements PersisterQueue.Listener {
     static final String TAG = "TaskPersister";
     static final boolean DEBUG = false;
-
-    /** When not flushing don't write out files faster than this */
-    private static final long INTER_WRITE_DELAY_MS = 500;
-
-    /**
-     * When not flushing delay this long before writing the first file out. This gives the next task
-     * being launched a chance to load its resources without this occupying IO bandwidth.
-     */
-    private static final long PRE_TASK_DELAY_MS = 3000;
-
-    /** The maximum number of entries to keep in the queue before draining it automatically. */
-    private static final int MAX_WRITE_QUEUE_LENGTH = 6;
-
-    /** Special value for mWriteTime to mean don't wait, just write */
-    private static final long FLUSH_QUEUE = -1;
+    static final String IMAGE_EXTENSION = ".png";
 
     private static final String TASKS_DIRNAME = "recent_tasks";
     private static final String TASK_FILENAME_SUFFIX = "_task.xml";
     private static final String IMAGES_DIRNAME = "recent_images";
     private static final String PERSISTED_TASK_IDS_FILENAME = "persisted_taskIds.txt";
-    static final String IMAGE_EXTENSION = ".png";
 
     private static final String TAG_TASK = "task";
 
@@ -90,39 +78,9 @@
     private final File mTaskIdsDir;
     // To lock file operations in TaskPersister
     private final Object mIoLock = new Object();
+    private final PersisterQueue mPersisterQueue;
 
-    /**
-     * Value determines write delay mode as follows: < 0 We are Flushing. No delays between writes
-     * until the image queue is drained and all tasks needing persisting are written to disk. There
-     * is no delay between writes. == 0 We are Idle. Next writes will be delayed by
-     * #PRE_TASK_DELAY_MS. > 0 We are Actively writing. Next write will be at this time. Subsequent
-     * writes will be delayed by #INTER_WRITE_DELAY_MS.
-     */
-    private long mNextWriteTime = 0;
-
-    private final LazyTaskWriterThread mLazyTaskWriterThread;
-
-    private static class WriteQueueItem {}
-
-    private static class TaskWriteQueueItem extends WriteQueueItem {
-        final TaskRecord mTask;
-
-        TaskWriteQueueItem(TaskRecord task) {
-            mTask = task;
-        }
-    }
-
-    private static class ImageWriteQueueItem extends WriteQueueItem {
-        final String mFilePath;
-        Bitmap mImage;
-
-        ImageWriteQueueItem(String filePath, Bitmap image) {
-            mFilePath = filePath;
-            mImage = image;
-        }
-    }
-
-    ArrayList<WriteQueueItem> mWriteQueue = new ArrayList<WriteQueueItem>();
+    private final ArraySet<Integer> mTmpTaskIds = new ArraySet<>();
 
     TaskPersister(File systemDir, ActivityStackSupervisor stackSupervisor,
             ActivityTaskManagerService service, RecentTasks recentTasks) {
@@ -145,7 +103,8 @@
         mStackSupervisor = stackSupervisor;
         mService = service;
         mRecentTasks = recentTasks;
-        mLazyTaskWriterThread = new LazyTaskWriterThread("LazyTaskWriterThread");
+        mPersisterQueue = new PersisterQueue();
+        mPersisterQueue.addListener(this);
     }
 
     @VisibleForTesting
@@ -154,42 +113,21 @@
         mStackSupervisor = null;
         mService = null;
         mRecentTasks = null;
-        mLazyTaskWriterThread = new LazyTaskWriterThread("LazyTaskWriterThreadTest");
+        mPersisterQueue = new PersisterQueue();
+        mPersisterQueue.addListener(this);
     }
 
-    void startPersisting() {
-        if (!mLazyTaskWriterThread.isAlive()) {
-            mLazyTaskWriterThread.start();
-        }
+    void onSystemReady() {
+        mPersisterQueue.startPersisting();
     }
 
     private void removeThumbnails(TaskRecord task) {
-        final String taskString = Integer.toString(task.taskId);
-        for (int queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
-            final WriteQueueItem item = mWriteQueue.get(queueNdx);
-            if (item instanceof ImageWriteQueueItem) {
-                final File thumbnailFile = new File(((ImageWriteQueueItem) item).mFilePath);
-                if (thumbnailFile.getName().startsWith(taskString)) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "Removing " + ((ImageWriteQueueItem) item).mFilePath +
-                                " from write queue");
-                    }
-                    mWriteQueue.remove(queueNdx);
-                }
-            }
-        }
-    }
-
-    private void yieldIfQueueTooDeep() {
-        boolean stall = false;
-        synchronized (this) {
-            if (mNextWriteTime == FLUSH_QUEUE) {
-                stall = true;
-            }
-        }
-        if (stall) {
-            Thread.yield();
-        }
+        mPersisterQueue.removeItems(
+                item -> {
+                    File file = new File(item.mFilePath);
+                    return file.getName().startsWith(Integer.toString(task.taskId));
+                },
+                ImageWriteQueueItem.class);
     }
 
     @NonNull
@@ -251,84 +189,51 @@
     }
 
     void wakeup(TaskRecord task, boolean flush) {
-        synchronized (this) {
+        synchronized (mPersisterQueue) {
             if (task != null) {
-                int queueNdx;
-                for (queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
-                    final WriteQueueItem item = mWriteQueue.get(queueNdx);
-                    if (item instanceof TaskWriteQueueItem &&
-                            ((TaskWriteQueueItem) item).mTask == task) {
-                        if (!task.inRecents) {
-                            // This task is being removed.
-                            removeThumbnails(task);
-                        }
-                        break;
-                    }
+                final TaskWriteQueueItem item = mPersisterQueue.findLastItem(
+                        queueItem -> task == queueItem.mTask, TaskWriteQueueItem.class);
+                if (item != null && !task.inRecents) {
+                    removeThumbnails(task);
                 }
-                if (queueNdx < 0 && task.isPersistable) {
-                    mWriteQueue.add(new TaskWriteQueueItem(task));
+
+                if (item == null && task.isPersistable) {
+                    mPersisterQueue.addItem(new TaskWriteQueueItem(task, mService), flush);
                 }
             } else {
                 // Dummy. Ensures removeObsoleteFiles is called when LazyTaskThreadWriter is
                 // notified.
-                mWriteQueue.add(new WriteQueueItem());
+                mPersisterQueue.addItem(PersisterQueue.EMPTY_ITEM, flush);
             }
-            if (flush || mWriteQueue.size() > MAX_WRITE_QUEUE_LENGTH) {
-                mNextWriteTime = FLUSH_QUEUE;
-            } else if (mNextWriteTime == 0) {
-                mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
+            if (DEBUG) {
+                Slog.d(TAG, "wakeup: task=" + task + " flush=" + flush + " Callers="
+                        + Debug.getCallers(4));
             }
-            if (DEBUG) Slog.d(TAG, "wakeup: task=" + task + " flush=" + flush + " mNextWriteTime="
-                    + mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size()
-                    + " Callers=" + Debug.getCallers(4));
-            notifyAll();
         }
 
-        yieldIfQueueTooDeep();
+        mPersisterQueue.yieldIfQueueTooDeep();
     }
 
     void flush() {
-        synchronized (this) {
-            mNextWriteTime = FLUSH_QUEUE;
-            notifyAll();
-            do {
-                try {
-                    wait();
-                } catch (InterruptedException e) {
-                }
-            } while (mNextWriteTime == FLUSH_QUEUE);
-        }
+        mPersisterQueue.flush();
     }
 
     void saveImage(Bitmap image, String filePath) {
-        synchronized (this) {
-            int queueNdx;
-            for (queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
-                final WriteQueueItem item = mWriteQueue.get(queueNdx);
-                if (item instanceof ImageWriteQueueItem) {
-                    ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
-                    if (imageWriteQueueItem.mFilePath.equals(filePath)) {
-                        // replace the Bitmap with the new one.
-                        imageWriteQueueItem.mImage = image;
-                        break;
-                    }
-                }
-            }
-            if (queueNdx < 0) {
-                mWriteQueue.add(new ImageWriteQueueItem(filePath, image));
-            }
-            if (mWriteQueue.size() > MAX_WRITE_QUEUE_LENGTH) {
-                mNextWriteTime = FLUSH_QUEUE;
-            } else if (mNextWriteTime == 0) {
-                mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
+        synchronized (mPersisterQueue) {
+            final ImageWriteQueueItem item = mPersisterQueue.findLastItem(
+                    queueItem -> queueItem.mFilePath.equals(filePath), ImageWriteQueueItem.class);
+            if (item != null) {
+                // replace the Bitmap with the new one.
+                item.mImage = image;
+            } else {
+                mPersisterQueue.addItem(new ImageWriteQueueItem(filePath, image),
+                        /* flush */ false);
             }
             if (DEBUG) Slog.d(TAG, "saveImage: filePath=" + filePath + " now=" +
-                    SystemClock.uptimeMillis() + " mNextWriteTime=" +
-                    mNextWriteTime + " Callers=" + Debug.getCallers(4));
-            notifyAll();
+                    SystemClock.uptimeMillis() + " Callers=" + Debug.getCallers(4));
         }
 
-        yieldIfQueueTooDeep();
+        mPersisterQueue.yieldIfQueueTooDeep();
     }
 
     Bitmap getTaskDescriptionIcon(String filePath) {
@@ -340,41 +245,10 @@
         return restoreImage(filePath);
     }
 
-    Bitmap getImageFromWriteQueue(String filePath) {
-        synchronized (this) {
-            for (int queueNdx = mWriteQueue.size() - 1; queueNdx >= 0; --queueNdx) {
-                final WriteQueueItem item = mWriteQueue.get(queueNdx);
-                if (item instanceof ImageWriteQueueItem) {
-                    ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
-                    if (imageWriteQueueItem.mFilePath.equals(filePath)) {
-                        return imageWriteQueueItem.mImage;
-                    }
-                }
-            }
-            return null;
-        }
-    }
-
-    private StringWriter saveToXml(TaskRecord task) throws IOException, XmlPullParserException {
-        if (DEBUG) Slog.d(TAG, "saveToXml: task=" + task);
-        final XmlSerializer xmlSerializer = new FastXmlSerializer();
-        StringWriter stringWriter = new StringWriter();
-        xmlSerializer.setOutput(stringWriter);
-
-        if (DEBUG) xmlSerializer.setFeature(
-                "http://xmlpull.org/v1/doc/features.html#indent-output", true);
-
-        // save task
-        xmlSerializer.startDocument(null, true);
-
-        xmlSerializer.startTag(null, TAG_TASK);
-        task.saveToXml(xmlSerializer);
-        xmlSerializer.endTag(null, TAG_TASK);
-
-        xmlSerializer.endDocument();
-        xmlSerializer.flush();
-
-        return stringWriter;
+    private Bitmap getImageFromWriteQueue(String filePath) {
+        final ImageWriteQueueItem item = mPersisterQueue.findLastItem(
+                queueItem -> queueItem.mFilePath.equals(filePath), ImageWriteQueueItem.class);
+        return item != null ? item.mImage : null;
     }
 
     private String fileToString(File file) {
@@ -534,6 +408,26 @@
         return tasks;
     }
 
+    @Override
+    public void onPreProcessItem(boolean queueEmpty) {
+        // We can't lock mService while locking the queue, but we don't want to
+        // call removeObsoleteFiles before every item, only the last time
+        // before going to sleep. The risk is that we call removeObsoleteFiles()
+        // successively.
+        if (queueEmpty) {
+            if (DEBUG) Slog.d(TAG, "Looking for obsolete files.");
+            mTmpTaskIds.clear();
+            synchronized (mService.mGlobalLock) {
+                if (DEBUG) Slog.d(TAG, "mRecents=" + mRecentTasks);
+                mRecentTasks.getPersistableTaskIds(mTmpTaskIds);
+                mService.mWindowManager.removeObsoleteTaskFiles(mTmpTaskIds,
+                        mRecentTasks.usersWithRecentsLoadedLocked());
+            }
+            removeObsoleteFiles(mTmpTaskIds);
+        }
+        writeTaskIdsFiles();
+    }
+
     private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) {
         if (DEBUG) Slog.d(TAG, "removeObsoleteFiles: persistentTaskIds=" + persistentTaskIds +
                 " files=" + files);
@@ -631,143 +525,117 @@
         return parentDir.exists() || parentDir.mkdirs();
     }
 
-    private class LazyTaskWriterThread extends Thread {
+    private static class TaskWriteQueueItem implements PersisterQueue.WriteQueueItem {
+        private final ActivityTaskManagerService mService;
+        private final TaskRecord mTask;
 
-        LazyTaskWriterThread(String name) {
-            super(name);
+        TaskWriteQueueItem(TaskRecord task, ActivityTaskManagerService service) {
+            mTask = task;
+            mService = service;
+        }
+
+        private StringWriter saveToXml(TaskRecord task) throws IOException, XmlPullParserException {
+            if (DEBUG) Slog.d(TAG, "saveToXml: task=" + task);
+            final XmlSerializer xmlSerializer = new FastXmlSerializer();
+            StringWriter stringWriter = new StringWriter();
+            xmlSerializer.setOutput(stringWriter);
+
+            if (DEBUG) {
+                xmlSerializer.setFeature(
+                        "http://xmlpull.org/v1/doc/features.html#indent-output", true);
+            }
+
+            // save task
+            xmlSerializer.startDocument(null, true);
+
+            xmlSerializer.startTag(null, TAG_TASK);
+            task.saveToXml(xmlSerializer);
+            xmlSerializer.endTag(null, TAG_TASK);
+
+            xmlSerializer.endDocument();
+            xmlSerializer.flush();
+
+            return stringWriter;
         }
 
         @Override
-        public void run() {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-            ArraySet<Integer> persistentTaskIds = new ArraySet<>();
-            while (true) {
-                // We can't lock mService while holding TaskPersister.this, but we don't want to
-                // call removeObsoleteFiles every time through the loop, only the last time before
-                // going to sleep. The risk is that we call removeObsoleteFiles() successively.
-                final boolean probablyDone;
-                synchronized (TaskPersister.this) {
-                    probablyDone = mWriteQueue.isEmpty();
-                }
-                if (probablyDone) {
-                    if (DEBUG) Slog.d(TAG, "Looking for obsolete files.");
-                    persistentTaskIds.clear();
-                    synchronized (mService.mGlobalLock) {
-                        if (DEBUG) Slog.d(TAG, "mRecents=" + mRecentTasks);
-                        mRecentTasks.getPersistableTaskIds(persistentTaskIds);
-                        mService.mWindowManager.removeObsoleteTaskFiles(persistentTaskIds,
-                                mRecentTasks.usersWithRecentsLoadedLocked());
+        public void process() {
+            // Write out one task.
+            StringWriter stringWriter = null;
+            TaskRecord task = mTask;
+            if (DEBUG) Slog.d(TAG, "Writing task=" + task);
+            synchronized (mService.mGlobalLock) {
+                if (task.inRecents) {
+                    // Still there.
+                    try {
+                        if (DEBUG) Slog.d(TAG, "Saving task=" + task);
+                        stringWriter = saveToXml(task);
+                    } catch (IOException e) {
+                    } catch (XmlPullParserException e) {
                     }
-                    removeObsoleteFiles(persistentTaskIds);
                 }
-                writeTaskIdsFiles();
-
-                processNextItem();
+            }
+            if (stringWriter != null) {
+                // Write out xml file while not holding mService lock.
+                FileOutputStream file = null;
+                AtomicFile atomicFile = null;
+                try {
+                    atomicFile = new AtomicFile(new File(
+                            getUserTasksDir(task.userId),
+                            String.valueOf(task.taskId) + TASK_FILENAME_SUFFIX));
+                    file = atomicFile.startWrite();
+                    file.write(stringWriter.toString().getBytes());
+                    file.write('\n');
+                    atomicFile.finishWrite(file);
+                } catch (IOException e) {
+                    if (file != null) {
+                        atomicFile.failWrite(file);
+                    }
+                    Slog.e(TAG,
+                            "Unable to open " + atomicFile + " for persisting. " + e);
+                }
             }
         }
 
-        private void processNextItem() {
-            // This part is extracted into a method so that the GC can clearly see the end of the
-            // scope of the variable 'item'.  If this part was in the loop above, the last item
-            // it processed would always "leak".
-            // See https://b.corp.google.com/issues/64438652#comment7
+        @Override
+        public String toString() {
+            return "TaskWriteQueueItem{task=" + mTask + "}";
+        }
+    }
 
-            // If mNextWriteTime, then don't delay between each call to saveToXml().
-            final WriteQueueItem item;
-            synchronized (TaskPersister.this) {
-                if (mNextWriteTime != FLUSH_QUEUE) {
-                    // The next write we don't have to wait so long.
-                    mNextWriteTime = SystemClock.uptimeMillis() + INTER_WRITE_DELAY_MS;
-                    if (DEBUG) Slog.d(TAG, "Next write time may be in " +
-                            INTER_WRITE_DELAY_MS + " msec. (" + mNextWriteTime + ")");
-                }
+    private static class ImageWriteQueueItem implements PersisterQueue.WriteQueueItem {
+        final String mFilePath;
+        Bitmap mImage;
 
-                while (mWriteQueue.isEmpty()) {
-                    if (mNextWriteTime != 0) {
-                        mNextWriteTime = 0; // idle.
-                        TaskPersister.this.notifyAll(); // wake up flush() if needed.
-                    }
-                    try {
-                        if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
-                        TaskPersister.this.wait();
-                    } catch (InterruptedException e) {
-                    }
-                    // Invariant: mNextWriteTime is either FLUSH_QUEUE or PRE_WRITE_DELAY_MS
-                    // from now.
-                }
-                item = mWriteQueue.remove(0);
+        ImageWriteQueueItem(String filePath, Bitmap image) {
+            mFilePath = filePath;
+            mImage = image;
+        }
 
-                long now = SystemClock.uptimeMillis();
-                if (DEBUG) Slog.d(TAG, "LazyTaskWriter: now=" + now + " mNextWriteTime=" +
-                        mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size());
-                while (now < mNextWriteTime) {
-                    try {
-                        if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting " +
-                                (mNextWriteTime - now));
-                        TaskPersister.this.wait(mNextWriteTime - now);
-                    } catch (InterruptedException e) {
-                    }
-                    now = SystemClock.uptimeMillis();
-                }
-
-                // Got something to do.
+        @Override
+        public void process() {
+            final String filePath = mFilePath;
+            if (!createParentDirectory(filePath)) {
+                Slog.e(TAG, "Error while creating images directory for file: " + filePath);
+                return;
             }
-
-            if (item instanceof ImageWriteQueueItem) {
-                ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
-                final String filePath = imageWriteQueueItem.mFilePath;
-                if (!createParentDirectory(filePath)) {
-                    Slog.e(TAG, "Error while creating images directory for file: " + filePath);
-                    return;
-                }
-                final Bitmap bitmap = imageWriteQueueItem.mImage;
-                if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filePath);
-                FileOutputStream imageFile = null;
-                try {
-                    imageFile = new FileOutputStream(new File(filePath));
-                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, imageFile);
-                } catch (Exception e) {
-                    Slog.e(TAG, "saveImage: unable to save " + filePath, e);
-                } finally {
-                    IoUtils.closeQuietly(imageFile);
-                }
-            } else if (item instanceof TaskWriteQueueItem) {
-                // Write out one task.
-                StringWriter stringWriter = null;
-                TaskRecord task = ((TaskWriteQueueItem) item).mTask;
-                if (DEBUG) Slog.d(TAG, "Writing task=" + task);
-                synchronized (mService.mGlobalLock) {
-                    if (task.inRecents) {
-                        // Still there.
-                        try {
-                            if (DEBUG) Slog.d(TAG, "Saving task=" + task);
-                            stringWriter = saveToXml(task);
-                        } catch (IOException e) {
-                        } catch (XmlPullParserException e) {
-                        }
-                    }
-                }
-                if (stringWriter != null) {
-                    // Write out xml file while not holding mService lock.
-                    FileOutputStream file = null;
-                    AtomicFile atomicFile = null;
-                    try {
-                        atomicFile = new AtomicFile(new File(
-                                getUserTasksDir(task.userId),
-                                String.valueOf(task.taskId) + TASK_FILENAME_SUFFIX));
-                        file = atomicFile.startWrite();
-                        file.write(stringWriter.toString().getBytes());
-                        file.write('\n');
-                        atomicFile.finishWrite(file);
-                    } catch (IOException e) {
-                        if (file != null) {
-                            atomicFile.failWrite(file);
-                        }
-                        Slog.e(TAG,
-                                "Unable to open " + atomicFile + " for persisting. " + e);
-                    }
-                }
+            final Bitmap bitmap = mImage;
+            if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filePath);
+            FileOutputStream imageFile = null;
+            try {
+                imageFile = new FileOutputStream(new File(filePath));
+                bitmap.compress(Bitmap.CompressFormat.PNG, 100, imageFile);
+            } catch (Exception e) {
+                Slog.e(TAG, "saveImage: unable to save " + filePath, e);
+            } finally {
+                IoUtils.closeQuietly(imageFile);
             }
         }
+
+        @Override
+        public String toString() {
+            return "ImageWriteQueueItem{path=" + mFilePath
+                    + ", image=(" + mImage.getWidth() + "x" + mImage.getHeight() + ")}";
+        }
     }
 }
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index ef8cb1c..5f59163 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -17,6 +17,7 @@
 package com.android.server.am;
 
 import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
 import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -45,17 +46,16 @@
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
 import static android.view.Display.DEFAULT_DISPLAY;
-
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_ADD_REMOVE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_TASKS;
-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.ActivityTaskManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_LOCKTASK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RECENTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_ADD_REMOVE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_LOCKTASK;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_RECENTS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_TASKS;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
@@ -75,7 +75,6 @@
 import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
 import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
 import static com.android.server.am.TaskRecordProto.STACK_ID;
-
 import static java.lang.Integer.MAX_VALUE;
 
 import android.annotation.IntDef;
@@ -131,7 +130,7 @@
 
 // TODO: Make package private again once move to WM package is complete.
 public class TaskRecord extends ConfigurationContainer implements TaskWindowContainerListener {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_AM;
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_ATM;
     private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
@@ -174,7 +173,6 @@
     // code.
     private static final int PERSIST_TASK_VERSION = 1;
 
-    static final int INVALID_TASK_ID = -1;
     private static final int INVALID_MIN_SIZE = -1;
 
     /**
@@ -1686,11 +1684,19 @@
         // so that the user can not render the task too small to manipulate. We don't need
         // to do this for the pinned stack as the bounds are controlled by the system.
         if (!inPinnedWindowingMode()) {
+            final int defaultMinSizeDp =
+                    mService.mStackSupervisor.mDefaultMinSizeOfResizeableTaskDp;
+            final ActivityDisplay display =
+                    mService.mStackSupervisor.getActivityDisplay(mStack.mDisplayId);
+            final float density =
+                    (float) display.getConfiguration().densityDpi / DisplayMetrics.DENSITY_DEFAULT;
+            final int defaultMinSize = (int) (defaultMinSizeDp * density);
+
             if (minWidth == INVALID_MIN_SIZE) {
-                minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
+                minWidth = defaultMinSize;
             }
             if (minHeight == INVALID_MIN_SIZE) {
-                minHeight = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask;
+                minHeight = defaultMinSize;
             }
         }
         final boolean adjustWidth = minWidth > bounds.width();
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 3b859ed..6cb1097 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -18,7 +18,6 @@
 
 import android.Manifest;
 import android.app.ActivityManager;
-import android.app.ActivityManagerProto;
 import android.content.pm.PackageManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -27,14 +26,14 @@
 import android.util.proto.ProtoUtils;
 
 import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.wm.ActivityTaskManagerInternal;
 
 /**
  * Overall information about a uid that has actively running processes.
  */
 public final class UidRecord {
     final int uid;
-    int curProcState;
+    private int mCurProcState;
     int setProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
     long lastBackgroundTime;
     boolean ephemeral;
@@ -44,11 +43,12 @@
     boolean idle;
     boolean setIdle;
     int numProcs;
+    final ActivityTaskManagerInternal mAtmInternal;
 
     /**
-     * Sequence number associated with the {@link #curProcState}. This is incremented using
+     * Sequence number associated with the {@link #mCurProcState}. This is incremented using
      * {@link ActivityManagerService#mProcStateSeqCounter}
-     * when {@link #curProcState} changes from background to foreground or vice versa.
+     * when {@link #mCurProcState} changes from background to foreground or vice versa.
      */
     @GuardedBy("networkStateUpdate")
     long curProcStateSeq;
@@ -117,14 +117,26 @@
     ChangeItem pendingChange;
     int lastReportedChange;
 
-    public UidRecord(int _uid) {
+    public UidRecord(int _uid, ActivityTaskManagerInternal atmInternal) {
         uid = _uid;
         idle = true;
+        mAtmInternal = atmInternal;
         reset();
     }
 
+    public int getCurProcState() {
+        return mCurProcState;
+    }
+
+    public void setCurProcState(int curProcState) {
+        mCurProcState = curProcState;
+        if (mAtmInternal != null) {
+            mAtmInternal.onUidProcStateChanged(uid, curProcState);
+        }
+    }
+
     public void reset() {
-        curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+        setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY);
         foregroundServices = false;
     }
 
@@ -148,7 +160,7 @@
     void writeToProto(ProtoOutputStream proto, long fieldId) {
         long token = proto.start(fieldId);
         proto.write(UidRecordProto.UID, uid);
-        proto.write(UidRecordProto.CURRENT, ProcessList.makeProcStateProtoEnum(curProcState));
+        proto.write(UidRecordProto.CURRENT, ProcessList.makeProcStateProtoEnum(mCurProcState));
         proto.write(UidRecordProto.EPHEMERAL, ephemeral);
         proto.write(UidRecordProto.FG_SERVICES, foregroundServices);
         proto.write(UidRecordProto.WHILELIST, curWhitelist);
@@ -178,7 +190,7 @@
         sb.append(' ');
         UserHandle.formatUid(sb, uid);
         sb.append(' ');
-        sb.append(ProcessList.makeProcStateString(curProcState));
+        sb.append(ProcessList.makeProcStateString(mCurProcState));
         if (ephemeral) {
             sb.append(" ephemeral");
         }
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 8154062..d2dd3db 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -2178,9 +2178,7 @@
         }
 
         protected void startHomeActivity(int userId, String reason) {
-            synchronized (mService) {
-                mService.startHomeActivityLocked(userId, reason);
-            }
+            mService.mAtmInternal.startHomeActivity(userId, reason);
         }
 
         void startUserWidgets(int userId) {
@@ -2244,21 +2242,15 @@
         }
 
         void stackSupervisorRemoveUser(int userId) {
-            synchronized (mService) {
-                mService.mStackSupervisor.removeUserLocked(userId);
-            }
+            mService.mAtmInternal.removeUser(userId);
         }
 
         protected boolean stackSupervisorSwitchUser(int userId, UserState uss) {
-            synchronized (mService) {
-                return mService.mStackSupervisor.switchUserLocked(userId, uss);
-            }
+            return mService.mAtmInternal.switchUser(userId, uss);
         }
 
         protected void stackSupervisorResumeFocusedStackTopActivity() {
-            synchronized (mService) {
-                mService.mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
-            }
+            mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
         }
 
         protected void clearAllLockedTasks(String reason) {
diff --git a/services/core/java/com/android/server/am/VrController.java b/services/core/java/com/android/server/am/VrController.java
index 366f95a..51d86d6 100644
--- a/services/core/java/com/android/server/am/VrController.java
+++ b/services/core/java/com/android/server/am/VrController.java
@@ -248,9 +248,9 @@
      *
      * @param tid the tid of the thread to set, or 0 to unset the current thread.
      * @param pid the pid of the process owning the thread to set.
-     * @param proc the ProcessRecord of the process owning the thread to set.
+     * @param proc the process owning the thread to set.
      */
-    public void setPersistentVrThreadLocked(int tid, int pid, ProcessRecord proc) {
+    public void setPersistentVrThreadLocked(int tid, int pid, WindowProcessController proc) {
         if (!hasPersistentVrFlagSet()) {
             Slog.w(TAG, "Persistent VR thread may only be set in persistent VR mode!");
             return;
diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java
index f6f4db6..94f1002 100644
--- a/services/core/java/com/android/server/am/WindowProcessController.java
+++ b/services/core/java/com/android/server/am/WindowProcessController.java
@@ -17,23 +17,29 @@
 package com.android.server.am;
 
 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.view.Display.INVALID_DISPLAY;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RELEASE;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
-import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RELEASE;
-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.ActivityStack.ActivityState.DESTROYED;
 import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_RELEASE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_CONFIGURATION;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_RELEASE;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityTaskManagerService
+        .INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS;
+import static com.android.server.am.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
+import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
 
 import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.IApplicationThread;
+import android.app.ProfilerInfo;
 import android.app.servertransaction.ConfigurationChangeItem;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -43,10 +49,12 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.app.HeavyWeightSwitcherActivity;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.wm.ConfigurationContainer;
+import com.android.server.wm.ConfigurationContainerListener;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -62,8 +70,9 @@
  * window manager so the window manager lock is held and appropriate permissions are checked before
  * calls are allowed to proceed.
  */
-public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer> {
-    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_AM;
+public class WindowProcessController extends ConfigurationContainer<ConfigurationContainer>
+        implements ConfigurationContainerListener {
+    private static final String TAG = TAG_WITH_CLASS_NAME ? "WindowProcessController" : TAG_ATM;
     private static final String TAG_RELEASE = TAG + POSTFIX_RELEASE;
     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
 
@@ -87,6 +96,8 @@
     private volatile IApplicationThread mThread;
     // Currently desired scheduling class
     private volatile int mCurSchedGroup;
+    // Currently computed process state
+    private volatile int mCurProcState = PROCESS_STATE_NONEXISTENT;
     // Last reported process state;
     private volatile int mRepProcState = PROCESS_STATE_NONEXISTENT;
     // are we in the process of crashing?
@@ -99,10 +110,34 @@
     private volatile String mRequiredAbi;
     // Running any services that are foreground?
     private volatile boolean mHasForegroundServices;
+    // Running any activities that are foreground?
+    private volatile boolean mHasForegroundActivities;
+    // Are there any client services with activities?
+    private volatile boolean mHasClientActivities;
+    // Is this process currently showing a non-activity UI that the user is interacting with?
+    // E.g. The status bar when it is expanded, but not when it is minimized. When true the process
+    // will be set to use the ProcessList#SCHED_GROUP_TOP_APP scheduling group to boost performance.
+    private volatile boolean mHasTopUi;
+    // Is the process currently showing a non-activity UI that overlays on-top of activity UIs on
+    // screen. E.g. display a window of type
+    // android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY When true the process will
+    // oom adj score will be set to ProcessList#PERCEPTIBLE_APP_ADJ at minimum to reduce the chance
+    // of the process getting killed.
+    private volatile boolean mHasOverlayUi;
+    // Want to clean up resources from showing UI?
+    private volatile boolean mPendingUiClean;
+    // The time we sent the last interaction event
+    private volatile long mInteractionEventTime;
+    // When we became foreground for interaction purposes
+    private volatile long mFgInteractionTime;
+    // When (uptime) the process last became unimportant
+    private volatile long mWhenUnimportant;
     // was app launched for debugging?
     private volatile boolean mDebugging;
     // Active instrumentation running in process?
     private volatile boolean mInstrumenting;
+    // This process it perceptible by the user.
+    private volatile boolean mPerceptible;
     // Set to true when process was launched with a wrapper attached
     private volatile boolean mUsingWrapper;
 
@@ -116,6 +151,8 @@
 
     // Last configuration that was reported to the process.
     private final Configuration mLastReportedConfiguration;
+    // Registered display id as a listener to override config change
+    private int mDisplayId;
 
     WindowProcessController(ActivityTaskManagerService atm, ApplicationInfo info, String name,
             int uid, int userId, Object owner, WindowProcessListener listener,
@@ -128,6 +165,7 @@
         mListener = listener;
         mAtm = atm;
         mLastReportedConfiguration = new Configuration();
+        mDisplayId = INVALID_DISPLAY;
         if (config != null) {
             onConfigurationChanged(config);
         }
@@ -161,6 +199,14 @@
         return mCurSchedGroup;
     }
 
+    public void setCurrentProcState(int curProcState) {
+        mCurProcState = curProcState;
+    }
+
+    int getCurrentProcState() {
+        return mCurProcState;
+    }
+
     public void setReportedProcState(int repProcState) {
         mRepProcState = repProcState;
     }
@@ -201,6 +247,78 @@
         return mHasForegroundServices;
     }
 
+    public void setHasForegroundActivities(boolean hasForegroundActivities) {
+        mHasForegroundActivities = hasForegroundActivities;
+    }
+
+    boolean hasForegroundActivities() {
+        return mHasForegroundActivities;
+    }
+
+    public void setHasClientActivities(boolean hasClientActivities) {
+        mHasClientActivities = hasClientActivities;
+    }
+
+    boolean hasClientActivities() {
+        return mHasClientActivities;
+    }
+
+    public void setHasTopUi(boolean hasTopUi) {
+        mHasTopUi = hasTopUi;
+    }
+
+    boolean hasTopUi() {
+        return mHasTopUi;
+    }
+
+    public void setHasOverlayUi(boolean hasOverlayUi) {
+        mHasOverlayUi = hasOverlayUi;
+    }
+
+    boolean hasOverlayUi() {
+        return mHasOverlayUi;
+    }
+
+    public void setPendingUiClean(boolean hasPendingUiClean) {
+        mPendingUiClean = hasPendingUiClean;
+    }
+
+    boolean hasPendingUiClean() {
+        return mPendingUiClean;
+    }
+
+    void postPendingUiCleanMsg(boolean pendingUiClean) {
+        if (mListener == null) return;
+        // Posting on handler so WM lock isn't held when we call into AM.
+        final Message m = PooledLambda.obtainMessage(
+                WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
+        mAtm.mH.sendMessage(m);
+    }
+
+    public void setInteractionEventTime(long interactionEventTime) {
+        mInteractionEventTime = interactionEventTime;
+    }
+
+    long getInteractionEventTime() {
+        return mInteractionEventTime;
+    }
+
+    public void setFgInteractionTime(long fgInteractionTime) {
+        mFgInteractionTime = fgInteractionTime;
+    }
+
+    long getFgInteractionTime() {
+        return mFgInteractionTime;
+    }
+
+    public void setWhenUnimportant(long whenUnimportant) {
+        mWhenUnimportant = whenUnimportant;
+    }
+
+    long getWhenUnimportant() {
+        return mWhenUnimportant;
+    }
+
     public void setRequiredAbi(String requiredAbi) {
         mRequiredAbi = requiredAbi;
     }
@@ -233,6 +351,14 @@
         return mInstrumenting;
     }
 
+    public void setPerceptible(boolean perceptible) {
+        mPerceptible = perceptible;
+    }
+
+    boolean isPerceptible() {
+        return mPerceptible;
+    }
+
     @Override
     protected int getChildCount() {
         return 0;
@@ -500,12 +626,19 @@
             final int activitiesSize = mActivities.size();
             for (int i = activitiesSize - 1; i >= 0; i--) {
                 final ActivityRecord r = mActivities.get(i);
-                if (r.mRelaunchReason != ActivityRecord.RELAUNCH_REASON_NONE) {
+                if (r.mRelaunchReason != RELAUNCH_REASON_NONE) {
                     return r.mRelaunchReason;
                 }
             }
         }
-        return ActivityRecord.RELAUNCH_REASON_NONE;
+        return RELAUNCH_REASON_NONE;
+    }
+
+    public long getInputDispatchingTimeout() {
+        synchronized (mAtm.mGlobalLock) {
+            return isInstrumenting() || isUsingWrapper()
+                    ? INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT_MS : KEY_DISPATCHING_TIMEOUT_MS;
+        }
     }
 
     void clearProfilerIfNeeded() {
@@ -532,14 +665,6 @@
                 WindowProcessListener::updateServiceConnectionActivities, mListener));
     }
 
-    void setPendingUiClean(boolean pendingUiClean) {
-        if (mListener == null) return;
-        // Posting on handler so WM lock isn't held when we call into AM.
-        final Message m = PooledLambda.obtainMessage(
-                WindowProcessListener::setPendingUiClean, mListener, pendingUiClean);
-        mAtm.mH.sendMessage(m);
-    }
-
     void setPendingUiCleanAndForceProcessStateUpTo(int newState) {
         if (mListener == null) return;
         // Posting on handler so WM lock isn't held when we call into AM.
@@ -557,6 +682,59 @@
         mAtm.mH.sendMessage(m);
     }
 
+    void clearWaitingToKill() {
+        if (mListener == null) return;
+        // Posting on handler so WM lock isn't held when we call into AM.
+        final Message m = PooledLambda.obtainMessage(
+                WindowProcessListener::clearWaitingToKill, mListener);
+        mAtm.mH.sendMessage(m);
+    }
+
+    void addPackage(String pkg, long versionCode) {
+        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
+        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
+        if (mListener == null) return;
+        mListener.addPackage(pkg, versionCode);
+    }
+
+    ProfilerInfo onStartActivity(int topProcessState) {
+        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
+        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
+        if (mListener == null) return null;
+        return mListener.onStartActivity(topProcessState);
+    }
+
+    public void appDied() {
+        // TODO(b/80414790): Calling directly into AM for now which can lead to deadlock once we are
+        // using WM lock. Need to figure-out if it is okay to do this asynchronously.
+        if (mListener == null) return;
+        mListener.appDied();
+    }
+
+    void registerDisplayConfigurationListenerLocked(ActivityDisplay activityDisplay) {
+        if (activityDisplay == null) {
+            return;
+        }
+        // A process can only register to one display to listener to the override configuration
+        // change. Unregister existing listener if it has one before register the new one.
+        unregisterDisplayConfigurationListenerLocked();
+        mDisplayId = activityDisplay.mDisplayId;
+        activityDisplay.registerConfigurationChangeListener(this);
+    }
+
+    private void unregisterDisplayConfigurationListenerLocked() {
+        if (mDisplayId == INVALID_DISPLAY) {
+            return;
+        }
+        final ActivityDisplay activityDisplay =
+                mAtm.mStackSupervisor.getActivityDisplay(mDisplayId);
+        if (activityDisplay != null) {
+            mAtm.mStackSupervisor.getActivityDisplay(
+                    mDisplayId).unregisterConfigurationChangeListener(this);
+        }
+        mDisplayId = INVALID_DISPLAY;
+    }
+
     @Override
     public void onConfigurationChanged(Configuration newGlobalConfig) {
         super.onConfigurationChanged(newGlobalConfig);
@@ -654,4 +832,9 @@
         pw.println(prefix + " mLastReportedConfiguration=" + mLastReportedConfiguration);
     }
 
+    void writeToProto(ProtoOutputStream proto, long fieldId) {
+        if (mListener != null) {
+            mListener.writeToProto(proto, fieldId);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/WindowProcessListener.java b/services/core/java/com/android/server/am/WindowProcessListener.java
index 2de3e37..4a7e6e8 100644
--- a/services/core/java/com/android/server/am/WindowProcessListener.java
+++ b/services/core/java/com/android/server/am/WindowProcessListener.java
@@ -16,6 +16,10 @@
 
 package com.android.server.am;
 
+import android.app.ProfilerInfo;
+import android.content.pm.ApplicationInfo;
+import android.util.proto.ProtoOutputStream;
+
 /**
  * Interface used by the owner/creator of a process that owns windows to listen to changes from the
  * WM side.
@@ -47,4 +51,17 @@
 
     /** Returns the total time (in milliseconds) spent executing in both user and system code. */
     long getCpuTime();
+
+    /** Clears the waiting to kill reason for this process. */
+    void clearWaitingToKill();
+
+    /** Adds the package to the process. */
+    void addPackage(String pkg, long versionCode);
+
+    /** Called when we are in the process on starting an activity. */
+    ProfilerInfo onStartActivity(int topProcessState);
+
+    /** App died :(...oh well */
+    void appDied();
+    void writeToProto(ProtoOutputStream proto, long fieldId);
 }
diff --git a/services/core/java/com/android/server/appbinding/AppBindingConstants.java b/services/core/java/com/android/server/appbinding/AppBindingConstants.java
index c2655a2..7184769 100644
--- a/services/core/java/com/android/server/appbinding/AppBindingConstants.java
+++ b/services/core/java/com/android/server/appbinding/AppBindingConstants.java
@@ -15,6 +15,7 @@
  */
 package com.android.server.appbinding;
 
+import android.content.Context;
 import android.util.KeyValueListParser;
 import android.util.Slog;
 
@@ -24,7 +25,7 @@
 /**
  * Constants that are configurable via the global settings for {@link AppBindingService}.
  */
-class AppBindingConstants {
+public class AppBindingConstants {
     private static final String TAG = AppBindingService.TAG;
 
     private static final String SERVICE_RECONNECT_BACKOFF_SEC_KEY =
@@ -36,6 +37,15 @@
     private static final String SERVICE_RECONNECT_MAX_BACKOFF_SEC_KEY =
             "service_reconnect_max_backoff_sec";
 
+    private static final String SERVICE_STABLE_CONNECTION_THRESHOLD_SEC_KEY =
+            "service_stable_connection_threshold_sec";
+
+    private static final String SMS_SERVICE_ENABLED_KEY =
+            "sms_service_enabled";
+
+    private static final String SMS_APP_BIND_FLAGS_KEY =
+            "sms_app_bind_flags";
+
     public final String sourceSettings;
 
     /**
@@ -54,6 +64,21 @@
      */
     public final long SERVICE_RECONNECT_MAX_BACKOFF_SEC;
 
+    /**
+     * If a connection lasts more than this duration, we reset the re-connect back-off time.
+     */
+    public final long SERVICE_STABLE_CONNECTION_THRESHOLD_SEC;
+
+    /**
+     * Whether to actually bind to the default SMS app service. (Feature flag)
+     */
+    public final boolean SMS_SERVICE_ENABLED;
+
+    /**
+     * Extra binding flags for SMS service.
+     */
+    public final int SMS_APP_BIND_FLAGS;
+
     private AppBindingConstants(String settings) {
         sourceSettings = settings;
 
@@ -67,13 +92,22 @@
         }
 
         long serviceReconnectBackoffSec = parser.getLong(
-                SERVICE_RECONNECT_BACKOFF_SEC_KEY, TimeUnit.HOURS.toSeconds(1));
+                SERVICE_RECONNECT_BACKOFF_SEC_KEY, 10);
 
         double serviceReconnectBackoffIncrease = parser.getFloat(
                 SERVICE_RECONNECT_BACKOFF_INCREASE_KEY, 2f);
 
         long serviceReconnectMaxBackoffSec = parser.getLong(
-                SERVICE_RECONNECT_MAX_BACKOFF_SEC_KEY, TimeUnit.DAYS.toSeconds(1));
+                SERVICE_RECONNECT_MAX_BACKOFF_SEC_KEY, TimeUnit.HOURS.toSeconds(1));
+
+        boolean smsServiceEnabled = parser.getBoolean(SMS_SERVICE_ENABLED_KEY, true);
+
+        int smsAppBindFlags = parser.getInt(
+                SMS_APP_BIND_FLAGS_KEY,
+                Context.BIND_NOT_VISIBLE | Context.BIND_FOREGROUND_SERVICE);
+
+        long serviceStableConnectionThresholdSec = parser.getLong(
+                SERVICE_STABLE_CONNECTION_THRESHOLD_SEC_KEY, TimeUnit.MINUTES.toSeconds(2));
 
         // Set minimum: 5 seconds.
         serviceReconnectBackoffSec = Math.max(5, serviceReconnectBackoffSec);
@@ -89,6 +123,9 @@
         SERVICE_RECONNECT_BACKOFF_SEC = serviceReconnectBackoffSec;
         SERVICE_RECONNECT_BACKOFF_INCREASE = serviceReconnectBackoffIncrease;
         SERVICE_RECONNECT_MAX_BACKOFF_SEC = serviceReconnectMaxBackoffSec;
+        SERVICE_STABLE_CONNECTION_THRESHOLD_SEC = serviceStableConnectionThresholdSec;
+        SMS_SERVICE_ENABLED = smsServiceEnabled;
+        SMS_APP_BIND_FLAGS = smsAppBindFlags;
     }
 
     /**
@@ -103,7 +140,8 @@
      */
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix);
-        pw.println("Constants:");
+        pw.print("Constants: ");
+        pw.println(sourceSettings);
 
         pw.print(prefix);
         pw.print("  SERVICE_RECONNECT_BACKOFF_SEC: ");
@@ -116,5 +154,17 @@
         pw.print(prefix);
         pw.print("  SERVICE_RECONNECT_MAX_BACKOFF_SEC: ");
         pw.println(SERVICE_RECONNECT_MAX_BACKOFF_SEC);
+
+        pw.print(prefix);
+        pw.print("  SERVICE_STABLE_CONNECTION_THRESHOLD_SEC: ");
+        pw.println(SERVICE_STABLE_CONNECTION_THRESHOLD_SEC);
+
+        pw.print(prefix);
+        pw.print("  SMS_SERVICE_ENABLED: ");
+        pw.println(SMS_SERVICE_ENABLED);
+
+        pw.print(prefix);
+        pw.print("  SMS_APP_BIND_FLAGS: 0x");
+        pw.println(Integer.toHexString(SMS_APP_BIND_FLAGS));
     }
 }
diff --git a/services/core/java/com/android/server/appbinding/AppBindingService.java b/services/core/java/com/android/server/appbinding/AppBindingService.java
index c5cb2a4..3131255 100644
--- a/services/core/java/com/android/server/appbinding/AppBindingService.java
+++ b/services/core/java/com/android/server/appbinding/AppBindingService.java
@@ -21,6 +21,7 @@
 import android.app.AppGlobals;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -58,10 +59,11 @@
  *
  * <p>As of android Q, we only use it for the default SMS app.
  *
- * TODO Unit tests
- * TODO How do we handle force stop??
- * TODO Change OOM adjustment to 200 or so
- * TODO Only allow it when the service is associated with a secondary process.
+ * Relevant tests:
+ * atest CtsAppBindingHostTestCases
+ *
+ * TODO Maybe handle force-stop differently. Right now we just get "binder died" and re-bind
+ * after a timeout. b/116813347
  */
 public class AppBindingService extends Binder {
     public static final String TAG = "AppBindingService";
@@ -91,17 +93,25 @@
         public IPackageManager getIPackageManager() {
             return AppGlobals.getPackageManager();
         }
+
+        public String getGlobalSettingString(ContentResolver resolver, String key) {
+            return Settings.Global.getString(resolver, key);
+        }
     }
 
     /**
      * {@link SystemService} for this service.
      */
-    public static final class Lifecycle extends SystemService {
+    public static class Lifecycle extends SystemService {
         final AppBindingService mService;
 
         public Lifecycle(Context context) {
+            this(context, new Injector());
+        }
+
+        Lifecycle(Context context, Injector injector) {
             super(context);
-            mService = new AppBindingService(new Injector(), context);
+            mService = new AppBindingService(injector, context);
         }
 
         @Override
@@ -171,7 +181,6 @@
         packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-        packageFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
         packageFilter.addDataScheme("package");
 
         packageFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
@@ -197,7 +206,7 @@
     };
 
     private void refreshConstants() {
-        final String newSetting = Settings.Global.getString(
+        final String newSetting = mInjector.getGlobalSettingString(
                 mContext.getContentResolver(), Global.APP_BINDING_CONSTANTS);
 
         synchronized (mLock) {
@@ -215,6 +224,9 @@
     final BroadcastReceiver mPackageUserMonitor = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Slog.d(TAG, "Broadcast received: " + intent);
+            }
             final int userId  = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
             if (userId == UserHandle.USER_NULL) {
                 Slog.w(TAG, "Intent broadcast does not contain user handle: " + intent);
@@ -410,7 +422,7 @@
                 unbindServicesLocked(userId, target, reasonForLog);
             }
 
-            final ServiceInfo service = app.findService(userId, mIPackageManager);
+            final ServiceInfo service = app.findService(userId, mIPackageManager, mConstants);
             if (service == null) {
                 continue;
             }
@@ -454,14 +466,15 @@
             super(TAG, context, handler, userId, componentName,
                     constants.SERVICE_RECONNECT_BACKOFF_SEC,
                     constants.SERVICE_RECONNECT_BACKOFF_INCREASE,
-                    constants.SERVICE_RECONNECT_MAX_BACKOFF_SEC);
+                    constants.SERVICE_RECONNECT_MAX_BACKOFF_SEC,
+                    constants.SERVICE_STABLE_CONNECTION_THRESHOLD_SEC);
             mFinder = finder;
             mConstants = constants;
         }
 
         @Override
         protected int getBindFlags() {
-            return Context.BIND_FOREGROUND_SERVICE;
+            return mFinder.getBindFlags(mConstants);
         }
 
         @Override
@@ -535,9 +548,21 @@
                 pw.print(conn.isBound() ? "bound" : "not-bound");
                 pw.print(",");
                 pw.print(conn.isConnected() ? "connected" : "not-connected");
+                pw.print(",#con=");
+                pw.print(conn.getNumConnected());
+                pw.print(",#dis=");
+                pw.print(conn.getNumDisconnected());
+                pw.print(",#died=");
+                pw.print(conn.getNumBindingDied());
+                pw.print(",backoff=");
+                pw.print(conn.getNextBackoffMs());
                 pw.println();
             }
             forAllAppsLocked((app) -> app.dumpSimple(pw));
         }
     }
+
+    AppBindingConstants getConstantsForTest() {
+        return mConstants;
+    }
 }
diff --git a/services/core/java/com/android/server/appbinding/finders/AppServiceFinder.java b/services/core/java/com/android/server/appbinding/finders/AppServiceFinder.java
index 68c5e496..a075c50 100644
--- a/services/core/java/com/android/server/appbinding/finders/AppServiceFinder.java
+++ b/services/core/java/com/android/server/appbinding/finders/AppServiceFinder.java
@@ -24,10 +24,12 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.IInterface;
+import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.server.appbinding.AppBindingConstants;
 import com.android.server.appbinding.AppBindingService;
 import com.android.server.appbinding.AppBindingUtils;
 
@@ -51,13 +53,13 @@
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
-    private final SparseArray<String> mTargetPackages = new SparseArray(1);
+    private final SparseArray<String> mTargetPackages = new SparseArray(4);
 
     @GuardedBy("mLock")
-    private final SparseArray<ServiceInfo> mTargetServices = new SparseArray(1);
+    private final SparseArray<ServiceInfo> mTargetServices = new SparseArray(4);
 
     @GuardedBy("mLock")
-    private final SparseArray<String> mLastMessages = new SparseArray(1);
+    private final SparseArray<String> mLastMessages = new SparseArray(4);
 
     public AppServiceFinder(Context context,
             BiConsumer<AppServiceFinder, Integer> listener,
@@ -67,6 +69,11 @@
         mHandler = callbackHandler;
     }
 
+    /** Whether this service should really be enabled. */
+    protected boolean isEnabled(AppBindingConstants constants) {
+        return true;
+    }
+
     /** Human readable description of the type of apps; e.g. [Default SMS app] */
     @NonNull
     public abstract String getAppDescription();
@@ -80,6 +87,7 @@
         synchronized (mLock) {
             mTargetPackages.delete(userId);
             mTargetServices.delete(userId);
+            mLastMessages.delete(userId);
         }
     }
 
@@ -87,10 +95,19 @@
      * Find the target service from the target app on a given user.
      */
     @Nullable
-    public final ServiceInfo findService(int userId, IPackageManager ipm) {
+    public final ServiceInfo findService(int userId, IPackageManager ipm,
+            AppBindingConstants constants) {
         synchronized (mLock) {
             mTargetPackages.put(userId, null);
             mTargetServices.put(userId, null);
+            mLastMessages.put(userId, null);
+
+            if (!isEnabled(constants)) {
+                final String message = "feature disabled";
+                mLastMessages.put(userId, message);
+                Slog.i(TAG, getAppDescription() + " " + message);
+                return null;
+            }
 
             final String targetPackage = getTargetPackage(userId);
             if (DEBUG) {
@@ -118,11 +135,18 @@
                 final String message = errorMessage.toString();
                 mLastMessages.put(userId, message);
                 if (DEBUG) {
+                    // This log is optional because findService() already did Log.e().
                     Slog.w(TAG, getAppDescription() + " package " + targetPackage + " u" + userId
                             + " " + message);
                 }
                 return null;
             }
+            final String error = validateService(service);
+            if (error != null) {
+                mLastMessages.put(userId, error);
+                Log.e(TAG, error);
+                return null;
+            }
 
             final String message = "Valid service found";
             mLastMessages.put(userId, message);
@@ -156,6 +180,17 @@
     @NonNull
     protected abstract String getServicePermission();
 
+    /**
+     * Subclass can implement it to decide whether to accept a service (by returning null) or not
+     * (by returning an error message.)
+     */
+    protected String validateService(ServiceInfo service) {
+        return null;
+    }
+
+    /** Return the bind flags for this service. */
+    public abstract int getBindFlags(AppBindingConstants constants);
+
     /** Dumpsys support. */
     public void dump(String prefix, PrintWriter pw) {
         pw.print(prefix);
@@ -165,24 +200,25 @@
 
         synchronized (mLock) {
             for (int i = 0; i < mTargetPackages.size(); i++) {
+                final int userId = mTargetPackages.keyAt(i);
                 pw.print(prefix);
                 pw.print("  User: ");
-                pw.print(mTargetPackages.keyAt(i));
+                pw.print(userId);
                 pw.println();
 
                 pw.print(prefix);
                 pw.print("    Package: ");
-                pw.print(mTargetPackages.valueAt(i));
+                pw.print(mTargetPackages.get(userId));
                 pw.println();
 
                 pw.print(prefix);
                 pw.print("    Service: ");
-                pw.print(mTargetServices.valueAt(i));
+                pw.print(mTargetServices.get(userId));
                 pw.println();
 
                 pw.print(prefix);
                 pw.print("    Message: ");
-                pw.print(mLastMessages.valueAt(i));
+                pw.print(mLastMessages.get(userId));
                 pw.println();
             }
         }
@@ -192,16 +228,17 @@
     public void dumpSimple(PrintWriter pw) {
         synchronized (mLock) {
             for (int i = 0; i < mTargetPackages.size(); i++) {
+                final int userId = mTargetPackages.keyAt(i);
                 pw.print("finder,");
                 pw.print(getAppDescription());
                 pw.print(",");
-                pw.print(mTargetPackages.keyAt(i)); // User-id
+                pw.print(userId);
                 pw.print(",");
-                pw.print(mTargetPackages.valueAt(i));
+                pw.print(mTargetPackages.get(userId));
                 pw.print(",");
-                pw.print(mTargetServices.valueAt(i));
+                pw.print(mTargetServices.get(userId));
                 pw.print(",");
-                pw.print(mLastMessages.valueAt(i));
+                pw.print(mLastMessages.get(userId));
                 pw.println();
             }
         }
diff --git a/services/core/java/com/android/server/appbinding/finders/SmsAppServiceFinder.java b/services/core/java/com/android/server/appbinding/finders/SmsAppServiceFinder.java
index c908bd9..fcc28f8 100644
--- a/services/core/java/com/android/server/appbinding/finders/SmsAppServiceFinder.java
+++ b/services/core/java/com/android/server/appbinding/finders/SmsAppServiceFinder.java
@@ -26,12 +26,17 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ServiceInfo;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.UserHandle;
 import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Slog;
 
+import com.android.internal.R;
 import com.android.internal.telephony.SmsApplication;
+import com.android.server.appbinding.AppBindingConstants;
 
 import java.util.function.BiConsumer;
 
@@ -46,6 +51,12 @@
     }
 
     @Override
+    protected boolean isEnabled(AppBindingConstants constants) {
+        return constants.SMS_SERVICE_ENABLED
+                && mContext.getResources().getBoolean(R.bool.config_useSmsAppService);
+    }
+
+    @Override
     public String getAppDescription() {
         return "[Default SMS app]";
     }
@@ -74,7 +85,13 @@
     public String getTargetPackage(int userId) {
         final ComponentName cn = SmsApplication.getDefaultSmsApplicationAsUser(
                 mContext, /* updateIfNeeded= */ true, userId);
-        return cn == null ? null : cn.getPackageName();
+        String ret = cn == null ? null : cn.getPackageName();
+
+        if (DEBUG) {
+            Slog.d(TAG, "getTargetPackage()=" + ret);
+        }
+
+        return ret;
     }
 
     @Override
@@ -84,6 +101,22 @@
                 /* permission= */ null, mHandler);
     }
 
+    @Override
+    protected String validateService(ServiceInfo service) {
+        final String packageName = service.packageName;
+        final String process = service.processName;
+
+        if (process == null || TextUtils.equals(packageName, process)) {
+            return "Service must not run on the main process";
+        }
+        return null; // Null means accept this service.
+    }
+
+    @Override
+    public int getBindFlags(AppBindingConstants constants) {
+        return constants.SMS_APP_BIND_FLAGS;
+    }
+
     private final BroadcastReceiver mSmsAppChangedWatcher = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index f0ff570..f56d8e6 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -4682,22 +4682,15 @@
         }
     }
 
-    @Override
-    public void setHearingAidDeviceConnectionState(BluetoothDevice device, int state)
-    {
-        mDeviceLogger.log((new AudioEventLogger.StringEvent(
-                "setHearingAidDeviceConnectionState state=" + state
-                        + " addr=" + device.getAddress())).printLog(TAG));
-
-        setBluetoothHearingAidDeviceConnectionState(
-                device, state,  false /* suppressNoisyIntent */, AudioSystem.DEVICE_NONE);
-    }
-
     public int setBluetoothHearingAidDeviceConnectionState(
             BluetoothDevice device, int state, boolean suppressNoisyIntent,
             int musicDevice)
     {
         int delay;
+        mDeviceLogger.log((new AudioEventLogger.StringEvent(
+                "setHearingAidDeviceConnectionState state=" + state
+                            + " addr=" + device.getAddress()
+                            + " supprNoisy=" + suppressNoisyIntent)).printLog(TAG));
         synchronized (mConnectedDevices) {
             if (!suppressNoisyIntent) {
                 int intState = (state == BluetoothHearingAid.STATE_CONNECTED) ? 1 : 0;
@@ -5887,6 +5880,7 @@
                                    address));
         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
                 AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, 0, null, 0);
+        setCurrentAudioRouteNameIfPossible(name);
     }
 
     private void onSendBecomingNoisyIntent() {
@@ -5908,7 +5902,7 @@
         mConnectedDevices.remove(
                 makeDeviceListKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address));
         // Remove A2DP routes as well
-        setCurrentAudioRouteName(null);
+        setCurrentAudioRouteNameIfPossible(null);
         if (mDockAddress == address) {
             mDockAddress = null;
         }
@@ -5975,6 +5969,10 @@
                                    address));
         sendMsg(mAudioHandler, MSG_ACCESSORY_PLUG_MEDIA_UNMUTE, SENDMSG_QUEUE,
                 AudioSystem.DEVICE_OUT_HEARING_AID, 0, null, 0);
+        sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE,
+                            AudioSystem.DEVICE_OUT_HEARING_AID, 0,
+                            mStreamStates[AudioSystem.STREAM_MUSIC], 0);
+        setCurrentAudioRouteNameIfPossible(name);
     }
 
     // must be called synchronized on mConnectedDevices
@@ -5984,7 +5982,7 @@
         mConnectedDevices.remove(
                 makeDeviceListKey(AudioSystem.DEVICE_OUT_HEARING_AID, address));
         // Remove Hearing Aid routes as well
-        setCurrentAudioRouteName(null);
+        setCurrentAudioRouteNameIfPossible(null);
     }
 
     // must be called synchronized on mConnectedDevices
@@ -6029,7 +6027,6 @@
                 } else {
                     makeA2dpDeviceUnavailableNow(address);
                 }
-                setCurrentAudioRouteName(null);
             } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
                 if (btDevice.isBluetoothDock()) {
                     // this could be a reconnection after a transient disconnection
@@ -6053,7 +6050,6 @@
                 }
                 makeA2dpDeviceAvailable(address, btDevice.getName(),
                         "onSetA2dpSinkConnectionState");
-                setCurrentAudioRouteName(btDevice.getAliasName());
             }
         }
     }
@@ -6105,25 +6101,35 @@
 
             if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
                 makeHearingAidDeviceUnavailable(address);
-                setCurrentAudioRouteName(null);
             } else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
                 makeHearingAidDeviceAvailable(address, btDevice.getName(),
                         "onSetHearingAidConnectionState");
-                setCurrentAudioRouteName(btDevice.getAliasName());
             }
         }
     }
 
-    private void setCurrentAudioRouteName(String name){
+    private void setCurrentAudioRouteNameIfPossible(String name) {
         synchronized (mCurAudioRoutes) {
             if (!TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) {
-                mCurAudioRoutes.bluetoothName = name;
-                sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
-                        SENDMSG_NOOP, 0, 0, null, 0);
+                if (name != null || !isCurrentDeviceConnected()) {
+                    mCurAudioRoutes.bluetoothName = name;
+                    sendMsg(mAudioHandler, MSG_REPORT_NEW_ROUTES,
+                            SENDMSG_NOOP, 0, 0, null, 0);
+                }
             }
         }
     }
 
+    private boolean isCurrentDeviceConnected() {
+        for (int i = 0; i < mConnectedDevices.size(); i++) {
+            DeviceListSpec deviceSpec = mConnectedDevices.valueAt(i);
+            if (TextUtils.equals(deviceSpec.mDeviceName, mCurAudioRoutes.bluetoothName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void onBluetoothA2dpDeviceConfigChange(BluetoothDevice btDevice)
     {
         if (DEBUG_DEVICES) {
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index aa4d34e..61836fdd 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -27,6 +27,7 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.security.KeyStore;
+import android.text.TextUtils;
 import android.util.Slog;
 
 import com.android.internal.statusbar.IStatusBarService;
@@ -195,7 +196,7 @@
             // ERROR_CANCELED message.
             return true;
         }
-        if (mBundle != null) {
+        if (mBundle != null && error != BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED) {
             try {
                 mStatusBarService.onBiometricError(getErrorString(error, vendorCode));
             } catch (RemoteException e) {
@@ -205,6 +206,16 @@
         return super.onError(deviceId, error, vendorCode);
     }
 
+    public void setTitleIfEmpty(CharSequence title) {
+        if (TextUtils.isEmpty(mBundle.getCharSequence(BiometricPrompt.KEY_TITLE))) {
+            mBundle.putCharSequence(BiometricPrompt.KEY_TITLE, title);
+        }
+    }
+
+    public boolean isBiometricPrompt() {
+        return mBundle != null;
+    }
+
     private void notifyClientAuthenticationSucceeded(BiometricAuthenticator.Identifier identifier)
             throws RemoteException {
         final BiometricServiceBase.ServiceListener listener = getListener();
@@ -232,6 +243,7 @@
     public boolean onAuthenticated(BiometricAuthenticator.Identifier identifier,
             boolean authenticated, ArrayList<Byte> token) {
         if (authenticated) {
+            mAlreadyDone = true;
             if (mRequireConfirmation) {
                 // Store the token so it can be sent to keystore after the user presses confirm
                 mEscrow = new TokenEscrow(identifier, token);
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 87cf9c4..b80dca6 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -17,13 +17,21 @@
 package com.android.server.biometrics;
 
 import static android.Manifest.permission.USE_BIOMETRIC;
+import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.Manifest.permission.USE_FINGERPRINT;
 
+import android.app.ActivityManager;
 import android.app.AppOpsManager;
+import android.app.UserSwitchObserver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.database.ContentObserver;
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
+import android.hardware.biometrics.BiometricPrompt;
+import android.hardware.biometrics.BiometricSourceType;
+import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
 import android.hardware.biometrics.IBiometricPromptReceiver;
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.biometrics.IBiometricServiceReceiver;
@@ -31,8 +39,10 @@
 import android.hardware.face.IFaceService;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.IFingerprintService;
+import android.net.Uri;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.DeadObjectException;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -40,19 +50,21 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.provider.Settings;
+import android.util.Pair;
 import android.util.Slog;
 
 import com.android.internal.R;
 import com.android.server.SystemService;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * System service that arbitrates the modality for BiometricPrompt to use.
  */
 public class BiometricService extends SystemService {
 
-    private static final String TAG = "BiometricPromptService";
+    private static final String TAG = "BiometricService";
 
     /**
      * No biometric methods or nothing has been enrolled.
@@ -87,6 +99,8 @@
     private final boolean mHasFeatureFingerprint;
     private final boolean mHasFeatureIris;
     private final boolean mHasFeatureFace;
+    private final SettingObserver mSettingObserver;
+    private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
 
     private IFingerprintService mFingerprintService;
     private IFaceService mFaceService;
@@ -120,18 +134,119 @@
         }
     }
 
+    private final class SettingObserver extends ContentObserver {
+        private final Uri FACE_UNLOCK_KEYGUARD_ENABLED =
+                Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED);
+        private final Uri FACE_UNLOCK_APP_ENABLED =
+                Settings.Secure.getUriFor(Settings.Secure.FACE_UNLOCK_APP_ENABLED);
+
+        private final ContentResolver mContentResolver;
+        private boolean mFaceEnabledOnKeyguard;
+        private boolean mFaceEnabledForApps;
+
+        /**
+         * Creates a content observer.
+         *
+         * @param handler The handler to run {@link #onChange} on, or null if none.
+         */
+        SettingObserver(Handler handler) {
+            super(handler);
+            mContentResolver = getContext().getContentResolver();
+            updateContentObserver();
+        }
+
+        void updateContentObserver() {
+            mContentResolver.unregisterContentObserver(this);
+            mContentResolver.registerContentObserver(FACE_UNLOCK_KEYGUARD_ENABLED,
+                    false /* notifyForDescendents */,
+                    this /* observer */,
+                    UserHandle.USER_CURRENT);
+            mContentResolver.registerContentObserver(FACE_UNLOCK_APP_ENABLED,
+                    false /* notifyForDescendents */,
+                    this /* observer */,
+                    UserHandle.USER_CURRENT);
+
+            // Update the value immediately
+            onChange(true /* selfChange */, FACE_UNLOCK_KEYGUARD_ENABLED);
+            onChange(true /* selfChange */, FACE_UNLOCK_APP_ENABLED);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (FACE_UNLOCK_KEYGUARD_ENABLED.equals(uri)) {
+                mFaceEnabledOnKeyguard =
+                        Settings.Secure.getIntForUser(
+                                mContentResolver,
+                                Settings.Secure.FACE_UNLOCK_KEYGUARD_ENABLED,
+                                1 /* default */,
+                                UserHandle.USER_CURRENT) != 0;
+
+                List<EnabledOnKeyguardCallback> callbacks = mEnabledOnKeyguardCallbacks;
+                for (int i = 0; i < callbacks.size(); i++) {
+                    callbacks.get(i).notify(BiometricSourceType.FACE, mFaceEnabledOnKeyguard);
+                }
+            } else if (FACE_UNLOCK_APP_ENABLED.equals(uri)) {
+                mFaceEnabledForApps =
+                        Settings.Secure.getIntForUser(
+                                mContentResolver,
+                                Settings.Secure.FACE_UNLOCK_APP_ENABLED,
+                                1 /* default */,
+                                UserHandle.USER_CURRENT) != 0;
+            }
+        }
+
+        boolean getFaceEnabledOnKeyguard() {
+            return mFaceEnabledOnKeyguard;
+        }
+
+        boolean getFaceEnabledForApps() {
+            return mFaceEnabledForApps;
+        }
+    }
+
+    private final class EnabledOnKeyguardCallback implements IBinder.DeathRecipient {
+
+        private final IBiometricEnabledOnKeyguardCallback mCallback;
+
+        EnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback) {
+            mCallback = callback;
+            try {
+                mCallback.asBinder().linkToDeath(EnabledOnKeyguardCallback.this, 0);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Unable to linkToDeath", e);
+            }
+        }
+
+        void notify(BiometricSourceType sourceType, boolean enabled) {
+            try {
+                mCallback.onChanged(sourceType, enabled);
+            } catch (DeadObjectException e) {
+                Slog.w(TAG, "Death while invoking notify", e);
+                mEnabledOnKeyguardCallbacks.remove(this);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Failed to invoke onChanged", e);
+            }
+        }
+
+        @Override
+        public void binderDied() {
+            Slog.e(TAG, "Enabled callback binder died");
+            mEnabledOnKeyguardCallbacks.remove(this);
+        }
+    }
+
     /**
      * This is just a pass-through service that wraps Fingerprint, Iris, Face services. This service
      * should not carry any state. The reality is we need to keep a tiny amount of state so that
      * cancelAuthentication() can go to the right place.
      */
-    private final class BiometricPromptServiceWrapper extends IBiometricService.Stub {
+    private final class BiometricServiceWrapper extends IBiometricService.Stub {
 
         @Override // Binder call
         public void authenticate(IBinder token, long sessionId, int userId,
                 IBiometricServiceReceiver receiver, int flags, String opPackageName,
                 Bundle bundle, IBiometricPromptReceiver dialogReceiver) throws RemoteException {
-            // Check the USE_BIOMETRIC permission here. In the BiometricService, check do the
+            // Check the USE_BIOMETRIC permission here. In the BiometricServiceBase, check do the
             // AppOps and foreground check.
             checkPermission();
 
@@ -141,13 +256,49 @@
                 return;
             }
 
+            // Check the usage of this in system server. Need to remove this check if it becomes
+            // a public API.
+            if (bundle.getBoolean(BiometricPrompt.KEY_USE_DEFAULT_TITLE, false)) {
+                checkInternalPermission();
+            }
+
             final int callingUid = Binder.getCallingUid();
             final int callingPid = Binder.getCallingPid();
             final int callingUserId = UserHandle.getCallingUserId();
 
             mHandler.post(() -> {
-                mCurrentModality = checkAndGetBiometricModality(receiver);
+                final Pair<Integer, Integer> result = checkAndGetBiometricModality(callingUserId);
+                final int modality = result.first;
+                final int error = result.second;
 
+                // Check for errors, notify callback, and return
+                if (error != BiometricConstants.BIOMETRIC_ERROR_NONE) {
+                    try {
+                        final String hardwareUnavailable =
+                                getContext().getString(R.string.biometric_error_hw_unavailable);
+                        switch (error) {
+                            case BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT:
+                                receiver.onError(0 /* deviceId */, error, hardwareUnavailable);
+                                break;
+                            case BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE:
+                                receiver.onError(0 /* deviceId */, error, hardwareUnavailable);
+                                break;
+                            case BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS:
+                                receiver.onError(0 /* deviceId */, error,
+                                        getErrorString(modality, error, 0 /* vendorCode */));
+                                break;
+                            default:
+                                Slog.e(TAG, "Unhandled error");
+                                break;
+                        }
+                    } catch (RemoteException e) {
+                        Slog.e(TAG, "Unable to send error", e);
+                    }
+                    return;
+                }
+
+                // Actually start authentication
+                mCurrentModality = modality;
                 try {
                     // No polymorphism :(
                     if (mCurrentModality == BIOMETRIC_FINGERPRINT) {
@@ -157,18 +308,9 @@
                     } else if (mCurrentModality == BIOMETRIC_IRIS) {
                         Slog.w(TAG, "Unsupported modality");
                     } else if (mCurrentModality == BIOMETRIC_FACE) {
-                        // If the user disabled face for apps, return ERROR_HW_UNAVAILABLE
-                        if (isFaceEnabledForApps()) {
-                            receiver.onError(0 /* deviceId */,
-                                    BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                                    FaceManager.getErrorString(getContext(),
-                                            BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                                            0 /* vendorCode */));
-                        } else {
-                            mFaceService.authenticateFromService(true /* requireConfirmation */,
-                                    token, sessionId, userId, receiver, flags, opPackageName,
-                                    bundle, dialogReceiver, callingUid, callingPid, callingUserId);
-                        }
+                        mFaceService.authenticateFromService(true /* requireConfirmation */,
+                                token, sessionId, userId, receiver, flags, opPackageName,
+                                bundle, dialogReceiver, callingUid, callingPid, callingUserId);
                     } else {
                         Slog.w(TAG, "Unsupported modality");
                     }
@@ -178,15 +320,6 @@
             });
         }
 
-        private boolean isFaceEnabledForApps() {
-            // TODO: maybe cache this and eliminate duplicated code with KeyguardUpdateMonitor
-            return Settings.Secure.getIntForUser(
-                    getContext().getContentResolver(),
-                    Settings.Secure.FACE_UNLOCK_APP_ENABLED,
-                    1 /* default */,
-                    UserHandle.USER_CURRENT) == 0;
-        }
-
         @Override // Binder call
         public void cancelAuthentication(IBinder token, String opPackageName)
                 throws RemoteException {
@@ -221,33 +354,62 @@
         }
 
         @Override // Binder call
-        public boolean hasEnrolledBiometrics(String opPackageName) {
+        public int canAuthenticate(String opPackageName) {
             checkPermission();
+            checkAppOp(opPackageName, Binder.getCallingUid());
 
-            if (mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, Binder.getCallingUid(),
-                    opPackageName) != AppOpsManager.MODE_ALLOWED) {
-                Slog.w(TAG, "Rejecting " + opPackageName + "; permission denied");
-                throw new SecurityException("Permission denied");
-            }
-
+            final int userId = UserHandle.getCallingUserId();
             final long ident = Binder.clearCallingIdentity();
-            boolean hasEnrolled = false;
+            int error;
             try {
-                // Note: On devices with multi-modal authentication, the selection logic will need
-                // to be updated.
+                final Pair<Integer, Integer> result = checkAndGetBiometricModality(userId);
+                error = result.second;
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+            return error;
+        }
+
+        @Override // Binder call
+        public void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback)
+                throws RemoteException {
+            checkInternalPermission();
+            mEnabledOnKeyguardCallbacks.add(new EnabledOnKeyguardCallback(callback));
+            try {
+                callback.onChanged(BiometricSourceType.FACE,
+                        mSettingObserver.getFaceEnabledOnKeyguard());
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Remote exception", e);
+            }
+        }
+
+        @Override // Binder call
+        public void setActiveUser(int userId) {
+            checkInternalPermission();
+            final long ident = Binder.clearCallingIdentity();
+            try {
                 for (int i = 0; i < mAuthenticators.size(); i++) {
-                    if (mAuthenticators.get(i).getAuthenticator().hasEnrolledTemplates()) {
-                        hasEnrolled = true;
-                        break;
-                    }
+                    mAuthenticators.get(i).getAuthenticator().setActiveUser(userId);
                 }
             } finally {
                 Binder.restoreCallingIdentity(ident);
             }
-            return hasEnrolled;
         }
     }
 
+    private void checkAppOp(String opPackageName, int callingUid) {
+        if (mAppOps.noteOp(AppOpsManager.OP_USE_BIOMETRIC, callingUid,
+                opPackageName) != AppOpsManager.MODE_ALLOWED) {
+            Slog.w(TAG, "Rejecting " + opPackageName + "; permission denied");
+            throw new SecurityException("Permission denied");
+        }
+    }
+
+    private void checkInternalPermission() {
+        getContext().enforceCallingPermission(USE_BIOMETRIC_INTERNAL,
+                "Must have USE_BIOMETRIC_INTERNAL permission");
+    }
+
     private void checkPermission() {
         if (getContext().checkCallingPermission(USE_FINGERPRINT)
                 != PackageManager.PERMISSION_GRANTED) {
@@ -270,11 +432,26 @@
 
         mAppOps = context.getSystemService(AppOpsManager.class);
         mHandler = new Handler(Looper.getMainLooper());
+        mEnabledOnKeyguardCallbacks = new ArrayList<>();
+        mSettingObserver = new SettingObserver(mHandler);
 
         final PackageManager pm = context.getPackageManager();
         mHasFeatureFingerprint = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
         mHasFeatureIris = pm.hasSystemFeature(PackageManager.FEATURE_IRIS);
         mHasFeatureFace = pm.hasSystemFeature(PackageManager.FEATURE_FACE);
+
+        try {
+            ActivityManager.getService().registerUserSwitchObserver(
+                    new UserSwitchObserver() {
+                        @Override
+                        public void onUserSwitchComplete(int newUserId) {
+                            mSettingObserver.updateContentObserver();
+                        }
+                    }, BiometricService.class.getName()
+            );
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to register user switch observer", e);
+        }
     }
 
     @Override
@@ -298,72 +475,101 @@
             }
         }
 
-        publishBinderService(Context.BIOMETRIC_SERVICE, new BiometricPromptServiceWrapper());
+        publishBinderService(Context.BIOMETRIC_SERVICE, new BiometricServiceWrapper());
     }
 
     /**
      * Checks if there are any available biometrics, and returns the modality. This method also
      * returns errors through the callback (no biometric feature, hardware not detected, no
      * templates enrolled, etc). This service must not start authentication if errors are sent.
+     *
+     * @Returns A pair [Modality, Error] with Modality being one of {@link #BIOMETRIC_NONE},
+     * {@link #BIOMETRIC_FINGERPRINT}, {@link #BIOMETRIC_IRIS}, {@link #BIOMETRIC_FACE}
+     * and the error containing one of the {@link BiometricConstants} errors.
      */
-    private int checkAndGetBiometricModality(IBiometricServiceReceiver receiver) {
+    private Pair<Integer, Integer> checkAndGetBiometricModality(int callingUid) {
         int modality = BIOMETRIC_NONE;
-        final String hardwareUnavailable =
-                getContext().getString(R.string.biometric_error_hw_unavailable);
 
         // No biometric features, send error
         if (mAuthenticators.isEmpty()) {
-            try {
-                receiver.onError(0 /* deviceId */,
-                        BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT,
-                        hardwareUnavailable);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to send error", e);
-            }
-            return BIOMETRIC_NONE;
+            return new Pair<>(BIOMETRIC_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_NOT_PRESENT);
         }
 
-        // Find first authenticator that's both detected and enrolled
+        // Assuming that authenticators are listed in priority-order, the rest of this function
+        // will go through and find the first authenticator that's available, enrolled, and enabled.
+        // The tricky part is returning the correct error. Error strings that are modality-specific
+        // should also respect the priority-order.
+
+        // Find first authenticator that's detected, enrolled, and enabled.
         boolean isHardwareDetected = false;
         boolean hasTemplatesEnrolled = false;
+        boolean enabledForApps = false;
+
+        int firstHwAvailable = BIOMETRIC_NONE;
         for (int i = 0; i < mAuthenticators.size(); i++) {
-            int featureId = mAuthenticators.get(i).getType();
+            modality = mAuthenticators.get(i).getType();
             BiometricAuthenticator authenticator = mAuthenticators.get(i).getAuthenticator();
             if (authenticator.isHardwareDetected()) {
                 isHardwareDetected = true;
-                if (authenticator.hasEnrolledTemplates()) {
+                if (firstHwAvailable == BIOMETRIC_NONE) {
+                    // Store the first one since we want to return the error in correct priority
+                    // order.
+                    firstHwAvailable = modality;
+                }
+                if (authenticator.hasEnrolledTemplates(callingUid)) {
                     hasTemplatesEnrolled = true;
-                    modality = featureId;
-                    break;
+                    if (isEnabledForApp(modality)) {
+                        // TODO(b/110907543): When face settings (and other settings) have both a
+                        // user toggle as well as a work profile settings page, this needs to be
+                        // updated to reflect the correct setting.
+                        enabledForApps = true;
+                        break;
+                    }
                 }
             }
         }
 
         // Check error conditions
         if (!isHardwareDetected) {
-            try {
-                receiver.onError(0 /* deviceId */,
-                        BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
-                        hardwareUnavailable);
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to send error", e);
-            }
-            return BIOMETRIC_NONE;
-        }
-        if (!hasTemplatesEnrolled) {
-            try {
-                receiver.onError(0 /* deviceId */,
-                        BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS,
-                        FaceManager.getErrorString(getContext(),
-                                BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS,
-                                0 /* vendorCode */));
-            } catch (RemoteException e) {
-                Slog.e(TAG, "Unable to send error", e);
-            }
-            return BIOMETRIC_NONE;
+            return new Pair<>(BIOMETRIC_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
+        } else if (!hasTemplatesEnrolled) {
+            // Return the modality here so the correct error string can be sent. This error is
+            // preferred over !enabledForApps
+            return new Pair<>(firstHwAvailable, BiometricConstants.BIOMETRIC_ERROR_NO_BIOMETRICS);
+        } else if (!enabledForApps) {
+            return new Pair<>(BIOMETRIC_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
         }
 
-        return modality;
+        return new Pair<>(modality, BiometricConstants.BIOMETRIC_ERROR_NONE);
+    }
+
+    private boolean isEnabledForApp(int modality) {
+        switch(modality) {
+            case BIOMETRIC_FINGERPRINT:
+                return true;
+            case BIOMETRIC_IRIS:
+                return true;
+            case BIOMETRIC_FACE:
+                return mSettingObserver.getFaceEnabledForApps();
+            default:
+                Slog.w(TAG, "Unsupported modality: " + modality);
+                return false;
+        }
+    }
+
+    private String getErrorString(int type, int error, int vendorCode) {
+        switch (type) {
+            case BIOMETRIC_FINGERPRINT:
+                return FingerprintManager.getErrorString(getContext(), error, vendorCode);
+            case BIOMETRIC_IRIS:
+                Slog.w(TAG, "Modality not supported");
+                return null; // not supported
+            case BIOMETRIC_FACE:
+                return FaceManager.getErrorString(getContext(), error, vendorCode);
+            default:
+                Slog.w(TAG, "Unable to get error string for modality: " + type);
+                return null;
+        }
     }
 
     private BiometricAuthenticator getAuthenticator(int type) {
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index 6a22193..74d742a 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -16,6 +16,7 @@
 
 package com.android.server.biometrics;
 
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
 
 import android.app.ActivityManager;
@@ -55,6 +56,7 @@
 import android.util.SparseBooleanArray;
 import android.util.SparseIntArray;
 
+import com.android.internal.R;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.server.SystemService;
@@ -408,7 +410,8 @@
                         mActivityTaskManager.getTasks(1);
                 if (!runningTasks.isEmpty()) {
                     final String topPackage = runningTasks.get(0).topActivity.getPackageName();
-                    if (!topPackage.contentEquals(currentClient)) {
+                    if (!topPackage.contentEquals(currentClient)
+                            && !mCurrentClient.isAlreadyDone()) {
                         Slog.e(getTag(), "Stopping background authentication, top: " + topPackage
                                 + " currentClient: " + currentClient);
                         mCurrentClient.stop(false /* initiatedByClient */);
@@ -703,6 +706,30 @@
         }
 
         mHandler.post(() -> {
+            if (client.isBiometricPrompt()) {
+                try {
+                    final List<ActivityManager.RunningAppProcessInfo> procs =
+                            ActivityManager.getService().getRunningAppProcesses();
+                    for (int i = 0; i < procs.size(); i++) {
+                        final ActivityManager.RunningAppProcessInfo info = procs.get(i);
+                        if (info.uid == callingUid && info.importance == IMPORTANCE_FOREGROUND) {
+                            PackageManager pm = getContext().getPackageManager();
+                            final CharSequence label = pm.getApplicationLabel(
+                                    pm.getApplicationInfo(info.processName,
+                                            PackageManager.GET_META_DATA));
+                            final String title = getContext()
+                                    .getString(R.string.biometric_dialog_default_title, label);
+                            client.setTitleIfEmpty(title);
+                            break;
+                        }
+                    }
+                } catch (RemoteException e) {
+                    Slog.e(getTag(), "Unable to get application name", e);
+                } catch (PackageManager.NameNotFoundException e) {
+                    Slog.e(getTag(), "Unable to get application name", e);
+                }
+            }
+
             mMetricsLogger.histogram(getMetrics().tagAuthToken(), opId != 0L ? 1 : 0);
 
             // Get performance stats object for this user.
diff --git a/services/core/java/com/android/server/biometrics/ClientMonitor.java b/services/core/java/com/android/server/biometrics/ClientMonitor.java
index d1daad5..22b7418 100644
--- a/services/core/java/com/android/server/biometrics/ClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/ClientMonitor.java
@@ -63,6 +63,7 @@
     protected final Metrics mMetrics;
 
     protected boolean mAlreadyCancelled;
+    protected boolean mAlreadyDone;
 
     /**
      * @param context context of BiometricService
@@ -136,6 +137,11 @@
     public abstract boolean onEnumerationResult(
             BiometricAuthenticator.Identifier identifier, int remaining);
 
+
+    public boolean isAlreadyDone() {
+        return mAlreadyDone;
+    }
+
     /**
      * Called when we get notification from the biometric's HAL that an image has been acquired.
      * Common to authenticate and enroll.
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index ca9b256..30659c1 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -1031,6 +1031,11 @@
                 result.isPortal() /* isCaptivePortal */,
                 startTime, endTime);
 
+        log("isCaptivePortal: isSuccessful()=" + result.isSuccessful() +
+                " isPortal()=" + result.isPortal() +
+                " RedirectUrl=" + result.redirectUrl +
+                " StartTime=" + startTime + " EndTime=" + endTime);
+
         return result;
     }
 
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index dc65e1e..15468ff 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -16,6 +16,12 @@
 
 package com.android.server.connectivity;
 
+import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST;
+import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_HOST;
+import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_PAC;
+import static android.provider.Settings.Global.GLOBAL_HTTP_PROXY_PORT;
+import static android.provider.Settings.Global.HTTP_PROXY;
+
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.ContentResolver;
@@ -47,16 +53,14 @@
     @NonNull
     private final Context mContext;
 
-    // TODO : make this private and import as much managing logic from ConnectivityService as
-    // possible
     @NonNull
-    public final Object mProxyLock = new Object();
+    private final Object mProxyLock = new Object();
     // The global proxy is the proxy that is set device-wide, overriding any network-specific
     // proxy. Note however that proxies are hints ; the system does not enforce their use. Hence
     // this value is only for querying.
     @Nullable
     @GuardedBy("mProxyLock")
-    public ProxyInfo mGlobalProxy = null;
+    private ProxyInfo mGlobalProxy = null;
     // The default proxy is the proxy that applies to no particular network if the global proxy
     // is not set. Individual networks have their own settings that override this. This member
     // is set through setDefaultProxy, which is called when the default network changes proxies
@@ -64,10 +68,10 @@
     // when PacManager resolves the proxy.
     @Nullable
     @GuardedBy("mProxyLock")
-    public volatile ProxyInfo mDefaultProxy = null;
-    // Whether the default proxy is disabled. TODO : make this mDefaultProxyEnabled
+    private volatile ProxyInfo mDefaultProxy = null;
+    // Whether the default proxy is enabled.
     @GuardedBy("mProxyLock")
-    public boolean mDefaultProxyDisabled = false;
+    private boolean mDefaultProxyEnabled = true;
 
     // The object responsible for Proxy Auto Configuration (PAC).
     @NonNull
@@ -85,7 +89,7 @@
     @Nullable
     private static ProxyInfo canonicalizeProxyInfo(@Nullable final ProxyInfo proxy) {
         if (proxy != null && TextUtils.isEmpty(proxy.getHost())
-                && (proxy.getPacFileUrl() == null || Uri.EMPTY.equals(proxy.getPacFileUrl()))) {
+                && Uri.EMPTY.equals(proxy.getPacFileUrl())) {
             return null;
         }
         return proxy;
@@ -122,9 +126,9 @@
     public ProxyInfo getDefaultProxy() {
         // This information is already available as a world read/writable jvm property.
         synchronized (mProxyLock) {
-            final ProxyInfo ret = mGlobalProxy;
-            if ((ret == null) && !mDefaultProxyDisabled) return mDefaultProxy;
-            return ret;
+            if (mGlobalProxy != null) return mGlobalProxy;
+            if (mDefaultProxyEnabled) return mDefaultProxy;
+            return null;
         }
     }
 
@@ -142,15 +146,68 @@
     }
 
     /**
+     * Read the global proxy settings and cache them in memory.
+     */
+    public void loadGlobalProxy() {
+        ContentResolver res = mContext.getContentResolver();
+        String host = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_HOST);
+        int port = Settings.Global.getInt(res, GLOBAL_HTTP_PROXY_PORT, 0);
+        String exclList = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_EXCLUSION_LIST);
+        String pacFileUrl = Settings.Global.getString(res, GLOBAL_HTTP_PROXY_PAC);
+        if (!TextUtils.isEmpty(host) || !TextUtils.isEmpty(pacFileUrl)) {
+            ProxyInfo proxyProperties;
+            if (!TextUtils.isEmpty(pacFileUrl)) {
+                proxyProperties = new ProxyInfo(pacFileUrl);
+            } else {
+                proxyProperties = new ProxyInfo(host, port, exclList);
+            }
+            if (!proxyProperties.isValid()) {
+                if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyProperties);
+                return;
+            }
+
+            synchronized (mProxyLock) {
+                mGlobalProxy = proxyProperties;
+            }
+        }
+        loadDeprecatedGlobalHttpProxy();
+        // TODO : shouldn't this function call mPacManager.setCurrentProxyScriptUrl ?
+    }
+
+    /**
+     * Read the global proxy from the deprecated Settings.Global.HTTP_PROXY setting and apply it.
+     */
+    public void loadDeprecatedGlobalHttpProxy() {
+        final String proxy = Settings.Global.getString(mContext.getContentResolver(), HTTP_PROXY);
+        if (!TextUtils.isEmpty(proxy)) {
+            String data[] = proxy.split(":");
+            if (data.length == 0) {
+                return;
+            }
+
+            final String proxyHost = data[0];
+            int proxyPort = 8080;
+            if (data.length > 1) {
+                try {
+                    proxyPort = Integer.parseInt(data[1]);
+                } catch (NumberFormatException e) {
+                    return;
+                }
+            }
+            final ProxyInfo p = new ProxyInfo(proxyHost, proxyPort, "");
+            setGlobalProxy(p);
+        }
+    }
+
+    /**
      * Sends the system broadcast informing apps about a new proxy configuration.
      *
      * Confusingly this method also sets the PAC file URL. TODO : separate this, it has nothing
      * to do in a "sendProxyBroadcast" method.
-     * @param proxyInfo the proxy spec, or null for no proxy.
      */
-    // TODO : make the argument NonNull final and the method private
-    public void sendProxyBroadcast(@Nullable ProxyInfo proxyInfo) {
-        if (proxyInfo == null) proxyInfo = new ProxyInfo("", 0, "");
+    public void sendProxyBroadcast() {
+        final ProxyInfo defaultProxy = getDefaultProxy();
+        final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : new ProxyInfo("", 0, "");
         if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)) return;
         if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
         Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
@@ -203,16 +260,15 @@
             final ContentResolver res = mContext.getContentResolver();
             final long token = Binder.clearCallingIdentity();
             try {
-                Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, host);
-                Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, port);
-                Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
-                        exclList);
-                Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
+                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_HOST, host);
+                Settings.Global.putInt(res, GLOBAL_HTTP_PROXY_PORT, port);
+                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_EXCLUSION_LIST, exclList);
+                Settings.Global.putString(res, GLOBAL_HTTP_PROXY_PAC, pacFileUrl);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
 
-            sendProxyBroadcast(mGlobalProxy == null ? mDefaultProxy : proxyInfo);
+            sendProxyBroadcast();
         }
     }
 
@@ -224,10 +280,7 @@
      */
     public void setDefaultProxy(@Nullable ProxyInfo proxyInfo) {
         synchronized (mProxyLock) {
-            if (mDefaultProxy != null && mDefaultProxy.equals(proxyInfo)) {
-                return;
-            }
-            if (mDefaultProxy == proxyInfo) return; // catches repeated nulls
+            if (Objects.equals(mDefaultProxy, proxyInfo)) return;
             if (proxyInfo != null &&  !proxyInfo.isValid()) {
                 if (DBG) Slog.d(TAG, "Invalid proxy properties, ignoring: " + proxyInfo);
                 return;
@@ -242,14 +295,32 @@
                     && (!Uri.EMPTY.equals(proxyInfo.getPacFileUrl()))
                     && proxyInfo.getPacFileUrl().equals(mGlobalProxy.getPacFileUrl())) {
                 mGlobalProxy = proxyInfo;
-                sendProxyBroadcast(mGlobalProxy);
+                sendProxyBroadcast();
                 return;
             }
             mDefaultProxy = proxyInfo;
 
             if (mGlobalProxy != null) return;
-            if (!mDefaultProxyDisabled) {
-                sendProxyBroadcast(proxyInfo);
+            if (mDefaultProxyEnabled) {
+                sendProxyBroadcast();
+            }
+        }
+    }
+
+    /**
+     * Enable or disable the default proxy.
+     *
+     * This sets the flag for enabling/disabling the default proxy and sends the broadcast
+     * if applicable.
+     * @param enabled whether the default proxy should be enabled.
+     */
+    public void setDefaultProxyEnabled(final boolean enabled) {
+        synchronized (mProxyLock) {
+            if (mDefaultProxyEnabled != enabled) {
+                mDefaultProxyEnabled = enabled;
+                if (mGlobalProxy == null && mDefaultProxy != null) {
+                    sendProxyBroadcast();
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 5698fdf..5ed6263 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -1615,6 +1615,15 @@
     }
 
     @Override
+    public void onDbCorruption(String tag, String message, String stacktrace) {
+        Slog.e(tag, message);
+        Slog.e(tag, "at " + stacktrace);
+
+        // TODO: Figure out a better way to report it. b/117886381
+        Slog.wtf(tag, message);
+    }
+
+    @Override
     public void onShellCommand(FileDescriptor in, FileDescriptor out,
             FileDescriptor err, String[] args, ShellCallback callback,
             ResultReceiver resultReceiver) {
diff --git a/services/core/java/com/android/server/content/SyncLogger.java b/services/core/java/com/android/server/content/SyncLogger.java
index 8c35e27..5cbe5b9 100644
--- a/services/core/java/com/android/server/content/SyncLogger.java
+++ b/services/core/java/com/android/server/content/SyncLogger.java
@@ -20,12 +20,17 @@
 import android.os.Build;
 import android.os.Environment;
 import android.os.FileUtils;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
 import android.os.SystemProperties;
 import android.text.format.DateUtils;
 import android.util.Log;
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.IntPair;
+import com.android.server.IoThread;
 
 import libcore.io.IoUtils;
 
@@ -65,10 +70,11 @@
      */
     public static synchronized SyncLogger getInstance() {
         if (sInstance == null) {
+            final String flag = SystemProperties.get("debug.synclog");
             final boolean enable =
-                    Build.IS_DEBUGGABLE
-                    || "1".equals(SystemProperties.get("debug.synclog"))
-                    || Log.isLoggable(TAG, Log.VERBOSE);
+                    (Build.IS_DEBUGGABLE
+                    || "1".equals(flag)
+                    || Log.isLoggable(TAG, Log.VERBOSE)) && !"0".equals(flag);
             if (enable) {
                 sInstance = new RotatingFileLogger();
             } else {
@@ -142,8 +148,11 @@
 
         private static final boolean DO_LOGCAT = Log.isLoggable(TAG, Log.DEBUG);
 
+        private final MyHandler mHandler;
+
         RotatingFileLogger() {
             mLogPath = new File(Environment.getDataSystemDirectory(), "syncmanager-log");
+            mHandler = new MyHandler(IoThread.get().getLooper());
         }
 
         @Override
@@ -163,8 +172,12 @@
             if (message == null) {
                 return;
             }
+            final long now = System.currentTimeMillis();
+            mHandler.log(now, message);
+        }
+
+        void logInner(long now, Object[] message) {
             synchronized (mLock) {
-                final long now = System.currentTimeMillis();
                 openLogLocked(now);
                 if (mLogWriter == null) {
                     return; // Couldn't open log file?
@@ -272,5 +285,28 @@
             } catch (IOException e) {
             }
         }
+
+        private class MyHandler extends Handler {
+            public static final int MSG_LOG_ID = 1;
+
+            MyHandler(Looper looper) {
+                super(looper);
+            }
+
+            public void log(long now, Object[] message) {
+                obtainMessage(MSG_LOG_ID, IntPair.first(now), IntPair.second(now), message)
+                        .sendToTarget();
+            }
+
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_LOG_ID: {
+                        logInner(IntPair.of(msg.arg1, msg.arg2), (Object[]) msg.obj);
+                        break;
+                    }
+                }
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java
index 2405925..7bfe9ce 100644
--- a/services/core/java/com/android/server/display/DisplayDevice.java
+++ b/services/core/java/com/android/server/display/DisplayDevice.java
@@ -19,7 +19,6 @@
 import android.graphics.Rect;
 import android.hardware.display.DisplayViewport;
 import android.os.IBinder;
-import android.view.Display;
 import android.view.Surface;
 import android.view.SurfaceControl;
 
@@ -224,6 +223,8 @@
         DisplayDeviceInfo info = getDisplayDeviceInfoLocked();
         viewport.deviceWidth = isRotated ? info.height : info.width;
         viewport.deviceHeight = isRotated ? info.width : info.height;
+
+        viewport.uniqueId = info.uniqueId;
     }
 
     /**
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 512e851..c51dc52 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -110,6 +110,13 @@
     public static final int FLAG_MASK_DISPLAY_CUTOUT = 1 << 11;
 
     /**
+     * Flag: This flag identifies secondary displays that should show system decorations, such as
+     * status bar, navigation bar, home activity or IME.
+     * @hide
+     */
+    public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 12;
+
+    /**
      * Touch attachment: Display does not receive touch.
      */
     public static final int TOUCH_NONE = 0;
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 0eff7f5..e70460a 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -17,15 +17,14 @@
 package com.android.server.display;
 
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
+import static android.hardware.display.DisplayManager
+        .VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
-import static android.hardware.display.DisplayManager
-        .VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.DumpUtils;
-import com.android.internal.util.IndentingPrintWriter;
+import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
+import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
+import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -45,8 +44,8 @@
 import android.hardware.display.Curve;
 import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.display.DisplayManagerInternal;
-import android.hardware.display.DisplayViewport;
 import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener;
+import android.hardware.display.DisplayViewport;
 import android.hardware.display.IDisplayManager;
 import android.hardware.display.IDisplayManagerCallback;
 import android.hardware.display.IVirtualDisplayCallback;
@@ -83,14 +82,17 @@
 import android.view.Surface;
 import android.view.SurfaceControl;
 
-import com.android.internal.util.Preconditions;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.AnimationThread;
 import com.android.server.DisplayThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.UiThread;
-import com.android.server.wm.WindowManagerInternal;
 import com.android.server.wm.SurfaceAnimationThread;
+import com.android.server.wm.WindowManagerInternal;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -256,9 +258,8 @@
 
     // Viewports of the default display and the display that should receive touch
     // input from an external source.  Used by the input system.
-    private final DisplayViewport mDefaultViewport = new DisplayViewport();
-    private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
-    private final ArrayList<DisplayViewport> mVirtualTouchViewports = new ArrayList<>();
+    @GuardedBy("mSyncRoot")
+    private final ArrayList<DisplayViewport> mViewports = new ArrayList<>();
 
     // Persistent data store for all internal settings maintained by the display manager service.
     private final PersistentDataStore mPersistentDataStore = new PersistentDataStore();
@@ -272,9 +273,7 @@
 
     // Temporary viewports, used when sending new viewport information to the
     // input system.  May be used outside of the lock but only on the handler thread.
-    private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
-    private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
-    private final ArrayList<DisplayViewport> mTempVirtualTouchViewports = new ArrayList<>();
+    private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>();
 
     // The default color mode for default displays. Overrides the usual
     // Display.Display.COLOR_MODE_DEFAULT for displays with the
@@ -1255,9 +1254,7 @@
     }
 
     private void clearViewportsLocked() {
-        mDefaultViewport.valid = false;
-        mExternalTouchViewport.valid = false;
-        mVirtualTouchViewports.clear();
+        mViewports.clear();
     }
 
     private void configureDisplayLocked(SurfaceControl.Transaction t, DisplayDevice device) {
@@ -1287,40 +1284,89 @@
         }
         display.configureDisplayLocked(t, device, info.state == Display.STATE_OFF);
 
-        // Update the viewports if needed.
-        if (!mDefaultViewport.valid
-                && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
-            setViewportLocked(mDefaultViewport, display, device);
+        // Update the corresponding viewport.
+        DisplayViewport internalViewport = getInternalViewportLocked();
+        if ((info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
+            populateViewportLocked(internalViewport, display, device);
         }
-        if (!mExternalTouchViewport.valid
-                && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
-            setViewportLocked(mExternalTouchViewport, display, device);
+        DisplayViewport externalViewport = getExternalViewportLocked();
+        if (info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
+            populateViewportLocked(externalViewport, display, device);
+        } else if (!externalViewport.valid) {
+            // TODO (b/116850516) move this logic into InputReader
+            externalViewport.copyFrom(internalViewport);
+            externalViewport.type = DisplayViewport.VIEWPORT_EXTERNAL;
         }
 
         if (info.touch == DisplayDeviceInfo.TOUCH_VIRTUAL && !TextUtils.isEmpty(info.uniqueId)) {
-            final DisplayViewport viewport = getVirtualTouchViewportLocked(info.uniqueId);
-            setViewportLocked(viewport, display, device);
+            final DisplayViewport viewport = getVirtualViewportLocked(info.uniqueId);
+            populateViewportLocked(viewport, display, device);
         }
     }
 
-    /** Gets the virtual device viewport or creates it if not yet created. */
-    private DisplayViewport getVirtualTouchViewportLocked(@NonNull String uniqueId) {
+    /** Get the virtual device viewport that has the specified uniqueId.
+     * If such viewport does not exist, create it. */
+    private DisplayViewport getVirtualViewportLocked(@NonNull String uniqueId) {
         DisplayViewport viewport;
-        final int count = mVirtualTouchViewports.size();
+        final int count = mViewports.size();
         for (int i = 0; i < count; i++) {
-            viewport = mVirtualTouchViewports.get(i);
+            viewport = mViewports.get(i);
             if (uniqueId.equals(viewport.uniqueId)) {
+                if (viewport.type != VIEWPORT_VIRTUAL) {
+                    Slog.wtf(TAG, "Found a viewport with uniqueId '"  + uniqueId
+                            + "' but it has type " + DisplayViewport.typeToString(viewport.type)
+                            + " (expected VIRTUAL)");
+                    continue;
+                }
                 return viewport;
             }
         }
 
         viewport = new DisplayViewport();
         viewport.uniqueId = uniqueId;
-        mVirtualTouchViewports.add(viewport);
+        viewport.type = VIEWPORT_VIRTUAL;
+        mViewports.add(viewport);
         return viewport;
     }
 
-    private static void setViewportLocked(DisplayViewport viewport,
+    private DisplayViewport getInternalViewportLocked() {
+        return getViewportByTypeLocked(VIEWPORT_INTERNAL);
+    }
+
+    private DisplayViewport getExternalViewportLocked() {
+        return getViewportByTypeLocked(VIEWPORT_EXTERNAL);
+    }
+
+    /**
+     * Get internal or external viewport. Create it if does not currently exist.
+     * @param viewportType - either INTERNAL or EXTERNAL
+     * @return the viewport with the requested type
+     */
+    private DisplayViewport getViewportByTypeLocked(int viewportType) {
+        // Only allow a single INTERNAL or EXTERNAL viewport, which makes this function possible.
+        // TODO (b/116824030) allow multiple EXTERNAL viewports and remove this function.
+        // Creates the viewport if none exists.
+        if (viewportType != VIEWPORT_INTERNAL && viewportType != VIEWPORT_EXTERNAL) {
+            Slog.wtf(TAG, "Cannot call getViewportByTypeLocked for type "
+                    + DisplayViewport.typeToString(viewportType));
+            return null;
+        }
+        DisplayViewport viewport;
+        final int count = mViewports.size();
+        for (int i = 0; i < count; i++) {
+            viewport = mViewports.get(i);
+            if (viewport.type == viewportType) {
+                return viewport;
+            }
+        }
+
+        viewport = new DisplayViewport();
+        viewport.type = viewportType;
+        mViewports.add(viewport);
+        return viewport;
+    }
+
+    private static void populateViewportLocked(DisplayViewport viewport,
             LogicalDisplay display, DisplayDevice device) {
         viewport.valid = true;
         viewport.displayId = display.getDisplayIdLocked();
@@ -1400,9 +1446,7 @@
             pw.println("  mPendingTraversal=" + mPendingTraversal);
             pw.println("  mGlobalDisplayState=" + Display.stateToString(mGlobalDisplayState));
             pw.println("  mNextNonDefaultDisplayId=" + mNextNonDefaultDisplayId);
-            pw.println("  mDefaultViewport=" + mDefaultViewport);
-            pw.println("  mExternalTouchViewport=" + mExternalTouchViewport);
-            pw.println("  mVirtualTouchViewports=" + mVirtualTouchViewports);
+            pw.println("  mViewports=" + mViewports);
             pw.println("  mDefaultDisplayDefaultColorMode=" + mDefaultDisplayDefaultColorMode);
             pw.println("  mSingleDisplayDemoMode=" + mSingleDisplayDemoMode);
             pw.println("  mWifiDisplayScanRequestCount=" + mWifiDisplayScanRequestCount);
@@ -1522,18 +1566,19 @@
                     break;
 
                 case MSG_UPDATE_VIEWPORT: {
+                    final boolean changed;
                     synchronized (mSyncRoot) {
-                        mTempDefaultViewport.copyFrom(mDefaultViewport);
-                        mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
-                        if (!mTempVirtualTouchViewports.equals(mVirtualTouchViewports)) {
-                          mTempVirtualTouchViewports.clear();
-                          for (DisplayViewport d : mVirtualTouchViewports) {
-                              mTempVirtualTouchViewports.add(d.makeCopy());
-                          }
+                        changed = !mTempViewports.equals(mViewports);
+                        if (changed) {
+                            mTempViewports.clear();
+                            for (DisplayViewport d : mViewports) {
+                                mTempViewports.add(d.makeCopy());
+                            }
                         }
                     }
-                    mInputManagerInternal.setDisplayViewports(mTempDefaultViewport,
-                            mTempExternalTouchViewport, mTempVirtualTouchViewports);
+                    if (changed) {
+                        mInputManagerInternal.setDisplayViewports(mTempViewports);
+                    }
                     break;
                 }
 
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 5b7c520..6f726e6 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -18,7 +18,6 @@
 
 import android.graphics.Rect;
 import android.hardware.display.DisplayManagerInternal;
-import android.os.SystemProperties;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Surface;
@@ -256,6 +255,9 @@
             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
                 mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
             }
+            if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
+                mBaseDisplayInfo.flags |= Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
+            }
             Rect maskingInsets = getMaskingInsets(deviceInfo);
             int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
             int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
index 6111c23..5aa585f 100644
--- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java
@@ -17,15 +17,14 @@
 package com.android.server.display;
 
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;
-import static android.hardware.display.DisplayManager
-        .VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
-import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
 import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ROTATES_WITH_CONTENT;
-import static android.hardware.display.DisplayManager
-        .VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
+import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SUPPORTS_TOUCH;
 
 import android.content.Context;
 import android.hardware.display.IVirtualDisplayCallback;
@@ -33,10 +32,10 @@
 import android.media.projection.IMediaProjectionCallback;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.SystemProperties;
 import android.os.IBinder.DeathRecipient;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.SystemProperties;
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.view.Display;
@@ -60,7 +59,8 @@
     static final boolean DEBUG = false;
 
     // Unique id prefix for virtual displays
-    private static final String UNIQUE_ID_PREFIX = "virtual:";
+    @VisibleForTesting
+    static final String UNIQUE_ID_PREFIX = "virtual:";
 
     private final ArrayMap<IBinder, VirtualDisplayDevice> mVirtualDisplayDevices =
             new ArrayMap<IBinder, VirtualDisplayDevice>();
@@ -366,7 +366,10 @@
                     mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
                 }
                 if ((mFlags & VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) {
-                  mInfo.flags |= DisplayDeviceInfo.FLAG_DESTROY_CONTENT_ON_REMOVAL;
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_DESTROY_CONTENT_ON_REMOVAL;
+                }
+                if ((mFlags & VIRTUAL_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
                 }
 
                 mInfo.type = Display.TYPE_VIRTUAL;
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index c16d3cd..b148a2f 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -307,19 +307,19 @@
     private final class CecMessageBuffer {
         private List<HdmiCecMessage> mBuffer = new ArrayList<>();
 
-        public void bufferMessage(HdmiCecMessage message) {
+        public boolean bufferMessage(HdmiCecMessage message) {
             switch (message.getOpcode()) {
                 case Constants.MESSAGE_ACTIVE_SOURCE:
                     bufferActiveSource(message);
-                    break;
+                    return true;
                 case Constants.MESSAGE_IMAGE_VIEW_ON:
                 case Constants.MESSAGE_TEXT_VIEW_ON:
                     bufferImageOrTextViewOn(message);
-                    break;
+                    return true;
                     // Add here if new message that needs to buffer
                 default:
                     // Do not need to buffer messages other than above
-                    break;
+                    return false;
             }
         }
 
@@ -906,10 +906,6 @@
     @ServiceThreadOnly
     boolean handleCecCommand(HdmiCecMessage message) {
         assertRunOnServiceThread();
-        if (!mAddressAllocated) {
-            mCecMessageBuffer.bufferMessage(message);
-            return true;
-        }
         int errorCode = mMessageValidator.isValid(message);
         if (errorCode != HdmiCecMessageValidator.OK) {
             // We'll not response on the messages with the invalid source or destination
@@ -919,7 +915,12 @@
             }
             return true;
         }
-        return dispatchMessageToLocalDevice(message);
+
+        if (dispatchMessageToLocalDevice(message)) {
+            return true;
+        }
+
+        return (!mAddressAllocated) ? mCecMessageBuffer.bufferMessage(message) : false;
     }
 
     void enableAudioReturnChannel(int portId, boolean enabled) {
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
index d347a91..f7e871d 100644
--- a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
@@ -50,8 +50,7 @@
             @Override
             public void onSendCompleted(int error) {
                 if (error != SendMessageResult.SUCCESS) {
-                    tv().setSystemAudioMode(false);
-                    finish();
+                    handleSystemAudioModeStatusTimeout();
                 }
             }
         });
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 0f28439..c20079e 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -16,9 +16,6 @@
 
 package com.android.server.input;
 
-import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
-import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
-
 import android.annotation.NonNull;
 import android.app.IInputForwarder;
 import android.app.Notification;
@@ -188,13 +185,8 @@
     private static native long nativeInit(InputManagerService service,
             Context context, MessageQueue messageQueue);
     private static native void nativeStart(long ptr);
-    private static native void nativeSetVirtualDisplayViewports(long ptr,
+    private static native void nativeSetDisplayViewports(long ptr,
             DisplayViewport[] viewports);
-    private static native void nativeSetDisplayViewport(long ptr, int viewportType,
-            int displayId, int rotation,
-            int logicalLeft, int logicalTop, int logicalRight, int logicalBottom,
-            int physicalLeft, int physicalTop, int physicalRight, int physicalBottom,
-            int deviceWidth, int deviceHeight, String uniqueId);
 
     private static native int nativeGetScanCodeState(long ptr,
             int deviceId, int sourceMask, int scanCode);
@@ -205,7 +197,7 @@
     private static native boolean nativeHasKeys(long ptr,
             int deviceId, int sourceMask, int[] keyCodes, boolean[] keyExists);
     private static native void nativeRegisterInputChannel(long ptr, InputChannel inputChannel,
-            InputWindowHandle inputWindowHandle, boolean monitor);
+            InputWindowHandle inputWindowHandle, int displayId);
     private static native void nativeUnregisterInputChannel(long ptr, InputChannel inputChannel);
     private static native void nativeSetInputFilterEnabled(long ptr, boolean enable);
     private static native int nativeInjectInputEvent(long ptr, InputEvent event,
@@ -217,7 +209,8 @@
     private static native void nativeSetInputDispatchMode(long ptr, boolean enabled, boolean frozen);
     private static native void nativeSetSystemUiVisibility(long ptr, int visibility);
     private static native void nativeSetFocusedApplication(long ptr,
-            InputApplicationHandle application);
+            int displayId, InputApplicationHandle application);
+    private static native void nativeSetFocusedDisplay(long ptr, int displayId);
     private static native boolean nativeTransferTouchFocus(long ptr,
             InputChannel fromChannel, InputChannel toChannel);
     private static native void nativeSetPointerSpeed(long ptr, int speed);
@@ -409,31 +402,8 @@
         nativeReloadDeviceAliases(mPtr);
     }
 
-    private void setDisplayViewportsInternal(DisplayViewport defaultViewport,
-            DisplayViewport externalTouchViewport,
-            List<DisplayViewport> virtualTouchViewports) {
-        if (defaultViewport.valid) {
-            setDisplayViewport(VIEWPORT_INTERNAL, defaultViewport);
-        }
-
-        if (externalTouchViewport.valid) {
-            setDisplayViewport(VIEWPORT_EXTERNAL, externalTouchViewport);
-        } else if (defaultViewport.valid) {
-            setDisplayViewport(VIEWPORT_EXTERNAL, defaultViewport);
-        }
-
-        nativeSetVirtualDisplayViewports(mPtr,
-                virtualTouchViewports.toArray(new DisplayViewport[0]));
-    }
-
-    private void setDisplayViewport(int viewportType, DisplayViewport viewport) {
-        nativeSetDisplayViewport(mPtr, viewportType,
-                viewport.displayId, viewport.orientation,
-                viewport.logicalFrame.left, viewport.logicalFrame.top,
-                viewport.logicalFrame.right, viewport.logicalFrame.bottom,
-                viewport.physicalFrame.left, viewport.physicalFrame.top,
-                viewport.physicalFrame.right, viewport.physicalFrame.bottom,
-                viewport.deviceWidth, viewport.deviceHeight, viewport.uniqueId);
+    private void setDisplayViewportsInternal(List<DisplayViewport> viewports) {
+        nativeSetDisplayViewports(mPtr, viewports.toArray(new DisplayViewport[0]));
     }
 
     /**
@@ -503,15 +473,21 @@
     /**
      * Creates an input channel that will receive all input from the input dispatcher.
      * @param inputChannelName The input channel name.
+     * @param displayId Target display id.
      * @return The input channel.
      */
-    public InputChannel monitorInput(String inputChannelName) {
+    public InputChannel monitorInput(String inputChannelName, int displayId) {
         if (inputChannelName == null) {
             throw new IllegalArgumentException("inputChannelName must not be null.");
         }
 
+        if (displayId < Display.DEFAULT_DISPLAY) {
+            throw new IllegalArgumentException("displayId must >= 0.");
+        }
+
         InputChannel[] inputChannels = InputChannel.openInputChannelPair(inputChannelName);
-        nativeRegisterInputChannel(mPtr, inputChannels[0], null, true);
+        // Register channel for monitor.
+        nativeRegisterInputChannel(mPtr, inputChannels[0], null, displayId);
         inputChannels[0].dispose(); // don't need to retain the Java object reference
         return inputChannels[1];
     }
@@ -528,7 +504,8 @@
             throw new IllegalArgumentException("inputChannel must not be null.");
         }
 
-        nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, false);
+        // Register channel for normal.
+        nativeRegisterInputChannel(mPtr, inputChannel, inputWindowHandle, Display.INVALID_DISPLAY);
     }
 
     /**
@@ -1462,21 +1439,27 @@
         }
     }
 
-    public void setInputWindows(InputWindowHandle[] windowHandles,
-            InputWindowHandle focusedWindowHandle, int displayId) {
-        final IWindow newFocusedWindow =
-            focusedWindowHandle != null ? focusedWindowHandle.clientWindow : null;
-        if (mFocusedWindow != newFocusedWindow) {
-            mFocusedWindow = newFocusedWindow;
-            if (mFocusedWindowHasCapture) {
-                setPointerCapture(false);
-            }
-        }
+    public void setInputWindows(InputWindowHandle[] windowHandles, int displayId) {
         nativeSetInputWindows(mPtr, windowHandles, displayId);
     }
 
-    public void setFocusedApplication(InputApplicationHandle application) {
-        nativeSetFocusedApplication(mPtr, application);
+    public void setFocusedApplication(int displayId, InputApplicationHandle application) {
+        nativeSetFocusedApplication(mPtr, displayId, application);
+    }
+
+    public void setFocusedWindow(InputWindowHandle focusedWindowHandle) {
+        final IWindow newFocusedWindow =
+            focusedWindowHandle != null ? focusedWindowHandle.clientWindow : null;
+        if (mFocusedWindow != newFocusedWindow) {
+            if (mFocusedWindowHasCapture) {
+                setPointerCapture(false);
+            }
+            mFocusedWindow = newFocusedWindow;
+        }
+    }
+
+    public void setFocusedDisplay(int displayId) {
+        nativeSetFocusedDisplay(mPtr, displayId);
     }
 
     @Override
@@ -1491,16 +1474,18 @@
             return;
         }
         setPointerCapture(enabled);
-        try {
-            mFocusedWindow.dispatchPointerCaptureChanged(enabled);
-        } catch (RemoteException ex) {
-            /* ignore */
-        }
     }
 
     private void setPointerCapture(boolean enabled) {
-        mFocusedWindowHasCapture = enabled;
-        nativeSetPointerCapture(mPtr, enabled);
+        if (mFocusedWindowHasCapture != enabled) {
+            mFocusedWindowHasCapture = enabled;
+            try {
+                mFocusedWindow.dispatchPointerCaptureChanged(enabled);
+            } catch (RemoteException ex) {
+                /* ignore */
+            }
+            nativeSetPointerCapture(mPtr, enabled);
+        }
     }
 
     public void setInputDispatchMode(boolean enabled, boolean frozen) {
@@ -2203,11 +2188,8 @@
 
     private final class LocalService extends InputManagerInternal {
         @Override
-        public void setDisplayViewports(DisplayViewport defaultViewport,
-                DisplayViewport externalTouchViewport,
-                List<DisplayViewport> virtualTouchViewports) {
-            setDisplayViewportsInternal(defaultViewport, externalTouchViewport,
-                    virtualTouchViewports);
+        public void setDisplayViewports(List<DisplayViewport> viewports) {
+            setDisplayViewportsInternal(viewports);
         }
 
         @Override
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index a9b0d5c..e37153e 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -66,6 +66,7 @@
 import android.content.res.TypedArray;
 import android.database.ContentObserver;
 import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManagerInternal;
 import android.inputmethodservice.InputMethodService;
 import android.net.Uri;
 import android.os.Binder;
@@ -103,6 +104,8 @@
 import android.util.Slog;
 import android.util.Xml;
 import android.view.ContextThemeWrapper;
+import android.view.Display;
+import android.view.DisplayInfo;
 import android.view.IWindowManager;
 import android.view.InputChannel;
 import android.view.LayoutInflater;
@@ -110,10 +113,12 @@
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
+import android.view.WindowManager.LayoutParams.SoftInputModeFlags;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputBinding;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputConnectionInspector;
+import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
 import android.view.inputmethod.InputMethod;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
@@ -130,6 +135,9 @@
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.inputmethod.IInputContentUriToken;
 import com.android.internal.inputmethod.IInputMethodPrivilegedOperations;
+import com.android.internal.inputmethod.InputMethodDebug;
+import com.android.internal.inputmethod.StartInputReason;
+import com.android.internal.inputmethod.UnbindReason;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.HandlerCaller;
@@ -145,7 +153,6 @@
 import com.android.internal.view.IInputMethodSession;
 import com.android.internal.view.IInputSessionCallback;
 import com.android.internal.view.InputBindResult;
-import com.android.internal.view.InputMethodClient;
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -393,6 +400,7 @@
     };
 
     private void restoreNonVrImeFromSettingsNoCheck() {
+        mIsVrImeStarted = false;
         // switch back to non-VR InputMethod from settings.
         synchronized (mMethodMap) {
             final String lastInputId = mSettings.getSelectedInputMethod();
@@ -421,6 +429,7 @@
         final IInputContext inputContext;
         final int uid;
         final int pid;
+        final int selfReportedDisplayId;
         final InputBinding binding;
         final ClientDeathRecipient clientDeathRecipient;
 
@@ -430,16 +439,18 @@
         @Override
         public String toString() {
             return "ClientState{" + Integer.toHexString(
-                    System.identityHashCode(this)) + " uid " + uid
-                    + " pid " + pid + "}";
+                    System.identityHashCode(this)) + " uid=" + uid
+                    + " pid=" + pid + " displayId=" + selfReportedDisplayId + "}";
         }
 
         ClientState(IInputMethodClient _client, IInputContext _inputContext,
-                int _uid, int _pid, ClientDeathRecipient _clientDeathRecipient) {
+                int _uid, int _pid, int _selfReportedDisplayId,
+                ClientDeathRecipient _clientDeathRecipient) {
             client = _client;
             inputContext = _inputContext;
             uid = _uid;
             pid = _pid;
+            selfReportedDisplayId = _selfReportedDisplayId;
             binding = new InputBinding(null, inputContext.asBinder(), uid, pid);
             clientDeathRecipient = _clientDeathRecipient;
         }
@@ -498,6 +509,7 @@
      *
      * @see #mCurFocusedWindow
      */
+    @SoftInputModeFlags
     int mCurFocusedWindowSoftInputMode;
 
     /**
@@ -515,6 +527,7 @@
      *
      * @see android.view.inputmethod.InputConnectionInspector.MissingMethodFlags
      */
+    @MissingMethodFlags
     int mCurInputContextMissingMethods;
 
     /**
@@ -592,6 +605,11 @@
      */
     int mCurTokenDisplayId = INVALID_DISPLAY;
 
+    final ImeDisplayValidator mImeDisplayValidator;
+
+    /** True if VR IME started by {@link #startVrInputMethodNoCheck}. */
+    boolean mIsVrImeStarted;
+
     /**
      * If non-null, this is the input method service we are currently connected
      * to.
@@ -688,20 +706,21 @@
         final IBinder mImeToken;
         @NonNull
         final String mImeId;
-        // @InputMethodClient.StartInputReason
+        @StartInputReason
         final int mStartInputReason;
         final boolean mRestarting;
         @Nullable
         final IBinder mTargetWindow;
         @NonNull
         final EditorInfo mEditorInfo;
+        @SoftInputModeFlags
         final int mTargetWindowSoftInputMode;
         final int mClientBindSequenceNumber;
 
         StartInputInfo(@NonNull IBinder imeToken, @NonNull String imeId,
-                /* @InputMethodClient.StartInputReason */ int startInputReason, boolean restarting,
+                @StartInputReason int startInputReason, boolean restarting,
                 @Nullable IBinder targetWindow, @NonNull EditorInfo editorInfo,
-                int targetWindowSoftInputMode, int clientBindSequenceNumber) {
+                @SoftInputModeFlags int targetWindowSoftInputMode, int clientBindSequenceNumber) {
             mSequenceNumber = sSequenceNumber.getAndIncrement();
             mTimestamp = SystemClock.uptimeMillis();
             mWallTime = System.currentTimeMillis();
@@ -769,13 +788,14 @@
             String mImeTokenString;
             @NonNull
             String mImeId;
-            /* @InputMethodClient.StartInputReason */
+            @StartInputReason
             int mStartInputReason;
             boolean mRestarting;
             @NonNull
             String mTargetWindowString;
             @NonNull
             EditorInfo mEditorInfo;
+            @SoftInputModeFlags
             int mTargetWindowSoftInputMode;
             int mClientBindSequenceNumber;
 
@@ -832,7 +852,7 @@
                 pw.println(" time=" + dataFormat.format(new Date(entry.mWallTime))
                         + " (timestamp=" + entry.mTimestamp + ")"
                         + " reason="
-                        + InputMethodClient.getStartInputReason(entry.mStartInputReason)
+                        + InputMethodDebug.startInputReasonToString(entry.mStartInputReason)
                         + " restarting=" + entry.mRestarting);
 
                 pw.print(prefix);
@@ -844,7 +864,7 @@
                         + " clientBindSeq=" + entry.mClientBindSequenceNumber);
 
                 pw.print(prefix);
-                pw.println(" softInputMode=" + InputMethodClient.softInputModeToString(
+                pw.println(" softInputMode=" + InputMethodDebug.softInputModeToString(
                                 entry.mTargetWindowSoftInputMode));
 
                 pw.print(prefix);
@@ -990,6 +1010,7 @@
                     // set this is as current inputMethod without updating settings.
                     setInputMethodEnabledLocked(info.getId(), true);
                     setInputMethodLocked(info.getId(), NOT_A_SUBTYPE_ID);
+                    mIsVrImeStarted = true;
                     break;
                 }
             }
@@ -1386,6 +1407,13 @@
         mIWindowManager = IWindowManager.Stub.asInterface(
                 ServiceManager.getService(Context.WINDOW_SERVICE));
         mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
+        final DisplayManagerInternal displayManagerInternal = LocalServices.getService(
+                DisplayManagerInternal.class);
+        mImeDisplayValidator = (displayId) -> {
+            final DisplayInfo displayInfo = displayManagerInternal.getDisplayInfo(displayId);
+            return displayInfo != null
+                    && (displayInfo.flags & Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0;
+        };
         mCaller = new HandlerCaller(context, null, new HandlerCaller.Callback() {
             @Override
             public void executeMessage(Message msg) {
@@ -1497,7 +1525,7 @@
         // TODO: Is it really possible that switchUserLocked() happens before system ready?
         if (mSystemReady) {
             hideCurrentInputLocked(0, null);
-            resetCurrentMethodAndClient(InputMethodClient.UNBIND_REASON_SWITCH_USER);
+            resetCurrentMethodAndClient(UnbindReason.SWITCH_USER);
             buildInputMethodListLocked(initialUserSwitch);
             if (TextUtils.isEmpty(mSettings.getSelectedInputMethod())) {
                 // This is the first time of the user switch and
@@ -1505,11 +1533,6 @@
                 resetDefaultImeLocked(mContext);
             }
             updateFromSettingsLocked(true);
-            try {
-                startInputInnerLocked();
-            } catch (RuntimeException e) {
-                Slog.w(TAG, "Unexpected exception", e);
-            }
         }
 
         if (initialUserSwitch) {
@@ -1585,12 +1608,6 @@
                 InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mIPackageManager,
                         mSettings.getEnabledInputMethodListLocked(), currentUserId,
                         mContext.getBasePackageName());
-
-                try {
-                    startInputInnerLocked();
-                } catch (RuntimeException e) {
-                    Slog.w(TAG, "Unexpected exception", e);
-                }
             }
         }
     }
@@ -1738,22 +1755,28 @@
      * {@link InputMethodManagerService}.
      *
      * <p>As a general principle, IPCs from the application process that take
-     * {@link InputMethodClient} will be rejected without this step.</p>
+     * {@link IInputMethodClient} will be rejected without this step.</p>
      *
      * @param client {@link android.os.Binder} proxy that is associated with the singleton instance
      *               of {@link android.view.inputmethod.InputMethodManager} that runs on the client
      *               process
      * @param inputContext communication channel for the dummy
      *                     {@link android.view.inputmethod.InputConnection}
+     * @param selfReportedDisplayId self-reported display ID to which the client is associated.
+     *                              Whether the client is still allowed to access to this display
+     *                              or not needs to be evaluated every time the client interacts
+     *                              with the display
      */
     @Override
-    public void addClient(IInputMethodClient client, IInputContext inputContext) {
+    public void addClient(IInputMethodClient client, IInputContext inputContext,
+            int selfReportedDisplayId) {
         final int callerUid = Binder.getCallingUid();
         final int callerPid = Binder.getCallingPid();
         synchronized (mMethodMap) {
             // TODO: Optimize this linear search.
             for (ClientState state : mClients.values()) {
-                if (state.uid == callerUid && state.pid == callerPid) {
+                if (state.uid == callerUid && state.pid == callerPid
+                        && state.selfReportedDisplayId == selfReportedDisplayId) {
                     throw new SecurityException("uid=" + callerUid + "/pid=" + callerPid
                             + " is already registered");
                 }
@@ -1764,8 +1787,18 @@
             } catch (RemoteException e) {
                 throw new IllegalStateException(e);
             }
-            mClients.put(client.asBinder(),
-                    new ClientState(client, inputContext, callerUid, callerPid, deathRecipient));
+            // We cannot fully avoid race conditions where the client UID already lost the access to
+            // the given self-reported display ID, even if the client is not maliciously reporting
+            // a fake display ID. Unconditionally returning SecurityException just because the
+            // client doesn't pass display ID verification can cause many test failures hence not an
+            // option right now.  At the same time
+            //    context.getSystemService(InputMethodManager.class)
+            // is expected to return a valid non-null instance at any time if we do not choose to
+            // have the client crash.  Thus we do not verify the display ID at all here.  Instead we
+            // later check the display ID every time the client needs to interact with the specified
+            // display.
+            mClients.put(client.asBinder(), new ClientState(client, inputContext, callerUid,
+                    callerPid, selfReportedDisplayId, deathRecipient));
         }
     }
 
@@ -1801,8 +1834,7 @@
          }
     }
 
-    void unbindCurrentClientLocked(
-            /* @InputMethodClient.UnbindReason */ final int unbindClientReason) {
+    void unbindCurrentClientLocked(@UnbindReason int unbindClientReason) {
         if (mCurClient != null) {
             if (DEBUG) Slog.v(TAG, "unbindCurrentInputLocked: client="
                     + mCurClient.client.asBinder());
@@ -1848,8 +1880,7 @@
 
     @GuardedBy("mMethodMap")
     @NonNull
-    InputBindResult attachNewInputLocked(
-            /* @InputMethodClient.StartInputReason */ final int startInputReason, boolean initial) {
+    InputBindResult attachNewInputLocked(@StartInputReason int startInputReason, boolean initial) {
         if (!mBoundToMethod) {
             executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
                     MSG_BIND_INPUT, mCurMethod, mCurClient.binding));
@@ -1879,14 +1910,21 @@
     @GuardedBy("mMethodMap")
     @NonNull
     InputBindResult startInputUncheckedLocked(@NonNull ClientState cs, IInputContext inputContext,
-            /* @InputConnectionInspector.missingMethods */ final int missingMethods,
-            @NonNull EditorInfo attribute, int controlFlags,
-            /* @InputMethodClient.StartInputReason */ final int startInputReason) {
+            @MissingMethodFlags int missingMethods, @NonNull EditorInfo attribute, int controlFlags,
+            @StartInputReason int startInputReason) {
         // If no method is currently selected, do nothing.
         if (mCurMethodId == null) {
             return InputBindResult.NO_IME;
         }
 
+        if (!mSystemReady) {
+            // If the system is not yet ready, we shouldn't be running third
+            // party code.
+            return new InputBindResult(
+                    InputBindResult.ResultCode.ERROR_SYSTEM_NOT_READY,
+                    null, null, mCurMethodId, mCurSeq);
+        }
+
         if (!InputMethodUtils.checkIfPackageBelongsToUid(mAppOpsManager, cs.uid,
                 attribute.packageName)) {
             Slog.e(TAG, "Rejecting this client as it reported an invalid package name."
@@ -1894,12 +1932,21 @@
             return InputBindResult.INVALID_PACKAGE_NAME;
         }
 
+        if (!mWindowManagerInternal.isUidAllowedOnDisplay(cs.selfReportedDisplayId, cs.uid)) {
+            // Wait, the client no longer has access to the display.
+            return InputBindResult.INVALID_DISPLAY_ID;
+        }
+        // Compute the final shown display ID with validated cs.selfReportedDisplayId for this
+        // session & other conditions.
+        final int displayIdToShowIme = computeImeDisplayIdForTarget(
+                cs.selfReportedDisplayId, mIsVrImeStarted, mImeDisplayValidator);
+
         if (mCurClient != cs) {
             // Was the keyguard locked when switching over to the new client?
             mCurClientInKeyguard = isKeyguardLocked();
             // If the client is changing, we need to switch over to the new
             // one.
-            unbindCurrentClientLocked(InputMethodClient.UNBIND_REASON_SWITCH_CLIENT);
+            unbindCurrentClientLocked(UnbindReason.SWITCH_CLIENT);
             if (DEBUG) Slog.v(TAG, "switching to client: client="
                     + cs.client.asBinder() + " keyguard=" + mCurClientInKeyguard);
 
@@ -1918,9 +1965,10 @@
         mCurAttribute = attribute;
 
         // Check if the input method is changing.
-        final int displayId = mWindowManagerInternal.getDisplayIdForWindow(
-                mCurFocusedWindow);
-        if (mCurId != null && mCurId.equals(mCurMethodId) && displayId == mCurTokenDisplayId) {
+        // We expect the caller has already verified that the client is allowed to access this
+        // display ID.
+        if (mCurId != null && mCurId.equals(mCurMethodId)
+                && displayIdToShowIme == mCurTokenDisplayId) {
             if (cs.curSession != null) {
                 // Fast case: if we are already connected to the input method,
                 // then just return it.
@@ -1954,23 +2002,6 @@
             }
         }
 
-        return startInputInnerLocked();
-    }
-
-    @GuardedBy("mMethodMap")
-    InputBindResult startInputInnerLocked() {
-        if (mCurMethodId == null) {
-            return InputBindResult.NO_IME;
-        }
-
-        if (!mSystemReady) {
-            // If the system is not yet ready, we shouldn't be running third
-            // party code.
-            return new InputBindResult(
-                    InputBindResult.ResultCode.ERROR_SYSTEM_NOT_READY,
-                    null, null, mCurMethodId, mCurSeq);
-        }
-
         InputMethodInfo info = mMethodMap.get(mCurMethodId);
         if (info == null) {
             throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
@@ -1984,14 +2015,13 @@
                 com.android.internal.R.string.input_method_binding_label);
         mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
                 mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
-        final int displayId = mWindowManagerInternal.getDisplayIdForWindow(mCurFocusedWindow);
-        mCurTokenDisplayId = (displayId != INVALID_DISPLAY) ? displayId : DEFAULT_DISPLAY;
 
         if (bindCurrentInputMethodServiceLocked(mCurIntent, this, IME_CONNECTION_BIND_FLAGS)) {
             mLastBindTime = SystemClock.uptimeMillis();
             mHaveConnection = true;
             mCurId = info.getId();
             mCurToken = new Binder();
+            mCurTokenDisplayId = displayIdToShowIme;
             try {
                 if (DEBUG) {
                     Slog.v(TAG, "Adding window token: " + mCurToken + " for display: "
@@ -2009,8 +2039,33 @@
         return InputBindResult.IME_NOT_CONNECTED;
     }
 
-    @Override
-    public void finishInput(IInputMethodClient client) {
+    @FunctionalInterface
+    interface ImeDisplayValidator {
+        boolean displayCanShowIme(int displayId);
+    }
+
+    /**
+     * Find the display where the IME should be shown.
+     *
+     * @param displayId the ID of the display where the IME client target is.
+     * @param isVrImeStarted {@code true} if VR IME started, {@code false} otherwise.
+     * @param checker instance of {@link ImeDisplayValidator} which is used for
+     *                checking display config to adjust the final target display.
+     * @return The ID of the display where the IME should be shown.
+     */
+    static int computeImeDisplayIdForTarget(int displayId, boolean isVrImeStarted,
+            @NonNull ImeDisplayValidator checker) {
+        // For VR IME, we always show in default display.
+        if (isVrImeStarted) {
+            return DEFAULT_DISPLAY;
+        }
+        if (displayId == DEFAULT_DISPLAY || displayId == INVALID_DISPLAY) {
+            // We always assume that the default display id suitable to show the IME window.
+            return DEFAULT_DISPLAY;
+        }
+        // Show IME in default display when the display with IME target doesn't support system
+        // decorations.
+        return checker.displayCanShowIme(displayId) ? displayId : DEFAULT_DISPLAY;
     }
 
     @Override
@@ -2045,7 +2100,7 @@
                     mCurClient.curSession = new SessionState(mCurClient,
                             method, session, channel);
                     InputBindResult res = attachNewInputLocked(
-                            InputMethodClient.START_INPUT_REASON_SESSION_CREATED_BY_IME, true);
+                            StartInputReason.SESSION_CREATED_BY_IME, true);
                     if (res.method != null) {
                         executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO(
                                 MSG_BIND_CLIENT, mCurClient.client, res));
@@ -2087,8 +2142,7 @@
         clearCurMethodLocked();
     }
 
-    void resetCurrentMethodAndClient(
-            /* @InputMethodClient.UnbindReason */ final int unbindClientReason) {
+    void resetCurrentMethodAndClient(@UnbindReason int unbindClientReason) {
         mCurMethodId = null;
         unbindCurrentMethodLocked();
         unbindCurrentClientLocked(unbindClientReason);
@@ -2165,7 +2219,7 @@
                 mLastBindTime = SystemClock.uptimeMillis();
                 mShowRequested = mInputShown;
                 mInputShown = false;
-                unbindCurrentClientLocked(InputMethodClient.UNBIND_REASON_DISCONNECT_IME);
+                unbindCurrentClientLocked(UnbindReason.DISCONNECT_IME);
             }
         }
     }
@@ -2476,12 +2530,12 @@
                 setInputMethodLocked(id, mSettings.getSelectedInputMethodSubtypeId(id));
             } catch (IllegalArgumentException e) {
                 Slog.w(TAG, "Unknown input method from prefs: " + id, e);
-                resetCurrentMethodAndClient(InputMethodClient.UNBIND_REASON_SWITCH_IME_FAILED);
+                resetCurrentMethodAndClient(UnbindReason.SWITCH_IME_FAILED);
             }
             mShortcutInputMethodsAndSubtypes.clear();
         } else {
             // There is no longer an input method set, so stop any current one.
-            resetCurrentMethodAndClient(InputMethodClient.UNBIND_REASON_NO_IME);
+            resetCurrentMethodAndClient(UnbindReason.NO_IME);
         }
         // Here is not the perfect place to reset the switching controller. Ideally
         // mSwitchingController and mSettings should be able to share the same state.
@@ -2559,7 +2613,7 @@
                 intent.putExtra("input_method_id", id);
                 mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT);
             }
-            unbindCurrentClientLocked(InputMethodClient.UNBIND_REASON_SWITCH_IME);
+            unbindCurrentClientLocked(UnbindReason.SWITCH_IME);
         } finally {
             Binder.restoreCallingIdentity(ident);
         }
@@ -2584,7 +2638,8 @@
                     if (cs == null) {
                         throw new IllegalArgumentException("unknown client " + client.asBinder());
                     }
-                    if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid)) {
+                    if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid,
+                            cs.selfReportedDisplayId)) {
                         Slog.w(TAG, "Ignoring showSoftInput of uid " + uid + ": " + client);
                         return false;
                     }
@@ -2668,7 +2723,8 @@
                     if (cs == null) {
                         throw new IllegalArgumentException("unknown client " + client.asBinder());
                     }
-                    if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid)) {
+                    if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid,
+                            cs.selfReportedDisplayId)) {
                         if (DEBUG) {
                             Slog.w(TAG, "Ignoring hideSoftInput of uid " + uid + ": " + client);
                         }
@@ -2731,11 +2787,10 @@
     @NonNull
     @Override
     public InputBindResult startInputOrWindowGainedFocus(
-            /* @InputMethodClient.StartInputReason */ final int startInputReason,
-            IInputMethodClient client, IBinder windowToken, int controlFlags, int softInputMode,
-            int windowFlags, @Nullable EditorInfo attribute, IInputContext inputContext,
-            /* @InputConnectionInspector.missingMethods */ final int missingMethods,
-            int unverifiedTargetSdkVersion) {
+            @StartInputReason int startInputReason, IInputMethodClient client, IBinder windowToken,
+            int controlFlags, @SoftInputModeFlags int softInputMode, int windowFlags,
+            @Nullable EditorInfo attribute, IInputContext inputContext,
+            @MissingMethodFlags int missingMethods, int unverifiedTargetSdkVersion) {
         if (windowToken == null) {
             Slog.e(TAG, "windowToken cannot be null.");
             return InputBindResult.NULL;
@@ -2746,7 +2801,7 @@
         if (result == null) {
             // This must never happen, but just in case.
             Slog.wtf(TAG, "InputBindResult is @NonNull. startInputReason="
-                    + InputMethodClient.getStartInputReason(startInputReason)
+                    + InputMethodDebug.startInputReasonToString(startInputReason)
                     + " windowFlags=#" + Integer.toHexString(windowFlags)
                     + " editorInfo=" + attribute);
             return InputBindResult.NULL;
@@ -2756,27 +2811,27 @@
 
     @NonNull
     private InputBindResult startInputOrWindowGainedFocusInternal(
-            /* @InputMethodClient.StartInputReason */ final int startInputReason,
-            IInputMethodClient client, @NonNull IBinder windowToken, int controlFlags,
-            /* @android.view.WindowManager.LayoutParams.SoftInputModeFlags */ int softInputMode,
+            @StartInputReason int startInputReason, IInputMethodClient client,
+            @NonNull IBinder windowToken, int controlFlags, @SoftInputModeFlags int softInputMode,
             int windowFlags, EditorInfo attribute, IInputContext inputContext,
-            /* @InputConnectionInspector.missingMethods */  final int missingMethods,
-            int unverifiedTargetSdkVersion) {
+            @MissingMethodFlags int missingMethods, int unverifiedTargetSdkVersion) {
         // Needs to check the validity before clearing calling identity
         final boolean calledFromValidUser = calledFromValidUser();
         InputBindResult res = null;
         long ident = Binder.clearCallingIdentity();
         try {
+            final int windowDisplayId =
+                    mWindowManagerInternal.getDisplayIdForWindow(windowToken);
             synchronized (mMethodMap) {
                 if (DEBUG) Slog.v(TAG, "startInputOrWindowGainedFocusInternal: reason="
-                        + InputMethodClient.getStartInputReason(startInputReason)
+                        + InputMethodDebug.startInputReasonToString(startInputReason)
                         + " client=" + client.asBinder()
                         + " inputContext=" + inputContext
                         + " missingMethods="
                         + InputConnectionInspector.getMissingMethodFlagsAsString(missingMethods)
                         + " attribute=" + attribute
                         + " controlFlags=#" + Integer.toHexString(controlFlags)
-                        + " softInputMode=" + InputMethodClient.softInputModeToString(softInputMode)
+                        + " softInputMode=" + InputMethodDebug.softInputModeToString(softInputMode)
                         + " windowFlags=#" + Integer.toHexString(windowFlags)
                         + " unverifiedTargetSdkVersion=" + unverifiedTargetSdkVersion);
 
@@ -2785,8 +2840,15 @@
                     throw new IllegalArgumentException("unknown client "
                             + client.asBinder());
                 }
+                if (cs.selfReportedDisplayId != windowDisplayId) {
+                    Slog.e(TAG, "startInputOrWindowGainedFocusInternal: display ID mismatch."
+                            + " from client:" + cs.selfReportedDisplayId
+                            + " from window:" + windowDisplayId);
+                    return InputBindResult.DISPLAY_ID_MISMATCH;
+                }
 
-                if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid)) {
+                if (!mWindowManagerInternal.isInputMethodClientFocus(cs.uid, cs.pid,
+                        cs.selfReportedDisplayId)) {
                     // Check with the window manager to make sure this client actually
                     // has a window with focus.  If not, reject.  This is thread safe
                     // because if the focus changes some time before or after, the
@@ -2858,9 +2920,9 @@
                                 // If focused display changed, we should unbind current method
                                 // to make app window in previous display relayout after Ime
                                 // window token removed.
-                                final int newFocusDisplayId =
-                                        mWindowManagerInternal.getDisplayIdForWindow(windowToken);
-                                if (newFocusDisplayId != mCurTokenDisplayId) {
+                                // Note that we can trust client's display ID as long as it matches
+                                // to the display ID obtained from the window.
+                                if (cs.selfReportedDisplayId != mCurTokenDisplayId) {
                                     unbindCurrentMethodLocked();
                                 }
                             }
@@ -2958,6 +3020,7 @@
     }
 
     private boolean canShowInputMethodPickerLocked(IInputMethodClient client) {
+        // TODO(yukawa): multi-display support.
         final int uid = Binder.getCallingUid();
         if (UserHandle.getAppId(uid) == Process.SYSTEM_UID) {
             return true;
@@ -3034,6 +3097,7 @@
     @Override
     public void showInputMethodAndSubtypeEnablerFromClient(
             IInputMethodClient client, String inputMethodId) {
+        // TODO(yukawa): Should we verify the display ID?
         if (!calledFromValidUser()) {
             return;
         }
@@ -3229,6 +3293,7 @@
      */
     @Override
     public int getInputMethodWindowVisibleHeight() {
+        // TODO(yukawa): Should we verify the display ID?
         return mWindowManagerInternal.getInputMethodWindowVisibleHeight(mCurTokenDisplayId);
     }
 
@@ -4564,7 +4629,7 @@
             p.println("  mCurClient=" + client + " mCurSeq=" + mCurSeq);
             p.println("  mCurFocusedWindow=" + mCurFocusedWindow
                     + " softInputMode=" +
-                    InputMethodClient.softInputModeToString(mCurFocusedWindowSoftInputMode)
+                    InputMethodDebug.softInputModeToString(mCurFocusedWindowSoftInputMode)
                     + " client=" + mCurFocusedWindowClient);
             focusedWindowClient = mCurFocusedWindowClient;
             p.println("  mCurId=" + mCurId + " mHaveConnection=" + mHaveConnection
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 389782a..dd993b8 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -877,14 +877,17 @@
             // This may throw a SecurityException.
             jobStatus.prepareLocked(ActivityManager.getService());
 
-            if (toCancel != null) {
-                cancelJobImplLocked(toCancel, jobStatus, "job rescheduled by app");
-            }
             if (work != null) {
                 // If work has been supplied, enqueue it into the new job.
                 jobStatus.enqueueWorkLocked(ActivityManager.getService(), work);
             }
-            startTrackingJobLocked(jobStatus, toCancel);
+
+            if (toCancel != null) {
+                // Implicitly replaces the existing job record with the new instance
+                cancelJobImplLocked(toCancel, jobStatus, "job rescheduled by app");
+            } else {
+                startTrackingJobLocked(jobStatus, null);
+            }
             StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED,
                     uId, null, jobStatus.getBatteryName(),
                     StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__SCHEDULED,
@@ -1013,6 +1016,12 @@
         }
     }
 
+    /**
+     * Cancel the given job, stopping it if it's currently executing.  If {@code incomingJob}
+     * is null, the cancelled job is removed outright from the system.  If
+     * {@code incomingJob} is non-null, it replaces {@code cancelled} in the store of
+     * currently scheduled jobs.
+     */
     private void cancelJobImplLocked(JobStatus cancelled, JobStatus incomingJob, String reason) {
         if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString());
         cancelled.unprepareLocked(ActivityManager.getService());
@@ -1023,6 +1032,11 @@
         }
         // Cancel if running.
         stopJobOnServiceContextLocked(cancelled, JobParameters.REASON_CANCELED, reason);
+        // If this is a replacement, bring in the new version of the job
+        if (incomingJob != null) {
+            if (DEBUG) Slog.i(TAG, "Tracking replacement job " + incomingJob.toShortString());
+            startTrackingJobLocked(incomingJob, cancelled);
+        }
         reportActiveLocked();
     }
 
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 0c66c5b..6989c33 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -55,6 +55,8 @@
  * Each app can have a different default networks or different connectivity
  * status due to user-requested network policies, so we need to check
  * constraints on a per-UID basis.
+ *
+ * Test: atest com.android.server.job.controllers.ConnectivityControllerTest
  */
 public final class ConnectivityController extends StateController implements
         ConnectivityManager.OnNetworkActiveListener {
@@ -65,8 +67,9 @@
     private final ConnectivityManager mConnManager;
     private final NetworkPolicyManager mNetPolicyManager;
 
+    /** List of tracked jobs keyed by source UID. */
     @GuardedBy("mLock")
-    private final ArraySet<JobStatus> mTrackedJobs = new ArraySet<>();
+    private final SparseArray<ArraySet<JobStatus>> mTrackedJobs = new SparseArray<>();
 
     public ConnectivityController(JobSchedulerService service) {
         super(service);
@@ -87,7 +90,12 @@
     public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
         if (jobStatus.hasConnectivityConstraint()) {
             updateConstraintsSatisfied(jobStatus);
-            mTrackedJobs.add(jobStatus);
+            ArraySet<JobStatus> jobs = mTrackedJobs.get(jobStatus.getSourceUid());
+            if (jobs == null) {
+                jobs = new ArraySet<>();
+                mTrackedJobs.put(jobStatus.getSourceUid(), jobs);
+            }
+            jobs.add(jobStatus);
             jobStatus.setTrackingController(JobStatus.TRACKING_CONNECTIVITY);
         }
     }
@@ -97,7 +105,10 @@
     public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob,
             boolean forUpdate) {
         if (jobStatus.clearTrackingController(JobStatus.TRACKING_CONNECTIVITY)) {
-            mTrackedJobs.remove(jobStatus);
+            ArraySet<JobStatus> jobs = mTrackedJobs.get(jobStatus.getSourceUid());
+            if (jobs != null) {
+                jobs.remove(jobStatus);
+            }
         }
     }
 
@@ -235,47 +246,26 @@
     /**
      * Update any jobs tracked by this controller that match given filters.
      *
-     * @param filterUid only update jobs belonging to this UID, or {@code -1} to
-     *            update all tracked jobs.
+     * @param filterUid     only update jobs belonging to this UID, or {@code -1} to
+     *                      update all tracked jobs.
      * @param filterNetwork only update jobs that would use this
-     *            {@link Network}, or {@code null} to update all tracked jobs.
+     *                      {@link Network}, or {@code null} to update all tracked jobs.
      */
     private void updateTrackedJobs(int filterUid, Network filterNetwork) {
         synchronized (mLock) {
             // Since this is a really hot codepath, temporarily cache any
             // answers that we get from ConnectivityManager.
-            final SparseArray<Network> uidToNetwork = new SparseArray<>();
             final SparseArray<NetworkCapabilities> networkToCapabilities = new SparseArray<>();
 
             boolean changed = false;
-            for (int i = mTrackedJobs.size() - 1; i >= 0; i--) {
-                final JobStatus js = mTrackedJobs.valueAt(i);
-                final int uid = js.getSourceUid();
-
-                final boolean uidMatch = (filterUid == -1 || filterUid == uid);
-                if (uidMatch) {
-                    Network network = uidToNetwork.get(uid);
-                    if (network == null) {
-                        network = mConnManager.getActiveNetworkForUid(uid);
-                        uidToNetwork.put(uid, network);
-                    }
-
-                    // Update either when we have a network match, or when the
-                    // job hasn't yet been evaluated against the currently
-                    // active network; typically when we just lost a network.
-                    final boolean networkMatch = (filterNetwork == null
-                            || Objects.equals(filterNetwork, network));
-                    final boolean forceUpdate = !Objects.equals(js.network, network);
-                    if (networkMatch || forceUpdate) {
-                        final int netId = network != null ? network.netId : -1;
-                        NetworkCapabilities capabilities = networkToCapabilities.get(netId);
-                        if (capabilities == null) {
-                            capabilities = mConnManager.getNetworkCapabilities(network);
-                            networkToCapabilities.put(netId, capabilities);
-                        }
-                        changed |= updateConstraintsSatisfied(js, network, capabilities);
-                    }
+            if (filterUid == -1) {
+                for (int i = mTrackedJobs.size() - 1; i >= 0; i--) {
+                    changed |= updateTrackedJobsLocked(mTrackedJobs.valueAt(i),
+                            filterNetwork, networkToCapabilities);
                 }
+            } else {
+                changed = updateTrackedJobsLocked(mTrackedJobs.get(filterUid),
+                        filterNetwork, networkToCapabilities);
             }
             if (changed) {
                 mStateChangedListener.onControllerStateChanged();
@@ -283,6 +273,36 @@
         }
     }
 
+    private boolean updateTrackedJobsLocked(ArraySet<JobStatus> jobs, Network filterNetwork,
+            SparseArray<NetworkCapabilities> networkToCapabilities) {
+        if (jobs == null || jobs.size() == 0) {
+            return false;
+        }
+
+        final Network network = mConnManager.getActiveNetworkForUid(jobs.valueAt(0).getSourceUid());
+        final int netId = network != null ? network.netId : -1;
+        NetworkCapabilities capabilities = networkToCapabilities.get(netId);
+        if (capabilities == null) {
+            capabilities = mConnManager.getNetworkCapabilities(network);
+            networkToCapabilities.put(netId, capabilities);
+        }
+        final boolean networkMatch = (filterNetwork == null
+                || Objects.equals(filterNetwork, network));
+
+        boolean changed = false;
+        for (int i = jobs.size() - 1; i >= 0; i--) {
+            final JobStatus js = jobs.valueAt(i);
+
+            // Update either when we have a network match, or when the
+            // job hasn't yet been evaluated against the currently
+            // active network; typically when we just lost a network.
+            if (networkMatch || !Objects.equals(js.network, network)) {
+                changed |= updateConstraintsSatisfied(js, network, capabilities);
+            }
+        }
+        return changed;
+    }
+
     /**
      * We know the network has just come up. We want to run any jobs that are ready.
      */
@@ -290,12 +310,15 @@
     public void onNetworkActive() {
         synchronized (mLock) {
             for (int i = mTrackedJobs.size()-1; i >= 0; i--) {
-                final JobStatus js = mTrackedJobs.valueAt(i);
-                if (js.isReady()) {
-                    if (DEBUG) {
-                        Slog.d(TAG, "Running " + js + " due to network activity.");
+                final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
+                for (int j = jobs.size() - 1; j >= 0; j--) {
+                    final JobStatus js = jobs.valueAt(j);
+                    if (js.isReady()) {
+                        if (DEBUG) {
+                            Slog.d(TAG, "Running " + js + " due to network activity.");
+                        }
+                        mStateChangedListener.onRunJobNow(js);
                     }
-                    mStateChangedListener.onRunJobNow(js);
                 }
             }
         }
@@ -334,8 +357,12 @@
     public void dumpControllerStateLocked(IndentingPrintWriter pw,
             Predicate<JobStatus> predicate) {
         for (int i = 0; i < mTrackedJobs.size(); i++) {
-            final JobStatus js = mTrackedJobs.valueAt(i);
-            if (predicate.test(js)) {
+            final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
+            for (int j = 0; j < jobs.size(); j++) {
+                final JobStatus js = jobs.valueAt(j);
+                if (!predicate.test(js)) {
+                    continue;
+                }
                 pw.print("#");
                 js.printUniqueId(pw);
                 pw.print(" from ");
@@ -355,20 +382,26 @@
         final long mToken = proto.start(StateControllerProto.CONNECTIVITY);
 
         for (int i = 0; i < mTrackedJobs.size(); i++) {
-            final JobStatus js = mTrackedJobs.valueAt(i);
-            if (!predicate.test(js)) {
-                continue;
+            final ArraySet<JobStatus> jobs = mTrackedJobs.valueAt(i);
+            for (int j = 0; j < jobs.size(); j++) {
+                final JobStatus js = jobs.valueAt(j);
+                if (!predicate.test(js)) {
+                    continue;
+                }
+                final long jsToken = proto.start(
+                        StateControllerProto.ConnectivityController.TRACKED_JOBS);
+                js.writeToShortProto(proto,
+                        StateControllerProto.ConnectivityController.TrackedJob.INFO);
+                proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
+                        js.getSourceUid());
+                NetworkRequest rn = js.getJob().getRequiredNetwork();
+                if (rn != null) {
+                    rn.writeToProto(proto,
+                            StateControllerProto.ConnectivityController.TrackedJob
+                                    .REQUIRED_NETWORK);
+                }
+                proto.end(jsToken);
             }
-            final long jsToken = proto.start(StateControllerProto.ConnectivityController.TRACKED_JOBS);
-            js.writeToShortProto(proto, StateControllerProto.ConnectivityController.TrackedJob.INFO);
-            proto.write(StateControllerProto.ConnectivityController.TrackedJob.SOURCE_UID,
-                    js.getSourceUid());
-            NetworkRequest rn = js.getJob().getRequiredNetwork();
-            if (rn != null) {
-                rn.writeToProto(proto,
-                        StateControllerProto.ConnectivityController.TrackedJob.REQUIRED_NETWORK);
-            }
-            proto.end(jsToken);
         }
 
         proto.end(mToken);
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 3f8941d..4ece538d 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -57,6 +57,8 @@
  * This isn't strictly necessary because each controller is only interested in a specific field,
  * and the receivers that are listening for global state change will all run on the main looper,
  * but we don't enforce that so this is safer.
+ *
+ * Test: atest com.android.server.job.controllers.JobStatusTest
  * @hide
  */
 public final class JobStatus {
@@ -154,7 +156,9 @@
 
     // Constraints.
     final int requiredConstraints;
+    private final int mRequiredConstraintsOfInterest;
     int satisfiedConstraints = 0;
+    private int mSatisfiedConstraintsOfInterest = 0;
 
     // Set to true if doze constraint was satisfied due to app being whitelisted.
     public boolean dozeWhitelisted;
@@ -265,6 +269,28 @@
 
     private long totalNetworkBytes = JobInfo.NETWORK_BYTES_UNKNOWN;
 
+    /////// Booleans that track if a job is ready to run. They should be updated whenever dependent
+    /////// states change.
+
+    /**
+     * The deadline for the job has passed. This is only good for non-periodic jobs. A periodic job
+     * should only run if its constraints are satisfied.
+     * Computed as: NOT periodic AND has deadline constraint AND deadline constraint satisfied.
+     */
+    private boolean mReadyDeadlineSatisfied;
+
+    /**
+     * The device isn't Dozing or this job will be in the foreground. This implicit constraint must
+     * be satisfied.
+     */
+    private boolean mReadyNotDozing;
+
+    /**
+     * The job is not restricted from running in the background (due to Battery Saver). This
+     * implicit constraint must be satisfied.
+     */
+    private boolean mReadyNotRestrictedInBg;
+
     /** Provide a handle to the service that this job will be run on. */
     public int getServiceToken() {
         return callingUid;
@@ -349,6 +375,8 @@
             requiredConstraints |= CONSTRAINT_CONTENT_TRIGGER;
         }
         this.requiredConstraints = requiredConstraints;
+        mRequiredConstraintsOfInterest = requiredConstraints & CONSTRAINTS_OF_INTEREST;
+        mReadyNotDozing = (job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
 
         mLastSuccessfulRunTime = lastSuccessfulRunTime;
         mLastFailedRunTime = lastFailedRunTime;
@@ -865,7 +893,12 @@
     }
 
     boolean setDeadlineConstraintSatisfied(boolean state) {
-        return setConstraintSatisfied(CONSTRAINT_DEADLINE, state);
+        if (setConstraintSatisfied(CONSTRAINT_DEADLINE, state)) {
+            // The constraint was changed. Update the ready flag.
+            mReadyDeadlineSatisfied = !job.isPeriodic() && hasDeadlineConstraint() && state;
+            return true;
+        }
+        return false;
     }
 
     boolean setIdleConstraintSatisfied(boolean state) {
@@ -882,11 +915,21 @@
 
     boolean setDeviceNotDozingConstraintSatisfied(boolean state, boolean whitelisted) {
         dozeWhitelisted = whitelisted;
-        return setConstraintSatisfied(CONSTRAINT_DEVICE_NOT_DOZING, state);
+        if (setConstraintSatisfied(CONSTRAINT_DEVICE_NOT_DOZING, state)) {
+            // The constraint was changed. Update the ready flag.
+            mReadyNotDozing = state || (job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
+            return true;
+        }
+        return false;
     }
 
     boolean setBackgroundNotRestrictedConstraintSatisfied(boolean state) {
-        return setConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED, state);
+        if (setConstraintSatisfied(CONSTRAINT_BACKGROUND_NOT_RESTRICTED, state)) {
+            // The constraint was changed. Update the ready flag.
+            mReadyNotRestrictedInBg = state;
+            return true;
+        }
+        return false;
     }
 
     boolean setUidActive(final boolean newActiveState) {
@@ -903,6 +946,7 @@
             return false;
         }
         satisfiedConstraints = (satisfiedConstraints&~constraint) | (state ? constraint : 0);
+        mSatisfiedConstraintsOfInterest = satisfiedConstraints & CONSTRAINTS_OF_INTEREST;
         return true;
     }
 
@@ -933,24 +977,15 @@
     /**
      * @return Whether or not this job is ready to run, based on its requirements. This is true if
      * the constraints are satisfied <strong>or</strong> the deadline on the job has expired.
-     * TODO: This function is called a *lot*.  We should probably just have it check an
-     * already-computed boolean, which we updated whenever we see one of the states it depends
-     * on here change.
      */
     public boolean isReady() {
         // Deadline constraint trumps other constraints (except for periodic jobs where deadline
         // is an implementation detail. A periodic job should only run if its constraints are
         // satisfied).
-        // AppNotIdle implicit constraint must be satisfied
         // DeviceNotDozing implicit constraint must be satisfied
         // NotRestrictedInBackground implicit constraint must be satisfied
-        final boolean deadlineSatisfied = (!job.isPeriodic() && hasDeadlineConstraint()
-                && (satisfiedConstraints & CONSTRAINT_DEADLINE) != 0);
-        final boolean notDozing = (satisfiedConstraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0
-                || (job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
-        final boolean notRestrictedInBg =
-                (satisfiedConstraints & CONSTRAINT_BACKGROUND_NOT_RESTRICTED) != 0;
-        return (isConstraintsSatisfied() || deadlineSatisfied) && notDozing && notRestrictedInBg;
+        return mReadyNotDozing && mReadyNotRestrictedInBg && (mReadyDeadlineSatisfied
+                || isConstraintsSatisfied());
     }
 
     static final int CONSTRAINTS_OF_INTEREST = CONSTRAINT_CHARGING | CONSTRAINT_BATTERY_NOT_LOW
@@ -971,15 +1006,13 @@
             return true;
         }
 
-        final int req = requiredConstraints & CONSTRAINTS_OF_INTEREST;
-
-        int sat = satisfiedConstraints & CONSTRAINTS_OF_INTEREST;
+        int sat = mSatisfiedConstraintsOfInterest;
         if (overrideState == OVERRIDE_SOFT) {
             // override: pretend all 'soft' requirements are satisfied
             sat |= (requiredConstraints & SOFT_OVERRIDE_CONSTRAINTS);
         }
 
-        return (sat & req) == req;
+        return (sat & mRequiredConstraintsOfInterest) == mRequiredConstraintsOfInterest;
     }
 
     public boolean matches(int uid, int jobId) {
diff --git a/services/core/java/com/android/server/location/ContextHubClientBroker.java b/services/core/java/com/android/server/location/ContextHubClientBroker.java
index 9640e04..1d0ab8f 100644
--- a/services/core/java/com/android/server/location/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/ContextHubClientBroker.java
@@ -16,10 +16,12 @@
 
 package com.android.server.location;
 
+import android.app.PendingIntent;
 import android.content.Context;
 import android.hardware.contexthub.V1_0.ContextHubMsg;
 import android.hardware.contexthub.V1_0.IContexthub;
 import android.hardware.contexthub.V1_0.Result;
+import android.hardware.location.ContextHubInfo;
 import android.hardware.location.ContextHubTransaction;
 import android.hardware.location.IContextHubClient;
 import android.hardware.location.IContextHubClientCallback;
@@ -57,9 +59,9 @@
     private final ContextHubClientManager mClientManager;
 
     /*
-     * The ID of the hub that this client is attached to.
+     * The object describing the hub that this client is attached to.
      */
-    private final int mAttachedContextHubId;
+    private final ContextHubInfo mAttachedContextHubInfo;
 
     /*
      * The host end point ID of this client.
@@ -76,13 +78,21 @@
      */
     private final AtomicBoolean mConnectionOpen = new AtomicBoolean(true);
 
+    /*
+     * Internal interface used to invoke client callbacks.
+     */
+    private interface CallbackConsumer {
+        void accept(IContextHubClientCallback callback) throws RemoteException;
+    }
+
     /* package */ ContextHubClientBroker(
             Context context, IContexthub contextHubProxy, ContextHubClientManager clientManager,
-            int contextHubId, short hostEndPointId, IContextHubClientCallback callback) {
+            ContextHubInfo contextHubInfo, short hostEndPointId,
+            IContextHubClientCallback callback) {
         mContext = context;
         mContextHubProxy = contextHubProxy;
         mClientManager = clientManager;
-        mAttachedContextHubId = contextHubId;
+        mAttachedContextHubInfo = contextHubInfo;
         mHostEndPointId = hostEndPointId;
         mCallbackInterface = callback;
     }
@@ -112,11 +122,12 @@
             ContextHubMsg messageToNanoApp = ContextHubServiceUtil.createHidlContextHubMessage(
                     mHostEndPointId, message);
 
+            int contextHubId = mAttachedContextHubInfo.getId();
             try {
-                result = mContextHubProxy.sendMessageToHub(mAttachedContextHubId, messageToNanoApp);
+                result = mContextHubProxy.sendMessageToHub(contextHubId, messageToNanoApp);
             } catch (RemoteException e) {
                 Log.e(TAG, "RemoteException in sendMessageToNanoApp (target hub ID = "
-                        + mAttachedContextHubId + ")", e);
+                        + contextHubId + ")", e);
                 result = Result.UNKNOWN_FAILURE;
             }
         } else {
@@ -128,6 +139,27 @@
     }
 
     /**
+     * @param intent the intent to register
+     * @param nanoAppId the ID of the nanoapp to send events for
+     * @return true on success, false otherwise
+     */
+    @Override
+    public boolean registerIntent(PendingIntent intent, long nanoAppId) {
+        // TODO: Implement this
+        return false;
+    }
+
+    /**
+     * @param intent the intent to unregister
+     * @return true on success, false otherwise
+     */
+    @Override
+    public boolean unregisterIntent(PendingIntent intent) {
+        // TODO: Implement this
+        return false;
+    }
+
+    /**
      * Closes the connection for this client with the service.
      */
     @Override
@@ -140,19 +172,16 @@
     /**
      * Invoked when the underlying binder of this broker has died at the client process.
      */
+    @Override
     public void binderDied() {
-        try {
-            IContextHubClient.Stub.asInterface(this).close();
-        } catch (RemoteException e) {
-            Log.e(TAG, "RemoteException while closing client on death", e);
-        }
+        close();
     }
 
     /**
      * @return the ID of the context hub this client is attached to
      */
     /* package */ int getAttachedContextHubId() {
-        return mAttachedContextHubId;
+        return mAttachedContextHubInfo.getId();
     }
 
     /**
@@ -168,14 +197,7 @@
      * @param message the message that came from a nanoapp
      */
     /* package */ void sendMessageToClient(NanoAppMessage message) {
-        if (mConnectionOpen.get()) {
-            try {
-                mCallbackInterface.onMessageFromNanoApp(message);
-            } catch (RemoteException e) {
-                Log.e(TAG, "RemoteException while sending message to client (host endpoint ID = "
-                        + mHostEndPointId + ")", e);
-            }
-        }
+        invokeCallbackConcurrent(callback -> callback.onMessageFromNanoApp(message));
     }
 
     /**
@@ -184,14 +206,7 @@
      * @param nanoAppId the ID of the nanoapp that was loaded.
      */
     /* package */ void onNanoAppLoaded(long nanoAppId) {
-        if (mConnectionOpen.get()) {
-            try {
-                mCallbackInterface.onNanoAppLoaded(nanoAppId);
-            } catch (RemoteException e) {
-                Log.e(TAG, "RemoteException while calling onNanoAppLoaded on client"
-                        + " (host endpoint ID = " + mHostEndPointId + ")", e);
-            }
-        }
+        invokeCallbackConcurrent(callback -> callback.onNanoAppLoaded(nanoAppId));
     }
 
     /**
@@ -200,28 +215,14 @@
      * @param nanoAppId the ID of the nanoapp that was unloaded.
      */
     /* package */ void onNanoAppUnloaded(long nanoAppId) {
-        if (mConnectionOpen.get()) {
-            try {
-                mCallbackInterface.onNanoAppUnloaded(nanoAppId);
-            } catch (RemoteException e) {
-                Log.e(TAG, "RemoteException while calling onNanoAppUnloaded on client"
-                        + " (host endpoint ID = " + mHostEndPointId + ")", e);
-            }
-        }
+        invokeCallbackConcurrent(callback -> callback.onNanoAppUnloaded(nanoAppId));
     }
 
     /**
      * Notifies the client of a hub reset event if the connection is open.
      */
     /* package */ void onHubReset() {
-        if (mConnectionOpen.get()) {
-            try {
-                mCallbackInterface.onHubReset();
-            } catch (RemoteException e) {
-                Log.e(TAG, "RemoteException while calling onHubReset on client" +
-                        " (host endpoint ID = " + mHostEndPointId + ")", e);
-            }
-        }
+        invokeCallbackConcurrent(callback -> callback.onHubReset());
     }
 
     /**
@@ -231,12 +232,21 @@
      * @param abortCode the nanoapp specific abort code
      */
     /* package */ void onNanoAppAborted(long nanoAppId, int abortCode) {
+        invokeCallbackConcurrent(callback -> callback.onNanoAppAborted(nanoAppId, abortCode));
+    }
+
+    /**
+     * Helper function to invoke a specified client callback, if the connection is open.
+     *
+     * @param consumer the consumer specifying the callback to invoke
+     */
+    private void invokeCallbackConcurrent(CallbackConsumer consumer) {
         if (mConnectionOpen.get()) {
             try {
-                mCallbackInterface.onNanoAppAborted(nanoAppId, abortCode);
+                consumer.accept(mCallbackInterface);
             } catch (RemoteException e) {
-                Log.e(TAG, "RemoteException while calling onNanoAppAborted on client"
-                        + " (host endpoint ID = " + mHostEndPointId + ")", e);
+                Log.e(TAG, "RemoteException while invoking client callback (host endpoint ID = "
+                        + mHostEndPointId + ")", e);
             }
         }
     }
diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java
index 4243f02..eda8c6f 100644
--- a/services/core/java/com/android/server/location/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/ContextHubClientManager.java
@@ -19,13 +19,13 @@
 import android.content.Context;
 import android.hardware.contexthub.V1_0.ContextHubMsg;
 import android.hardware.contexthub.V1_0.IContexthub;
+import android.hardware.location.ContextHubInfo;
 import android.hardware.location.IContextHubClient;
 import android.hardware.location.IContextHubClientCallback;
 import android.hardware.location.NanoAppMessage;
 import android.os.RemoteException;
 import android.util.Log;
 
-import java.util.NoSuchElementException;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Consumer;
 
@@ -80,15 +80,15 @@
      * Registers a new client with the service.
      *
      * @param clientCallback the callback interface of the client to register
-     * @param contextHubId   the ID of the hub this client is attached to
+     * @param contextHubInfo the object describing the hub this client is attached to
      *
      * @return the client interface
      *
      * @throws IllegalStateException if max number of clients have already registered
      */
     /* package */ IContextHubClient registerClient(
-            IContextHubClientCallback clientCallback, int contextHubId) {
-        ContextHubClientBroker broker = createNewClientBroker(clientCallback, contextHubId);
+            IContextHubClientCallback clientCallback, ContextHubInfo contextHubInfo) {
+        ContextHubClientBroker broker = createNewClientBroker(clientCallback, contextHubInfo);
 
         try {
             broker.attachDeathRecipient();
@@ -183,14 +183,14 @@
      * manager.
      *
      * @param clientCallback the callback interface of the client to register
-     * @param contextHubId   the ID of the hub this client is attached to
+     * @param contextHubInfo the object describing the hub this client is attached to
      *
      * @return the ContextHubClientBroker object
      *
      * @throws IllegalStateException if max number of clients have already registered
      */
     private synchronized ContextHubClientBroker createNewClientBroker(
-            IContextHubClientCallback clientCallback, int contextHubId) {
+            IContextHubClientCallback clientCallback, ContextHubInfo contextHubInfo) {
         if (mHostEndPointIdToClientMap.size() == MAX_CLIENT_ID + 1) {
             throw new IllegalStateException("Could not register client - max limit exceeded");
         }
@@ -198,10 +198,11 @@
         ContextHubClientBroker broker = null;
         int id = mNextHostEndpointId;
         for (int i = 0; i <= MAX_CLIENT_ID; i++) {
-            if (!mHostEndPointIdToClientMap.containsKey((short)id)) {
+            if (!mHostEndPointIdToClientMap.containsKey((short) id)) {
                 broker = new ContextHubClientBroker(
-                        mContext, mContextHubProxy, this, contextHubId, (short)id, clientCallback);
-                mHostEndPointIdToClientMap.put((short)id, broker);
+                        mContext, mContextHubProxy, this, contextHubInfo, (short) id,
+                        clientCallback);
+                mHostEndPointIdToClientMap.put((short) id, broker);
                 mNextHostEndpointId = (id == MAX_CLIENT_ID) ? 0 : id + 1;
                 break;
             }
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index 27509de..96e9337 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -170,8 +170,9 @@
 
         HashMap<Integer, IContextHubClient> defaultClientMap = new HashMap<>();
         for (int contextHubId : mContextHubIdToInfoMap.keySet()) {
+            ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
             IContextHubClient client = mClientManager.registerClient(
-                    createDefaultClientCallback(contextHubId), contextHubId);
+                    createDefaultClientCallback(contextHubId), contextHubInfo);
             defaultClientMap.put(contextHubId, client);
 
             try {
@@ -623,7 +624,8 @@
             throw new NullPointerException("Cannot register client with null callback");
         }
 
-        return mClientManager.registerClient(clientCallback, contextHubId);
+        ContextHubInfo contextHubInfo = mContextHubIdToInfoMap.get(contextHubId);
+        return mClientManager.registerClient(clientCallback, contextHubInfo);
     }
 
     /**
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 31cf9e3..53d54ba 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -254,6 +254,9 @@
     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;
+    // Default time limit in milliseconds for the ConnectivityManager to find a suitable
+    // network with SUPL connectivity or report an error.
+    private static final int SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS = 10 * 1000;
 
     /** simpler wrapper for ProviderRequest + Worksource */
     private static class GpsRequest {
@@ -539,14 +542,23 @@
             new ConnectivityManager.NetworkCallback() {
                 @Override
                 public void onAvailable(Network network) {
+                    if (DEBUG) Log.d(TAG, "SUPL network connection available.");
                     // Specific to a change to a SUPL enabled network becoming ready
                     sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
                 }
 
                 @Override
                 public void onLost(Network network) {
+                    Log.i(TAG, "SUPL network connection lost.");
                     releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
                 }
+
+                @Override
+                public void onUnavailable() {
+                    Log.i(TAG, "SUPL network connection request timed out.");
+                    // Could not setup the connection to the network in the specified time duration.
+                    releaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
+                }
             };
 
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -953,7 +965,8 @@
         NetworkRequest request = requestBuilder.build();
         mConnMgr.requestNetwork(
                 request,
-                mSuplConnectivityCallback);
+                mSuplConnectivityCallback,
+                SUPL_NETWORK_REQUEST_TIMEOUT_MILLIS);
     }
 
     private void handleReleaseSuplConnection(int agpsDataConnStatus) {
@@ -2796,4 +2809,3 @@
 
     private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds);
 }
-
diff --git a/services/core/java/com/android/server/media/MediaUpdateService.java b/services/core/java/com/android/server/media/MediaUpdateService.java
index af06d15..7304f07 100644
--- a/services/core/java/com/android/server/media/MediaUpdateService.java
+++ b/services/core/java/com/android/server/media/MediaUpdateService.java
@@ -22,7 +22,7 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
-import android.media.IMediaExtractorUpdateService;
+import android.media.IMediaUpdateService;
 import android.os.Build;
 import android.os.IBinder;
 import android.os.Handler;
@@ -34,6 +34,7 @@
 import android.util.Log;
 import android.util.Slog;
 import com.android.server.SystemService;
+import java.util.HashMap;
 
 /** This class provides a system service that manages media framework updates. */
 public class MediaUpdateService extends SystemService {
@@ -42,34 +43,40 @@
     private static final String MEDIA_UPDATE_PACKAGE_NAME =
             SystemProperties.get("ro.mediacomponents.package");
     private static final String EXTRACTOR_UPDATE_SERVICE_NAME = "media.extractor.update";
-
-    private IMediaExtractorUpdateService mMediaExtractorUpdateService;
-    final Handler mHandler;
+    private static final String CODEC_UPDATE_SERVICE_NAME = "media.codec.update";
+    private static final String[] UPDATE_SERVICE_NAME_ARRAY = {
+            EXTRACTOR_UPDATE_SERVICE_NAME, CODEC_UPDATE_SERVICE_NAME,
+    };
+    private final HashMap<String, IMediaUpdateService> mUpdateServiceMap = new HashMap<>();
+    private final Handler mHandler = new Handler();
 
     public MediaUpdateService(Context context) {
         super(context);
-        mHandler = new Handler();
     }
 
     @Override
     public void onStart() {
         if (("userdebug".equals(android.os.Build.TYPE) || "eng".equals(android.os.Build.TYPE))
                 && !TextUtils.isEmpty(MEDIA_UPDATE_PACKAGE_NAME)) {
-            connect();
+            for (String serviceName : UPDATE_SERVICE_NAME_ARRAY) {
+                connect(serviceName);
+            }
             registerBroadcastReceiver();
         }
     }
 
-    private void connect() {
-        IBinder binder = ServiceManager.getService(EXTRACTOR_UPDATE_SERVICE_NAME);
+    private void connect(final String serviceName) {
+        IBinder binder = ServiceManager.getService(serviceName);
         if (binder != null) {
             try {
                 binder.linkToDeath(new IBinder.DeathRecipient() {
                     @Override
                     public void binderDied() {
-                        Slog.w(TAG, "mediaextractor died; reconnecting");
-                        mMediaExtractorUpdateService = null;
-                        connect();
+                        Slog.w(TAG, "service " + serviceName + " died; reconnecting");
+                        synchronized (mUpdateServiceMap) {
+                            mUpdateServiceMap.remove(serviceName);
+                        }
+                        connect(serviceName);
                     }
                 }, 0);
             } catch (Exception e) {
@@ -77,15 +84,18 @@
             }
         }
         if (binder != null) {
-            mMediaExtractorUpdateService = IMediaExtractorUpdateService.Stub.asInterface(binder);
+            synchronized (mUpdateServiceMap) {
+                mUpdateServiceMap.put(serviceName,
+                        IMediaUpdateService.Stub.asInterface(binder));
+            }
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    packageStateChanged();
+                    packageStateChanged(serviceName);
                 }
             });
         } else {
-            Slog.w(TAG, EXTRACTOR_UPDATE_SERVICE_NAME + " not found.");
+            Slog.w(TAG, serviceName + " not found.");
         }
     }
 
@@ -106,13 +116,12 @@
                                 // following ACTION_PACKAGE_ADDED case.
                                 return;
                             }
-                            packageStateChanged();
-                            break;
+                            // fall-thru
                         case Intent.ACTION_PACKAGE_CHANGED:
-                            packageStateChanged();
-                            break;
                         case Intent.ACTION_PACKAGE_ADDED:
-                            packageStateChanged();
+                            for (String serviceName : UPDATE_SERVICE_NAME_ARRAY) {
+                                packageStateChanged(serviceName);
+                            }
                             break;
                     }
                 }
@@ -128,7 +137,7 @@
                 null /* broadcast permission */, null /* handler */);
     }
 
-    private void packageStateChanged() {
+    private void packageStateChanged(String serviceName) {
         ApplicationInfo packageInfo = null;
         boolean pluginsAvailable = false;
         try {
@@ -144,17 +153,23 @@
                     + " targetSdk:" + packageInfo.targetSdkVersion);
             pluginsAvailable = false;
         }
-        loadExtractorPlugins(
+        loadPlugins(serviceName,
                 (packageInfo != null && pluginsAvailable) ? packageInfo.sourceDir : "");
     }
 
-    private void loadExtractorPlugins(String apkPath) {
+    private void loadPlugins(String serviceName, String apkPath) {
         try {
-            if (mMediaExtractorUpdateService != null) {
-                mMediaExtractorUpdateService.loadPlugins(apkPath);
+            IMediaUpdateService service = null;
+            synchronized (serviceName) {
+                service = mUpdateServiceMap.get(serviceName);
+            }
+            if (service != null) {
+                service.loadPlugins(apkPath);
+            } else {
+                Slog.w(TAG, "service " + serviceName + " passed away");
             }
         } catch (Exception e) {
-            Slog.w(TAG, "Error in loadPlugins", e);
+            Slog.w(TAG, "Error in loadPlugins for " + serviceName, e);
         }
     }
 }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyLogger.java b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
index 452b699..4f4b6bf 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyLogger.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyLogger.java
@@ -72,6 +72,7 @@
     static final int NTWK_ALLOWED_TMP_WHITELIST = 4;
     static final int NTWK_BLOCKED_BG_RESTRICT = 5;
     static final int NTWK_ALLOWED_DEFAULT = 6;
+    static final int NTWK_ALLOWED_SYSTEM = 7;
 
     private final LogBuffer mNetworkBlockedBuffer = new LogBuffer(MAX_NETWORK_BLOCKED_LOG_SIZE);
     private final LogBuffer mUidStateChangeBuffer = new LogBuffer(MAX_LOG_SIZE);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
index 61d67b7..099671d 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerInternal.java
@@ -16,6 +16,8 @@
 
 package com.android.server.net;
 
+import static com.android.server.net.NetworkPolicyManagerService.isUidNetworkingBlockedInternal;
+
 import android.net.Network;
 import android.net.NetworkTemplate;
 import android.telephony.SubscriptionPlan;
@@ -46,6 +48,28 @@
     public abstract boolean isUidNetworkingBlocked(int uid, String ifname);
 
     /**
+     * Figure out if networking is blocked for a given set of conditions.
+     *
+     * This is used by ConnectivityService via passing stale copies of conditions, so it must not
+     * take any locks.
+     *
+     * @param uid The target uid.
+     * @param uidRules The uid rules which are obtained from NetworkPolicyManagerService.
+     * @param isNetworkMetered True if the network is metered.
+     * @param isBackgroundRestricted True if data saver is enabled.
+     *
+     * @return true if networking is blocked for the UID under the specified conditions.
+     */
+    public static boolean isUidNetworkingBlocked(int uid, int uidRules, boolean isNetworkMetered,
+            boolean isBackgroundRestricted) {
+        // Log of invoking internal function is disabled because it will be called very
+        // frequently. And metrics are unlikely needed on this method because the callers are
+        // external and this method doesn't take any locks or perform expensive operations.
+        return isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
+                isBackgroundRestricted, null);
+    }
+
+    /**
      * Informs that an appId has been added or removed from the temp-powersave-whitelist so that
      * that network rules for that appId can be updated.
      *
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 48e09d7..d799642 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -99,6 +99,7 @@
 import static com.android.server.NetworkManagementService.LIMIT_GLOBAL_ALERT;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_DEFAULT;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_NON_METERED;
+import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_SYSTEM;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_TMP_WHITELIST;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_ALLOWED_WHITELIST;
 import static com.android.server.net.NetworkPolicyLogger.NTWK_BLOCKED_BG_RESTRICT;
@@ -4837,46 +4838,75 @@
         final long startTime = mStatLogger.getTime();
 
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
-        final boolean ret = isUidNetworkingBlockedInternal(uid, isNetworkMetered);
-
-        mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
-
-        return ret;
-    }
-
-    private boolean isUidNetworkingBlockedInternal(int uid, boolean isNetworkMetered) {
         final int uidRules;
         final boolean isBackgroundRestricted;
         synchronized (mUidRulesFirstLock) {
             uidRules = mUidRules.get(uid, RULE_NONE);
             isBackgroundRestricted = mRestrictBackground;
         }
-        if (hasRule(uidRules, RULE_REJECT_ALL)) {
-            mLogger.networkBlocked(uid, NTWK_BLOCKED_POWER);
-            return true;
+        final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
+                isBackgroundRestricted, mLogger);
+
+        mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
+
+        return ret;
+    }
+
+    private static boolean isSystem(int uid) {
+        return uid < Process.FIRST_APPLICATION_UID;
+    }
+
+    static boolean isUidNetworkingBlockedInternal(int uid, int uidRules, boolean isNetworkMetered,
+            boolean isBackgroundRestricted, @Nullable NetworkPolicyLogger logger) {
+        final int reason;
+        // Networks are never blocked for system components
+        if (isSystem(uid)) {
+            reason = NTWK_ALLOWED_SYSTEM;
         }
-        if (!isNetworkMetered) {
-            mLogger.networkBlocked(uid, NTWK_ALLOWED_NON_METERED);
-            return false;
+        else if (hasRule(uidRules, RULE_REJECT_ALL)) {
+            reason = NTWK_BLOCKED_POWER;
         }
-        if (hasRule(uidRules, RULE_REJECT_METERED)) {
-            mLogger.networkBlocked(uid, NTWK_BLOCKED_BLACKLIST);
-            return true;
+        else if (!isNetworkMetered) {
+            reason = NTWK_ALLOWED_NON_METERED;
         }
-        if (hasRule(uidRules, RULE_ALLOW_METERED)) {
-            mLogger.networkBlocked(uid, NTWK_ALLOWED_WHITELIST);
-            return false;
+        else if (hasRule(uidRules, RULE_REJECT_METERED)) {
+            reason = NTWK_BLOCKED_BLACKLIST;
         }
-        if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
-            mLogger.networkBlocked(uid, NTWK_ALLOWED_TMP_WHITELIST);
-            return false;
+        else if (hasRule(uidRules, RULE_ALLOW_METERED)) {
+            reason = NTWK_ALLOWED_WHITELIST;
         }
-        if (isBackgroundRestricted) {
-            mLogger.networkBlocked(uid, NTWK_BLOCKED_BG_RESTRICT);
-            return true;
+        else if (hasRule(uidRules, RULE_TEMPORARY_ALLOW_METERED)) {
+            reason = NTWK_ALLOWED_TMP_WHITELIST;
         }
-        mLogger.networkBlocked(uid, NTWK_ALLOWED_DEFAULT);
-        return false;
+        else if (isBackgroundRestricted) {
+            reason = NTWK_BLOCKED_BG_RESTRICT;
+        }
+        else {
+            reason = NTWK_ALLOWED_DEFAULT;
+        }
+
+        final boolean blocked;
+        switch(reason) {
+            case NTWK_ALLOWED_DEFAULT:
+            case NTWK_ALLOWED_NON_METERED:
+            case NTWK_ALLOWED_TMP_WHITELIST:
+            case NTWK_ALLOWED_WHITELIST:
+            case NTWK_ALLOWED_SYSTEM:
+                blocked = false;
+                break;
+            case NTWK_BLOCKED_POWER:
+            case NTWK_BLOCKED_BLACKLIST:
+            case NTWK_BLOCKED_BG_RESTRICT:
+                blocked = true;
+                break;
+            default:
+                throw new IllegalArgumentException();
+        }
+        if (logger != null) {
+            logger.networkBlocked(uid, reason);
+        }
+
+        return blocked;
     }
 
     private class NetworkPolicyManagerInternalImpl extends NetworkPolicyManagerInternal {
@@ -4918,11 +4948,18 @@
         public boolean isUidNetworkingBlocked(int uid, String ifname) {
             final long startTime = mStatLogger.getTime();
 
+            final int uidRules;
+            final boolean isBackgroundRestricted;
+            synchronized (mUidRulesFirstLock) {
+                uidRules = mUidRules.get(uid, RULE_NONE);
+                isBackgroundRestricted = mRestrictBackground;
+            }
             final boolean isNetworkMetered;
             synchronized (mNetworkPoliciesSecondLock) {
                 isNetworkMetered = mMeteredIfaces.contains(ifname);
             }
-            final boolean ret = isUidNetworkingBlockedInternal(uid, isNetworkMetered);
+            final boolean ret = isUidNetworkingBlockedInternal(uid, uidRules, isNetworkMetered,
+                    isBackgroundRestricted, mLogger);
 
             mStatLogger.logDurationStat(Stats.IS_UID_NETWORKING_BLOCKED, startTime);
 
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 60e9eaa..3f03169 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -159,8 +159,10 @@
     static final boolean LOGD = Log.isLoggable(TAG, Log.DEBUG);
     static final boolean LOGV = Log.isLoggable(TAG, Log.VERBOSE);
 
+    // Perform polling and persist all (FLAG_PERSIST_ALL).
     private static final int MSG_PERFORM_POLL = 1;
-    private static final int MSG_REGISTER_GLOBAL_ALERT = 2;
+    // Perform polling, persist network, and register the global alert again.
+    private static final int MSG_PERFORM_POLL_REGISTER_ALERT = 2;
 
     /** Flags to control detail level of poll event. */
     private static final int FLAG_PERSIST_NETWORK = 0x1;
@@ -168,6 +170,14 @@
     private static final int FLAG_PERSIST_ALL = FLAG_PERSIST_NETWORK | FLAG_PERSIST_UID;
     private static final int FLAG_PERSIST_FORCE = 0x100;
 
+    /**
+     * When global alert quota is high, wait for this delay before processing each polling,
+     * and do not schedule further polls once there is already one queued.
+     * This avoids firing the global alert too often on devices with high transfer speeds and
+     * high quota.
+     */
+    private static final int PERFORM_POLL_DELAY_MS = 1000;
+
     private static final String TAG_NETSTATS_ERROR = "netstats_error";
 
     private final Context mContext;
@@ -920,7 +930,7 @@
         }
 
         // Create baseline stats
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL, FLAG_PERSIST_ALL));
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_PERFORM_POLL));
 
         return normalizedRequest;
    }
@@ -1055,13 +1065,12 @@
             mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
 
             if (LIMIT_GLOBAL_ALERT.equals(limitName)) {
-                // kick off background poll to collect network stats; UID stats
-                // are handled during normal polling interval.
-                final int flags = FLAG_PERSIST_NETWORK;
-                mHandler.obtainMessage(MSG_PERFORM_POLL, flags, 0).sendToTarget();
-
-                // re-arm global alert for next update
-                mHandler.obtainMessage(MSG_REGISTER_GLOBAL_ALERT).sendToTarget();
+                // kick off background poll to collect network stats unless there is already
+                // such a call pending; UID stats are handled during normal polling interval.
+                if (!mHandler.hasMessages(MSG_PERFORM_POLL_REGISTER_ALERT)) {
+                    mHandler.sendEmptyMessageDelayed(MSG_PERFORM_POLL_REGISTER_ALERT,
+                            PERFORM_POLL_DELAY_MS);
+                }
             }
         }
     };
@@ -1673,11 +1682,11 @@
         public boolean handleMessage(Message msg) {
             switch (msg.what) {
                 case MSG_PERFORM_POLL: {
-                    final int flags = msg.arg1;
-                    mService.performPoll(flags);
+                    mService.performPoll(FLAG_PERSIST_ALL);
                     return true;
                 }
-                case MSG_REGISTER_GLOBAL_ALERT: {
+                case MSG_PERFORM_POLL_REGISTER_ALERT: {
+                    mService.performPoll(FLAG_PERSIST_NETWORK);
                     mService.registerGlobalAlert();
                     return true;
                 }
diff --git a/services/core/java/com/android/server/notification/CalendarTracker.java b/services/core/java/com/android/server/notification/CalendarTracker.java
index 4001b90..3829b65 100644
--- a/services/core/java/com/android/server/notification/CalendarTracker.java
+++ b/services/core/java/com/android/server/notification/CalendarTracker.java
@@ -22,7 +22,6 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
-import android.provider.BaseColumns;
 import android.provider.CalendarContract.Attendees;
 import android.provider.CalendarContract.Calendars;
 import android.provider.CalendarContract.Events;
@@ -89,13 +88,13 @@
         pw.print(prefix); pw.print("u="); pw.println(mUserContext.getUserId());
     }
 
-    private ArraySet<Long> getPrimaryCalendars() {
+    private ArraySet<Long> getCalendarsWithAccess() {
         final long start = System.currentTimeMillis();
         final ArraySet<Long> rt = new ArraySet<>();
-        final String primary = "\"primary\"";
-        final String[] projection = { Calendars._ID,
-                "(" + Calendars.ACCOUNT_NAME + "=" + Calendars.OWNER_ACCOUNT + ") AS " + primary };
-        final String selection = primary + " = 1";
+        final String[] projection = { Calendars._ID };
+        final String selection = Calendars.CALENDAR_ACCESS_LEVEL + " >= "
+                + Calendars.CAL_ACCESS_CONTRIBUTOR
+                + " AND " + Calendars.SYNC_EVENTS + " = 1";
         Cursor cursor = null;
         try {
             cursor = mUserContext.getContentResolver().query(Calendars.CONTENT_URI, projection,
@@ -108,7 +107,9 @@
                 cursor.close();
             }
         }
-        if (DEBUG) Log.d(TAG, "getPrimaryCalendars took " + (System.currentTimeMillis() - start));
+        if (DEBUG) {
+            Log.d(TAG, "getCalendarsWithAccess took " + (System.currentTimeMillis() - start));
+        }
         return rt;
     }
 
@@ -122,7 +123,7 @@
         final CheckEventResult result = new CheckEventResult();
         result.recheckAt = time + EVENT_CHECK_LOOKAHEAD;
         try {
-            final ArraySet<Long> primaryCalendars = getPrimaryCalendars();
+            final ArraySet<Long> calendars = getCalendarsWithAccess();
             while (cursor != null && cursor.moveToNext()) {
                 final long begin = cursor.getLong(0);
                 final long end = cursor.getLong(1);
@@ -133,17 +134,19 @@
                 final String owner = cursor.getString(6);
                 final long calendarId = cursor.getLong(7);
                 final int availability = cursor.getInt(8);
-                final boolean calendarPrimary = primaryCalendars.contains(calendarId);
-                if (DEBUG) Log.d(TAG, String.format(
-                        "%s %s-%s v=%s a=%s eid=%s n=%s o=%s cid=%s p=%s",
-                        title,
-                        new Date(begin), new Date(end), calendarVisible,
-                        availabilityToString(availability), eventId, name, owner, calendarId,
-                        calendarPrimary));
+                final boolean canAccessCal = calendars.contains(calendarId);
+                if (DEBUG) {
+                    Log.d(TAG, String.format("title=%s time=%s-%s vis=%s availability=%s "
+                                    + "eventId=%s name=%s owner=%s calId=%s canAccessCal=%s",
+                            title, new Date(begin), new Date(end), calendarVisible,
+                            availabilityToString(availability), eventId, name, owner, calendarId,
+                            canAccessCal));
+                }
                 final boolean meetsTime = time >= begin && time < end;
-                final boolean meetsCalendar = calendarVisible && calendarPrimary
-                        && (filter.calendar == null || Objects.equals(filter.calendar, owner)
-                        || Objects.equals(filter.calendar, name));
+                final boolean meetsCalendar = calendarVisible && canAccessCal
+                        && ((filter.calName == null && filter.calendarId == null)
+                        || (Objects.equals(filter.calendarId, calendarId))
+                        || Objects.equals(filter.calName, name));
                 final boolean meetsAvailability = availability != Instances.AVAILABILITY_FREE;
                 if (meetsCalendar && meetsAvailability) {
                     if (DEBUG) Log.d(TAG, "  MEETS CALENDAR & AVAILABILITY");
diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java
index 5bc9b1c..a4a94c2 100644
--- a/services/core/java/com/android/server/notification/EventConditionProvider.java
+++ b/services/core/java/com/android/server/notification/EventConditionProvider.java
@@ -27,7 +27,6 @@
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.os.Looper;
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -221,7 +220,7 @@
                     continue;
                 }
                 CheckEventResult result = null;
-                if (event.calendar == null) { // any calendar
+                if (event.calName == null) { // any calendar
                     // event could exist on any tracker
                     for (int i = 0; i < mTrackers.size(); i++) {
                         final CalendarTracker tracker = mTrackers.valueAt(i);
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index d326c22..6187583 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -696,7 +696,7 @@
             for (int i = 0; i < userIds.size(); i++) {
                 final int userId = userIds.get(i);
                 if (enabled) {
-                    if (isPackageOrComponentAllowed(component.toString(), userId)
+                    if (isPackageOrComponentAllowed(component.flattenToString(), userId)
                             || isPackageOrComponentAllowed(component.getPackageName(), userId)) {
                         registerServiceLocked(component, userId);
                     } else {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5005ea7..93b83ae 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -16,6 +16,7 @@
 
 package com.android.server.notification;
 
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.NotificationManager.ACTION_APP_BLOCK_STATE_CHANGED;
 import static android.app.NotificationManager.ACTION_NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED;
@@ -718,8 +719,7 @@
                     return;
                 }
                 final long now = System.currentTimeMillis();
-                MetricsLogger.action(r.getLogMaker(now)
-                        .setCategory(MetricsEvent.NOTIFICATION_ITEM)
+                MetricsLogger.action(r.getItemLogMaker()
                         .setType(MetricsEvent.TYPE_ACTION)
                         .addTaggedData(MetricsEvent.NOTIFICATION_SHADE_INDEX, nv.rank)
                         .addTaggedData(MetricsEvent.NOTIFICATION_SHADE_COUNT, nv.count));
@@ -864,8 +864,7 @@
                     r.stats.onExpansionChanged(userAction, expanded);
                     final long now = System.currentTimeMillis();
                     if (userAction) {
-                        MetricsLogger.action(r.getLogMaker(now)
-                                .setCategory(MetricsEvent.NOTIFICATION_ITEM)
+                        MetricsLogger.action(r.getItemLogMaker()
                                 .setType(expanded ? MetricsEvent.TYPE_DETAIL
                                         : MetricsEvent.TYPE_COLLAPSE));
                     }
@@ -2001,7 +2000,8 @@
         return mInternalService;
     }
 
-    private final IBinder mService = new INotificationManager.Stub() {
+    @VisibleForTesting
+    final IBinder mService = new INotificationManager.Stub() {
         // Toasts
         // ============================================================================
 
@@ -2015,21 +2015,30 @@
             }
 
             if (pkg == null || callback == null) {
-                Slog.e(TAG, "Not doing toast. pkg=" + pkg + " callback=" + callback);
+                Slog.e(TAG, "Not enqueuing toast. pkg=" + pkg + " callback=" + callback);
                 return ;
             }
-            final boolean isSystemToast = isCallerSystemOrPhone() || ("android".equals(pkg));
-            final boolean isPackageSuspended =
-                    isPackageSuspendedForUser(pkg, Binder.getCallingUid());
 
-            if (ENABLE_BLOCKED_TOASTS && !isSystemToast &&
-                    (!areNotificationsEnabledForPackage(pkg, Binder.getCallingUid())
-                            || isPackageSuspended)) {
-                Slog.e(TAG, "Suppressing toast from package " + pkg
-                        + (isPackageSuspended
-                                ? " due to package suspended by administrator."
-                                : " by user request."));
-                return;
+            final int callingUid = Binder.getCallingUid();
+            final boolean isSystemToast = isCallerSystemOrPhone()
+                    || PackageManagerService.PLATFORM_PACKAGE_NAME.equals(pkg);
+            final boolean isPackageSuspended = isPackageSuspendedForUser(pkg, callingUid);
+            final boolean notificationsDisabledForPackage = !areNotificationsEnabledForPackage(pkg,
+                    callingUid);
+
+            long callingIdentity = Binder.clearCallingIdentity();
+            try {
+                final boolean appIsForeground = mActivityManager.getUidImportance(callingUid)
+                        == IMPORTANCE_FOREGROUND;
+                if (ENABLE_BLOCKED_TOASTS && !isSystemToast && ((notificationsDisabledForPackage
+                        && !appIsForeground) || isPackageSuspended)) {
+                    Slog.e(TAG, "Suppressing toast from package " + pkg
+                            + (isPackageSuspended ? " due to package suspended."
+                            : " by user request."));
+                    return;
+                }
+            } finally {
+                Binder.restoreCallingIdentity(callingIdentity);
             }
 
             synchronized (mToastQueue) {
@@ -3613,7 +3622,7 @@
                 INotificationListener token, String pkg, UserHandle user,
                 NotificationChannelGroup group) throws RemoteException {
             Preconditions.checkNotNull(user);
-            verifyPrivilegedListener(token, user);
+            verifyPrivilegedListener(token, user, false);
             createNotificationChannelGroup(
                     pkg, getUidForPackageAndUser(pkg, user), group, false, true);
             savePolicyFile();
@@ -3626,7 +3635,7 @@
             Preconditions.checkNotNull(pkg);
             Preconditions.checkNotNull(user);
 
-            verifyPrivilegedListener(token, user);
+            verifyPrivilegedListener(token, user, false);
             updateNotificationChannelInt(pkg, getUidForPackageAndUser(pkg, user), channel, true);
         }
 
@@ -3635,7 +3644,7 @@
                 INotificationListener token, String pkg, UserHandle user) throws RemoteException {
             Preconditions.checkNotNull(pkg);
             Preconditions.checkNotNull(user);
-            verifyPrivilegedListener(token, user);
+            verifyPrivilegedListener(token, user, true);
 
             return mPreferencesHelper.getNotificationChannels(pkg, getUidForPackageAndUser(pkg, user),
                     false /* includeDeleted */);
@@ -3647,7 +3656,7 @@
                 INotificationListener token, String pkg, UserHandle user) throws RemoteException {
             Preconditions.checkNotNull(pkg);
             Preconditions.checkNotNull(user);
-            verifyPrivilegedListener(token, user);
+            verifyPrivilegedListener(token, user, true);
 
             List<NotificationChannelGroup> groups = new ArrayList<>();
             groups.addAll(mPreferencesHelper.getNotificationChannelGroups(
@@ -3655,13 +3664,18 @@
             return new ParceledListSlice<>(groups);
         }
 
-        private void verifyPrivilegedListener(INotificationListener token, UserHandle user) {
+        private void verifyPrivilegedListener(INotificationListener token, UserHandle user,
+                boolean assistantAllowed) {
             ManagedServiceInfo info;
             synchronized (mNotificationLock) {
                 info = mListeners.checkServiceTokenLocked(token);
             }
             if (!hasCompanionDevice(info)) {
-                throw new SecurityException(info + " does not have access");
+                synchronized (mNotificationLock) {
+                    if (!assistantAllowed || !mAssistants.isServiceTokenValidLocked(info.service)) {
+                        throw new SecurityException(info + " does not have access");
+                    }
+                }
             }
             if (!info.enabledAndUserMatches(user.getIdentifier())) {
                 throw new SecurityException(info + " does not have access");
@@ -4271,14 +4285,16 @@
     }
 
     private void doChannelWarningToast(CharSequence toastText) {
-        final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0;
-        final boolean warningEnabled = Settings.Global.getInt(getContext().getContentResolver(),
-                Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, defaultWarningEnabled) != 0;
-        if (warningEnabled) {
-            Toast toast = Toast.makeText(getContext(), mHandler.getLooper(), toastText,
-                    Toast.LENGTH_SHORT);
-            toast.show();
-        }
+        Binder.withCleanCallingIdentity(() -> {
+            final int defaultWarningEnabled = Build.IS_DEBUGGABLE ? 1 : 0;
+            final boolean warningEnabled = Settings.Global.getInt(getContext().getContentResolver(),
+                    Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS, defaultWarningEnabled) != 0;
+            if (warningEnabled) {
+                Toast toast = Toast.makeText(getContext(), mHandler.getLooper(), toastText,
+                        Toast.LENGTH_SHORT);
+                toast.show();
+            }
+        });
     }
 
     @VisibleForTesting
@@ -5829,8 +5845,7 @@
         mArchive.record(r.sbn);
 
         final long now = System.currentTimeMillis();
-        final LogMaker logMaker = r.getLogMaker(now)
-                .setCategory(MetricsEvent.NOTIFICATION_ITEM)
+        final LogMaker logMaker = r.getItemLogMaker()
                 .setType(MetricsEvent.TYPE_DISMISS)
                 .setSubtype(reason);
         if (rank != -1 && count != -1) {
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index fbb42ea..e9f2718 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -611,6 +611,7 @@
     }
 
     public void applyAdjustments() {
+        long now = System.currentTimeMillis();
         synchronized (mAdjustments) {
             for (Adjustment adjustment: mAdjustments) {
                 Bundle signals = adjustment.getSignals();
@@ -618,17 +619,25 @@
                     final ArrayList<String> people =
                             adjustment.getSignals().getStringArrayList(Adjustment.KEY_PEOPLE);
                     setPeopleOverride(people);
+                    MetricsLogger.action(getAdjustmentLogMaker()
+                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_PEOPLE, people.size()));
                 }
                 if (signals.containsKey(Adjustment.KEY_SNOOZE_CRITERIA)) {
                     final ArrayList<SnoozeCriterion> snoozeCriterionList =
                             adjustment.getSignals().getParcelableArrayList(
                                     Adjustment.KEY_SNOOZE_CRITERIA);
                     setSnoozeCriteria(snoozeCriterionList);
+                    MetricsLogger.action(getAdjustmentLogMaker()
+                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SNOOZE_CRITERIA,
+                                    snoozeCriterionList.size()));
                 }
                 if (signals.containsKey(Adjustment.KEY_GROUP_KEY)) {
                     final String groupOverrideKey =
                             adjustment.getSignals().getString(Adjustment.KEY_GROUP_KEY);
                     setOverrideGroupKey(groupOverrideKey);
+                    MetricsLogger.action(getAdjustmentLogMaker()
+                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_GROUP_KEY,
+                                    groupOverrideKey));
                 }
                 if (signals.containsKey(Adjustment.KEY_USER_SENTIMENT)) {
                     // Only allow user sentiment update from assistant if user hasn't already
@@ -637,19 +646,31 @@
                             && (getChannel().getUserLockedFields() & USER_LOCKED_IMPORTANCE) == 0) {
                         setUserSentiment(adjustment.getSignals().getInt(
                                 Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEUTRAL));
+                        MetricsLogger.action(getAdjustmentLogMaker()
+                                .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_USER_SENTIMENT,
+                                        getUserSentiment()));
                     }
                 }
                 if (signals.containsKey(Adjustment.KEY_SMART_ACTIONS)) {
                     setSmartActions(signals.getParcelableArrayList(Adjustment.KEY_SMART_ACTIONS));
+                    MetricsLogger.action(getAdjustmentLogMaker()
+                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_ACTIONS,
+                                    getSmartActions().size()));
                 }
                 if (signals.containsKey(Adjustment.KEY_SMART_REPLIES)) {
                     setSmartReplies(signals.getCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES));
+                    MetricsLogger.action(getAdjustmentLogMaker()
+                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_SMART_REPLIES,
+                                    getSmartReplies().size()));
                 }
                 if (signals.containsKey(Adjustment.KEY_IMPORTANCE)) {
                     int importance = signals.getInt(Adjustment.KEY_IMPORTANCE);
                     importance = Math.max(IMPORTANCE_UNSPECIFIED, importance);
                     importance = Math.min(IMPORTANCE_HIGH, importance);
                     setAssistantImportance(importance);
+                    MetricsLogger.action(getAdjustmentLogMaker()
+                            .addTaggedData(MetricsEvent.ADJUSTMENT_KEY_IMPORTANCE,
+                                    importance));
                 }
             }
         }
@@ -662,10 +683,6 @@
 
     public void setContactAffinity(float contactAffinity) {
         mContactAffinity = contactAffinity;
-        if (mImportance < IMPORTANCE_DEFAULT &&
-                mContactAffinity > ValidateNotificationPeople.VALID_CONTACT) {
-            setSystemImportance(IMPORTANCE_DEFAULT);
-        }
     }
 
     public float getContactAffinity() {
@@ -736,10 +753,10 @@
     protected void calculateImportance() {
         mImportance = calculateInitialImportance();
         mImportanceExplanation = "app";
-        if (getChannel().isImportanceLocked()) {
+        if (getChannel().hasUserSetImportance()) {
             mImportanceExplanation = "user";
         }
-        if (!getChannel().isImportanceLocked() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
+        if (!getChannel().hasUserSetImportance() && mAssistantImportance != IMPORTANCE_UNSPECIFIED) {
             mImportance = mAssistantImportance;
             mImportanceExplanation = "asst";
         }
@@ -1207,6 +1224,16 @@
         return getLogMaker(System.currentTimeMillis());
     }
 
+    public LogMaker getItemLogMaker() {
+        return getLogMaker().setCategory(MetricsEvent.NOTIFICATION_ITEM);
+    }
+
+    public LogMaker getAdjustmentLogMaker() {
+        return getLogMaker()
+                .setCategory(MetricsEvent.NOTIFICATION_ITEM)
+                .setType(MetricsEvent.NOTIFICATION_ASSISTANT_ADJUSTMENT);
+    }
+
     @VisibleForTesting
     static final class Light {
         public final int color;
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 760f155..44b80c1 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -1212,27 +1212,89 @@
     }
 
     private final class Metrics extends Callback {
-        private static final String COUNTER_PREFIX = "dnd_mode_";
+        private static final String COUNTER_MODE_PREFIX = "dnd_mode_";
+        private static final String COUNTER_TYPE_PREFIX = "dnd_type_";
+        private static final int DND_OFF = 0;
+        private static final int DND_ON_MANUAL = 1;
+        private static final int DND_ON_AUTOMATIC = 2;
+        private static final String COUNTER_RULE = "dnd_rule_count";
         private static final long MINIMUM_LOG_PERIOD_MS = 60 * 1000;
 
+        // Total silence, alarms only, priority only
         private int mPreviousZenMode = -1;
-        private long mBeginningMs = 0L;
+        private long mModeLogTimeMs = 0L;
+
+        private int mNumZenRules = -1;
+        private long mRuleCountLogTime = 0L;
+
+        // automatic (1) vs manual (0) vs dnd off (2)
+        private int mPreviousZenType = -1;
+        private long mTypeLogTimeMs = 0L;
 
         @Override
         void onZenModeChanged() {
             emit();
         }
 
+        @Override
+        void onConfigChanged() {
+            emit();
+        }
+
         private void emit() {
             mHandler.postMetricsTimer();
+            emitZenMode();
+            emitRules();
+            emitDndType();
+        }
+
+        private void emitZenMode() {
             final long now = SystemClock.elapsedRealtime();
-            final long since = (now - mBeginningMs);
+            final long since = (now - mModeLogTimeMs);
             if (mPreviousZenMode != mZenMode || since > MINIMUM_LOG_PERIOD_MS) {
                 if (mPreviousZenMode != -1) {
-                    MetricsLogger.count(mContext, COUNTER_PREFIX + mPreviousZenMode, (int) since);
+                    MetricsLogger.count(
+                            mContext, COUNTER_MODE_PREFIX + mPreviousZenMode, (int) since);
                 }
                 mPreviousZenMode = mZenMode;
-                mBeginningMs = now;
+                mModeLogTimeMs = now;
+            }
+        }
+
+        private void emitRules() {
+            final long now = SystemClock.elapsedRealtime();
+            final long since = (now - mRuleCountLogTime);
+            synchronized (mConfig) {
+                int numZenRules = mConfig.automaticRules.size();
+                if (mNumZenRules != numZenRules
+                        || since > MINIMUM_LOG_PERIOD_MS) {
+                    if (mNumZenRules != -1) {
+                        MetricsLogger.count(mContext, COUNTER_RULE,
+                                numZenRules - mNumZenRules);
+                    }
+                    mNumZenRules = numZenRules;
+
+                    mRuleCountLogTime = since;
+                }
+            }
+        }
+
+        private void emitDndType() {
+            final long now = SystemClock.elapsedRealtime();
+            final long since = (now - mTypeLogTimeMs);
+            synchronized (mConfig) {
+                boolean dndOn = mZenMode != Global.ZEN_MODE_OFF;
+                int zenType = !dndOn ? DND_OFF
+                        : (mConfig.manualRule != null) ? DND_ON_MANUAL : DND_ON_AUTOMATIC;
+                if (zenType != mPreviousZenType
+                        || since > MINIMUM_LOG_PERIOD_MS) {
+                    if (mPreviousZenType != -1) {
+                        MetricsLogger.count(
+                                mContext, COUNTER_TYPE_PREFIX + mPreviousZenType, (int) since);
+                    }
+                    mTypeLogTimeMs = now;
+                    mPreviousZenType = zenType;
+                }
             }
         }
     }
diff --git a/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java b/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java
index 5f08257..9c1ac34 100644
--- a/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java
+++ b/services/core/java/com/android/server/os/DeviceIdentifiersPolicyService.java
@@ -16,18 +16,15 @@
 
 package com.android.server.os;
 
-import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.Binder;
 import android.os.Build;
 import android.os.IDeviceIdentifiersPolicyService;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.os.UserHandle;
+
+import com.android.internal.telephony.TelephonyPermissions;
 import com.android.server.SystemService;
 
 /**
@@ -54,15 +51,22 @@
 
         @Override
         public @Nullable String getSerial() throws RemoteException {
-            if (UserHandle.getAppId(Binder.getCallingUid()) != Process.SYSTEM_UID
-                    && mContext.checkCallingOrSelfPermission(
-                            Manifest.permission.READ_PHONE_STATE)
-                                    != PackageManager.PERMISSION_GRANTED
-                    && mContext.checkCallingOrSelfPermission(
-                            Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-                                    != PackageManager.PERMISSION_GRANTED) {
-                throw new SecurityException("getSerial requires READ_PHONE_STATE"
-                        + " or READ_PRIVILEGED_PHONE_STATE permission");
+            // Since this invocation is on the server side a null value is used for the
+            // callingPackage as the server's package name (typically android) should not be used
+            // for any device / profile owner checks. The majority of requests for the serial number
+            // should use the getSerialForPackage method with the calling package specified.
+            if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext,
+                    /* callingPackage */ null, "getSerial")) {
+                return Build.UNKNOWN;
+            }
+            return SystemProperties.get("ro.serialno", Build.UNKNOWN);
+        }
+
+        @Override
+        public @Nullable String getSerialForPackage(String callingPackage) throws RemoteException {
+            if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext,
+                    callingPackage, "getSerial")) {
+                return Build.UNKNOWN;
             }
             return SystemProperties.get("ro.serialno", Build.UNKNOWN);
         }
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 9323040..404f152 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -20,6 +20,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.AppDetailsActivity;
 import android.app.AppGlobals;
 import android.app.IApplicationThread;
 import android.app.PendingIntent;
@@ -65,7 +66,9 @@
 import com.android.server.SystemService;
 import com.android.server.wm.ActivityTaskManagerInternal;
 
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
 
 /**
@@ -74,6 +77,7 @@
  */
 public class LauncherAppsService extends SystemService {
 
+    private static final boolean SHOW_HIDDEN_APP_ENABLED = false;
     private final LauncherAppsImpl mLauncherAppsImpl;
 
     public LauncherAppsService(Context context) {
@@ -281,15 +285,84 @@
             }
         }
 
+        private ResolveInfo getHiddenAppActivityInfo(String packageName, int callingUid,
+                UserHandle user) {
+            Intent intent = new Intent();
+            intent.setComponent(new ComponentName(packageName, AppDetailsActivity.class.getName()));
+            final PackageManagerInternal pmInt =
+                    LocalServices.getService(PackageManagerInternal.class);
+            List<ResolveInfo> apps = pmInt.queryIntentActivities(intent,
+                    PackageManager.MATCH_DIRECT_BOOT_AWARE
+                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
+                    callingUid, user.getIdentifier());
+            if (apps.size() > 0) {
+                return apps.get(0);
+            }
+            return null;
+        }
+
         @Override
         public ParceledListSlice<ResolveInfo> getLauncherActivities(String callingPackage,
-                String packageName, UserHandle user)
-                throws RemoteException {
-            return queryActivitiesForUser(callingPackage,
+                String packageName, UserHandle user) throws RemoteException {
+            ParceledListSlice<ResolveInfo> launcherActivities = queryActivitiesForUser(
+                    callingPackage,
                     new Intent(Intent.ACTION_MAIN)
                             .addCategory(Intent.CATEGORY_LAUNCHER)
                             .setPackage(packageName),
                     user);
+            if (!SHOW_HIDDEN_APP_ENABLED) {
+                return launcherActivities;
+            }
+
+            final int callingUid = injectBinderCallingUid();
+            final ArrayList<ResolveInfo> result = new ArrayList<>(launcherActivities.getList());
+            if (packageName != null) {
+                // If target package has launcher activities, then return those launcher
+                // activities. Otherwise, return hidden activity that forwards user to app
+                // details page.
+                if (result.size() > 0) {
+                    return launcherActivities;
+                }
+                ResolveInfo info = getHiddenAppActivityInfo(packageName, callingUid, user);
+                if (info != null) {
+                    result.add(info);
+                }
+                return new ParceledListSlice<>(result);
+            }
+
+            long ident = injectClearCallingIdentity();
+            try {
+                final HashSet<String> visiblePackages = new HashSet<>();
+                for (ResolveInfo info : result) {
+                    visiblePackages.add(info.activityInfo.packageName);
+                }
+                final PackageManagerInternal pmInt =
+                        LocalServices.getService(PackageManagerInternal.class);
+                List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(0,
+                        user.getIdentifier(), callingUid);
+                for (ApplicationInfo applicationInfo : installedPackages) {
+                    if (!visiblePackages.contains(applicationInfo.packageName)) {
+                        if (!shouldShowHiddenApp(applicationInfo)) {
+                            continue;
+                        }
+                        ResolveInfo info = getHiddenAppActivityInfo(applicationInfo.packageName,
+                                callingUid, user);
+                        if (info != null) {
+                            result.add(info);
+                        }
+                    }
+                }
+                return new ParceledListSlice<>(result);
+            } finally {
+                injectRestoreCallingIdentity(ident);
+            }
+        }
+
+        private static boolean shouldShowHiddenApp(ApplicationInfo appInfo) {
+            if (appInfo.isSystemApp() || appInfo.isUpdatedSystemApp()) {
+                return false;
+            }
+            return true;
         }
 
         @Override
@@ -586,15 +659,6 @@
             try {
                 final PackageManagerInternal pmInt =
                         LocalServices.getService(PackageManagerInternal.class);
-                ActivityInfo info = pmInt.getActivityInfo(component,
-                        PackageManager.MATCH_DIRECT_BOOT_AWARE
-                                | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                        callingUid, user.getIdentifier());
-                if (!info.exported) {
-                    throw new SecurityException("Cannot launch non-exported components "
-                            + component);
-                }
-
                 // Check that the component actually has Intent.CATEGORY_LAUCNCHER
                 // as calling startActivityAsUser ignores the category and just
                 // resolves based on the component if present.
@@ -607,6 +671,11 @@
                     ActivityInfo activityInfo = apps.get(i).activityInfo;
                     if (activityInfo.packageName.equals(component.getPackageName()) &&
                             activityInfo.name.equals(component.getClassName())) {
+                        if (!activityInfo.exported) {
+                            throw new SecurityException("Cannot launch non-exported components "
+                                    + component);
+                        }
+
                         // Found an activity with category launcher that matches
                         // this component so ok to launch.
                         launchIntent.setPackage(null);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 329b1da..9399ebf 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -121,6 +121,7 @@
 import android.annotation.UserIdInt;
 import android.app.ActivityManager;
 import android.app.ActivityManagerInternal;
+import android.app.AppDetailsActivity;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.ResourcesManager;
@@ -187,6 +188,7 @@
 import android.content.pm.ServiceInfo;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.Signature;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.content.pm.VerifierDeviceIdentity;
 import android.content.pm.VerifierInfo;
@@ -940,6 +942,7 @@
     private UserManagerInternal mUserManagerInternal;
     private ActivityManagerInternal mActivityManagerInternal;
     private ActivityTaskManagerInternal mActivityTaskManagerInternal;
+    private StorageManagerInternal mStorageManagerInternal;
 
     private DeviceIdleController.LocalService mDeviceIdleController;
 
@@ -2919,7 +2922,7 @@
                 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
                     final PermissionManager.SplitPermissionInfo splitPerm =
                             splitPermissions.get(splitPermNum);
-                    final String rootPerm = splitPerm.getRootPermission();
+                    final String rootPerm = splitPerm.getSplitPermission();
 
                     if (preUpgradeSdkVersion >= splitPerm.getTargetSdk()) {
                         continue;
@@ -2941,11 +2944,11 @@
                             continue;
                         }
 
-                        final String[] newPerms = splitPerm.getNewPermissions();
+                        final List<String> newPerms = splitPerm.getNewPermissions();
 
-                        final int numNewPerms = newPerms.length;
+                        final int numNewPerms = newPerms.size();
                         for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
-                            final String newPerm = newPerms[newPermNum];
+                            final String newPerm = newPerms.get(newPermNum);
                             if (checkPermission(newPerm, pkgName, userId) == PERMISSION_GRANTED) {
                                 continue;
                             }
@@ -4598,6 +4601,13 @@
         return mDeviceIdleController;
     }
 
+    private StorageManagerInternal getStorageManagerInternal() {
+        if (mStorageManagerInternal == null) {
+            mStorageManagerInternal = LocalServices.getService(StorageManagerInternal.class);
+        }
+        return mStorageManagerInternal;
+    }
+
     /**
      * Update given flags when being used to request {@link PackageInfo}.
      */
@@ -7861,10 +7871,16 @@
     @Override
     public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
         final int callingUid = Binder.getCallingUid();
+        return new ParceledListSlice<>(
+                getInstalledApplicationsListInternal(flags, userId, callingUid));
+    }
+
+    private List<ApplicationInfo> getInstalledApplicationsListInternal(int flags, int userId,
+            int callingUid) {
         if (getInstantAppPackageName(callingUid) != null) {
-            return ParceledListSlice.emptyList();
+            return Collections.emptyList();
         }
-        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
+        if (!sUserManager.exists(userId)) return Collections.emptyList();
         flags = updateFlagsForApplication(flags, userId, null);
         final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
 
@@ -7929,7 +7945,7 @@
                 }
             }
 
-            return new ParceledListSlice<>(list);
+            return list;
         }
     }
 
@@ -9505,6 +9521,30 @@
             } catch (InstallerException e) {
                 Slog.w(TAG, String.valueOf(e));
             }
+            // If this package doesn't have a sharedUserId or there are no other packages
+            // present with same sharedUserId, then delete the sandbox data too.
+            try {
+                final SharedUserSetting sharedUserSetting = mSettings.getSharedUserLPw(
+                        pkg.mSharedUserId, 0 /* pkgFlags */,
+                        0 /* pkgPrivateFlags */, false /* create */);
+                boolean deleteSandboxData = true;
+                if (sharedUserSetting != null && sharedUserSetting.packages != null) {
+                    for (int i = sharedUserSetting.packages.size() - 1; i >= 0; --i) {
+                        final PackageSetting packageSetting = sharedUserSetting.packages.valueAt(i);
+                        if (!packageSetting.name.equals(pkg.packageName)
+                                && packageSetting.readUserState(realUserId).isAvailable(
+                                        MATCH_UNINSTALLED_PACKAGES)) {
+                            deleteSandboxData = false;
+                            break;
+                        }
+                    }
+                }
+                if (deleteSandboxData && getStorageManagerInternal() != null) {
+                    getStorageManagerInternal().destroySandboxForApp(pkg.packageName, realUserId);
+                }
+            } catch (PackageManagerException e) {
+                // Should not happen
+            }
             mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
         }
     }
@@ -12118,7 +12158,9 @@
             if (mPackageListObservers.size() == 0) {
                 return;
             }
-            observers = (PackageListObserver[]) mPackageListObservers.toArray();
+            final PackageListObserver[] observerArray =
+                    new PackageListObserver[mPackageListObservers.size()];
+            observers = mPackageListObservers.toArray(observerArray);
         }
         for (int i = observers.length - 1; i >= 0; --i) {
             observers[i].onPackageAdded(packageName);
@@ -12138,7 +12180,9 @@
             if (mPackageListObservers.size() == 0) {
                 return;
             }
-            observers = (PackageListObserver[]) mPackageListObservers.toArray();
+            final PackageListObserver[] observerArray =
+                    new PackageListObserver[mPackageListObservers.size()];
+            observers = mPackageListObservers.toArray(observerArray);
         }
         for (int i = observers.length - 1; i >= 0; --i) {
             observers[i].onPackageRemoved(packageName);
@@ -12673,8 +12717,8 @@
 
     @Override
     public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
-            PersistableBundle appExtras, PersistableBundle launcherExtras, String dialogMessage,
-            String callingPackage, int userId) {
+            PersistableBundle appExtras, PersistableBundle launcherExtras,
+            SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
                 "setPackagesSuspendedAsUser");
 
@@ -12719,7 +12763,7 @@
                         unactionedPackages.add(packageName);
                         continue;
                     }
-                    pkgSetting.setSuspended(suspended, callingPackage, dialogMessage, appExtras,
+                    pkgSetting.setSuspended(suspended, callingPackage, dialogInfo, appExtras,
                             launcherExtras, userId);
                     changedPackagesList.add(packageName);
                     changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
@@ -17773,7 +17817,7 @@
                     false /*hidden*/,
                     false /*suspended*/,
                     null /*suspendingPackage*/,
-                    null /*dialogMessage*/,
+                    null /*dialogInfo*/,
                     null /*suspendedAppExtras*/,
                     null /*suspendedLauncherExtras*/,
                     false /*instantApp*/,
@@ -19356,6 +19400,16 @@
                 throw new SecurityException("Cannot disable a protected package: " + packageName);
             }
         }
+        // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden
+        // app details activity
+        if (AppDetailsActivity.class.getName().equals(className)) {
+            if (mContext.checkCallingOrSelfPermission(
+                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE)
+                    != PackageManager.PERMISSION_GRANTED) {
+                Slog.e(TAG, "Cannot disable a protected component: " + packageName);
+                return;
+            }
+        }
 
         synchronized (mPackages) {
             if (callingUid == Process.SHELL_UID
@@ -19820,9 +19874,7 @@
         mDexManager.systemReady();
         mPackageDexOptimizer.systemReady();
 
-        StorageManagerInternal storageManagerInternal = LocalServices.getService(
-                StorageManagerInternal.class);
-        storageManagerInternal.addExternalStoragePolicy(
+        getStorageManagerInternal().addExternalStoragePolicy(
                 new StorageManagerInternal.ExternalStorageMountPolicy() {
             @Override
             public int getMountMode(int uid, String packageName) {
@@ -21215,10 +21267,8 @@
         }
 
         prepareAppDataContentsLeafLIF(pkg, userId, flags);
-        final StorageManagerInternal storageManagerInternal
-                = LocalServices.getService(StorageManagerInternal.class);
-        if (storageManagerInternal != null) {
-            storageManagerInternal.mountExternalStorageForApp(
+        if (getStorageManagerInternal() != null) {
+            getStorageManagerInternal().prepareSandboxForApp(
                     pkg.packageName, appId, pkg.mSharedUserId, userId);
         }
     }
@@ -22255,6 +22305,14 @@
         }
 
         @Override
+        public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
+                int callingUid) {
+            return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
+                    callingUid);
+        }
+
+
+        @Override
         public boolean isPlatformSigned(String packageName) {
             PackageSetting packageSetting = mSettings.mPackages.get(packageName);
             if (packageSetting == null) {
@@ -22528,10 +22586,10 @@
         }
 
         @Override
-        public String getSuspendedDialogMessage(String suspendedPackage, int userId) {
+        public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage, int userId) {
             synchronized (mPackages) {
                 final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
-                return (ps != null) ? ps.readUserState(userId).dialogMessage : null;
+                return (ps != null) ? ps.readUserState(userId).dialogInfo : null;
             }
         }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 93729d1..e25cca4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -51,6 +51,7 @@
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.content.pm.VersionedPackage;
 import android.content.pm.dex.ArtManager;
@@ -1701,9 +1702,18 @@
         }
         final String callingPackage =
                 (Binder.getCallingUid() == Process.ROOT_UID) ? "root" : "com.android.shell";
+
+        final SuspendDialogInfo info;
+        if (!TextUtils.isEmpty(dialogMessage)) {
+            info = new SuspendDialogInfo.Builder()
+                    .setMessage(dialogMessage)
+                    .build();
+        } else {
+            info = null;
+        }
         try {
             mInterface.setPackagesSuspendedAsUser(new String[]{packageName}, suspendedState,
-                    appExtras, launcherExtras, dialogMessage, callingPackage, userId);
+                    appExtras, launcherExtras, info, callingPackage, userId);
             pw.println("Package " + packageName + " new suspended state: "
                     + mInterface.isPackageSuspendedForUser(packageName, userId));
             return 0;
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index fd6aceb..3c22f07 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -26,6 +26,7 @@
 import android.content.pm.PackageParser;
 import android.content.pm.PackageUserState;
 import android.content.pm.Signature;
+import android.content.pm.SuspendDialogInfo;
 import android.os.PersistableBundle;
 import android.service.pm.PackageProto;
 import android.util.ArraySet;
@@ -395,12 +396,12 @@
         return readUserState(userId).suspended;
     }
 
-    void setSuspended(boolean suspended, String suspendingPackage, String dialogMessage,
+    void setSuspended(boolean suspended, String suspendingPackage, SuspendDialogInfo dialogInfo,
             PersistableBundle appExtras, PersistableBundle launcherExtras, int userId) {
         final PackageUserState existingUserState = modifyUserState(userId);
         existingUserState.suspended = suspended;
         existingUserState.suspendingPackage = suspended ? suspendingPackage : null;
-        existingUserState.dialogMessage = suspended ? dialogMessage : null;
+        existingUserState.dialogInfo = suspended ? dialogInfo : null;
         existingUserState.suspendedAppExtras = suspended ? appExtras : null;
         existingUserState.suspendedLauncherExtras = suspended ? launcherExtras : null;
     }
@@ -423,7 +424,7 @@
 
     void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
             boolean notLaunched, boolean hidden, boolean suspended, String suspendingPackage,
-            String dialogMessage, PersistableBundle suspendedAppExtras,
+            SuspendDialogInfo dialogInfo, PersistableBundle suspendedAppExtras,
             PersistableBundle suspendedLauncherExtras, boolean instantApp,
             boolean virtualPreload, String lastDisableAppCaller,
             ArraySet<String> enabledComponents, ArraySet<String> disabledComponents,
@@ -438,7 +439,7 @@
         state.hidden = hidden;
         state.suspended = suspended;
         state.suspendingPackage = suspendingPackage;
-        state.dialogMessage = dialogMessage;
+        state.dialogInfo = dialogInfo;
         state.suspendedAppExtras = suspendedAppExtras;
         state.suspendedLauncherExtras = suspendedLauncherExtras;
         state.lastDisableAppCaller = lastDisableAppCaller;
diff --git a/services/core/java/com/android/server/pm/PackageSignatures.java b/services/core/java/com/android/server/pm/PackageSignatures.java
index 471729e..6bce788 100644
--- a/services/core/java/com/android/server/pm/PackageSignatures.java
+++ b/services/core/java/com/android/server/pm/PackageSignatures.java
@@ -16,18 +16,18 @@
 
 package com.android.server.pm;
 
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 import android.annotation.NonNull;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
 import android.content.pm.Signature;
 import android.util.Log;
 
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
 import java.io.IOException;
 import java.security.cert.CertificateException;
 import java.util.ArrayList;
@@ -61,23 +61,22 @@
         serializer.attribute(null, "count", Integer.toString(mSigningDetails.signatures.length));
         serializer.attribute(null, "schemeVersion",
                 Integer.toString(mSigningDetails.signatureSchemeVersion));
-        writeCertsListXml(serializer, writtenSignatures, mSigningDetails.signatures, null);
+        writeCertsListXml(serializer, writtenSignatures, mSigningDetails.signatures, false);
 
         // if we have past signer certificate information, write it out
         if (mSigningDetails.pastSigningCertificates != null) {
             serializer.startTag(null, "pastSigs");
             serializer.attribute(null, "count",
                     Integer.toString(mSigningDetails.pastSigningCertificates.length));
-            writeCertsListXml(
-                    serializer, writtenSignatures, mSigningDetails.pastSigningCertificates,
-                    mSigningDetails.pastSigningCertificatesFlags);
+            writeCertsListXml(serializer, writtenSignatures,
+                    mSigningDetails.pastSigningCertificates, true);
             serializer.endTag(null, "pastSigs");
         }
         serializer.endTag(null, tagName);
     }
 
     private void writeCertsListXml(XmlSerializer serializer, ArrayList<Signature> writtenSignatures,
-            Signature[] signatures, int[] flags) throws IOException {
+            Signature[] signatures, boolean isPastSigs) throws IOException {
         for (int i=0; i<signatures.length; i++) {
             serializer.startTag(null, "cert");
             final Signature sig = signatures[i];
@@ -96,8 +95,10 @@
                 serializer.attribute(null, "index", Integer.toString(numWritten));
                 serializer.attribute(null, "key", sig.toCharsString());
             }
-            if (flags != null) {
-                serializer.attribute(null, "flags", Integer.toString(flags[i]));
+            // The flags attribute is only written for previous signatures to represent the
+            // capabilities the developer wants to grant to the previous signing certificates.
+            if (isPastSigs) {
+                serializer.attribute(null, "flags", Integer.toString(sig.getFlags()));
             }
             serializer.endTag(null, "cert");
         }
@@ -114,6 +115,7 @@
                     "Error in package manager settings: <sigs> has"
                        + " no count at " + parser.getPositionDescription());
             XmlUtils.skipCurrentTag(parser);
+            return;
         }
         final int count = Integer.parseInt(countStr);
 
@@ -128,16 +130,11 @@
             signatureSchemeVersion = Integer.parseInt(schemeVersionStr);
         }
         builder.setSignatureSchemeVersion(signatureSchemeVersion);
-        Signature[] signatures = new Signature[count];
-        int pos = readCertsListXml(parser, readSignatures, signatures, null, builder);
+        ArrayList<Signature> signatureList = new ArrayList<>();
+        int pos = readCertsListXml(parser, readSignatures, signatureList, count, false, builder);
+        Signature[] signatures = signatureList.toArray(new Signature[signatureList.size()]);
         builder.setSignatures(signatures);
         if (pos < count) {
-            // Should never happen -- there is an error in the written
-            // settings -- but if it does we don't want to generate
-            // a bad array.
-            Signature[] newSigs = new Signature[pos];
-            System.arraycopy(signatures, 0, newSigs, 0, pos);
-            builder = builder.setSignatures(newSigs);
             PackageManagerService.reportSettingsProblem(Log.WARN,
                     "Error in package manager settings: <sigs> count does not match number of "
                             + " <cert> entries" + parser.getPositionDescription());
@@ -154,9 +151,9 @@
     }
 
     private int readCertsListXml(XmlPullParser parser, ArrayList<Signature> readSignatures,
-            Signature[] signatures, int[] flags, PackageParser.SigningDetails.Builder builder)
+            ArrayList<Signature> signatures, int count, boolean isPastSigs,
+            PackageParser.SigningDetails.Builder builder)
             throws IOException, XmlPullParserException {
-        int count = signatures.length;
         int pos = 0;
 
         int outerDepth = parser.getDepth();
@@ -174,6 +171,7 @@
                 if (pos < count) {
                     String index = parser.getAttributeValue(null, "index");
                     if (index != null) {
+                        boolean signatureParsed = false;
                         try {
                             int idx = Integer.parseInt(index);
                             String key = parser.getAttributeValue(null, "key");
@@ -181,7 +179,8 @@
                                 if (idx >= 0 && idx < readSignatures.size()) {
                                     Signature sig = readSignatures.get(idx);
                                     if (sig != null) {
-                                        signatures[pos] = readSignatures.get(idx);
+                                        signatures.add(sig);
+                                        signatureParsed = true;
                                     } else {
                                         PackageManagerService.reportSettingsProblem(Log.WARN,
                                                 "Error in package manager settings: <cert> "
@@ -195,12 +194,15 @@
                                                     + parser.getPositionDescription());
                                 }
                             } else {
-                                while (readSignatures.size() <= idx) {
+                                // Create the signature first to prevent adding null entries to the
+                                // output List if the key value is invalid.
+                                Signature sig = new Signature(key);
+                                while (readSignatures.size() < idx) {
                                     readSignatures.add(null);
                                 }
-                                Signature sig = new Signature(key);
-                                readSignatures.set(idx, sig);
-                                signatures[pos] = sig;
+                                readSignatures.add(sig);
+                                signatures.add(sig);
+                                signatureParsed = true;
                             }
                         } catch (NumberFormatException e) {
                             PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -215,11 +217,22 @@
                                             + e.getMessage());
                         }
 
-                        if (flags != null) {
+                        if (isPastSigs) {
                             String flagsStr = parser.getAttributeValue(null, "flags");
                             if (flagsStr != null) {
                                 try {
-                                    flags[pos] = Integer.parseInt(flagsStr);
+                                    int flagsValue = Integer.parseInt(flagsStr);
+                                    // only modify the flags if the signature of the previous signer
+                                    // was successfully parsed above
+                                    if (signatureParsed) {
+                                        signatures.get(signatures.size() - 1).setFlags(flagsValue);
+                                    } else {
+                                        PackageManagerService.reportSettingsProblem(Log.WARN,
+                                                "Error in package manager settings: signature not "
+                                                        + "available at index "
+                                                        + pos + " to set flags at "
+                                                        + parser.getPositionDescription());
+                                    }
                                 } catch (NumberFormatException e) {
                                     PackageManagerService.reportSettingsProblem(Log.WARN,
                                             "Error in package manager settings: <cert> "
@@ -246,7 +259,7 @@
                 pos++;
                 XmlUtils.skipCurrentTag(parser);
             } else if (tagName.equals("pastSigs")) {
-                if (flags == null) {
+                if (!isPastSigs) {
                     // we haven't encountered pastSigs yet, go ahead
                     String countStr = parser.getAttributeValue(null, "count");
                     if (countStr == null) {
@@ -254,32 +267,23 @@
                                 "Error in package manager settings: <pastSigs> has"
                                         + " no count at " + parser.getPositionDescription());
                         XmlUtils.skipCurrentTag(parser);
+                        continue;
                     }
                     try {
                         final int pastSigsCount = Integer.parseInt(countStr);
-                        Signature[] pastSignatures = new Signature[pastSigsCount];
-                        int[] pastSignaturesFlags = new int[pastSigsCount];
-                        int pastSigsPos = readCertsListXml(parser, readSignatures, pastSignatures,
-                                pastSignaturesFlags, builder);
-                        builder = builder
-                                .setPastSigningCertificates(pastSignatures)
-                                .setPastSigningCertificatesFlags(pastSignaturesFlags);
+                        ArrayList<Signature> pastSignatureList = new ArrayList<>();
+                        int pastSigsPos = readCertsListXml(parser, readSignatures,
+                                pastSignatureList,
+                                pastSigsCount, true, builder);
+                        Signature[] pastSignatures = pastSignatureList.toArray(
+                                new Signature[pastSignatureList.size()]);
+                        builder = builder.setPastSigningCertificates(pastSignatures);
 
                         if (pastSigsPos < pastSigsCount) {
-                            // Should never happen -- there is an error in the written
-                            // settings -- but if it does we don't want to generate
-                            // a bad array.
-                            Signature[] newSigs = new Signature[pastSigsPos];
-                            System.arraycopy(pastSignatures, 0, newSigs, 0, pastSigsPos);
-                            int[] newFlags = new int[pastSigsPos];
-                            System.arraycopy(pastSignaturesFlags, 0, newFlags, 0, pastSigsPos);
-                            builder = builder
-                                    .setPastSigningCertificates(newSigs)
-                                    .setPastSigningCertificatesFlags(newFlags);
                             PackageManagerService.reportSettingsProblem(Log.WARN,
                                     "Error in package manager settings: <pastSigs> count does not "
-                                    + "match number of <cert> entries "
-                                    + parser.getPositionDescription());
+                                            + "match number of <cert> entries "
+                                            + parser.getPositionDescription());
                         }
                     } catch (NumberFormatException e) {
                         PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -326,7 +330,8 @@
                 buf.append(Integer.toHexString(
                         mSigningDetails.pastSigningCertificates[i].hashCode()));
                 buf.append(" flags: ");
-                buf.append(Integer.toHexString(mSigningDetails.pastSigningCertificatesFlags[i]));
+                buf.append(
+                        Integer.toHexString(mSigningDetails.pastSigningCertificates[i].getFlags()));
             }
         }
         buf.append("]}");
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 5c88e06..e2818b7 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -49,6 +49,7 @@
 import android.content.pm.PermissionInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.Signature;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.content.pm.VerifierDeviceIdentity;
 import android.net.Uri;
@@ -203,6 +204,7 @@
     private static final String TAG_DEFAULT_BROWSER = "default-browser";
     private static final String TAG_DEFAULT_DIALER = "default-dialer";
     private static final String TAG_VERSION = "version";
+    private static final String TAG_SUSPENDED_DIALOG_INFO = "suspended-dialog-info";
     private static final String TAG_SUSPENDED_APP_EXTRAS = "suspended-app-extras";
     private static final String TAG_SUSPENDED_LAUNCHER_EXTRAS = "suspended-launcher-extras";
 
@@ -222,6 +224,10 @@
     private static final String ATTR_HIDDEN = "hidden";
     private static final String ATTR_SUSPENDED = "suspended";
     private static final String ATTR_SUSPENDING_PACKAGE = "suspending-package";
+    /**
+     * @deprecated Legacy attribute, kept only for upgrading from P builds.
+     */
+    @Deprecated
     private static final String ATTR_SUSPEND_DIALOG_MESSAGE = "suspend_dialog_message";
     // Legacy, uninstall blocks are stored separately.
     @Deprecated
@@ -730,7 +736,7 @@
                                 false /*hidden*/,
                                 false /*suspended*/,
                                 null /*suspendingPackage*/,
-                                null /*dialogMessage*/,
+                                null /*dialogInfo*/,
                                 null /*suspendedAppExtras*/,
                                 null /*suspendedLauncherExtras*/,
                                 instantApp,
@@ -1620,7 +1626,7 @@
                                 false /*hidden*/,
                                 false /*suspended*/,
                                 null /*suspendingPackage*/,
-                                null /*dialogMessage*/,
+                                null /*dialogInfo*/,
                                 null /*suspendedAppExtras*/,
                                 null /*suspendedLauncherExtras*/,
                                 false /*instantApp*/,
@@ -1730,6 +1736,7 @@
                     ArraySet<String> disabledComponents = null;
                     PersistableBundle suspendedAppExtras = null;
                     PersistableBundle suspendedLauncherExtras = null;
+                    SuspendDialogInfo suspendDialogInfo = null;
 
                     int packageDepth = parser.getDepth();
                     while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
@@ -1752,20 +1759,28 @@
                             case TAG_SUSPENDED_LAUNCHER_EXTRAS:
                                 suspendedLauncherExtras = PersistableBundle.restoreFromXml(parser);
                                 break;
+                            case TAG_SUSPENDED_DIALOG_INFO:
+                                suspendDialogInfo = SuspendDialogInfo.restoreFromXml(parser);
+                                break;
                             default:
                                 Slog.wtf(TAG, "Unknown tag " + parser.getName() + " under tag "
                                         + TAG_PACKAGE);
                         }
                     }
+                    if (suspendDialogInfo == null && !TextUtils.isEmpty(dialogMessage)) {
+                        suspendDialogInfo = new SuspendDialogInfo.Builder()
+                                .setMessage(dialogMessage)
+                                .build();
+                    }
 
                     if (blockUninstall) {
                         setBlockUninstallLPw(userId, name, true);
                     }
                     ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
-                            hidden, suspended, suspendingPackage, dialogMessage, suspendedAppExtras,
-                            suspendedLauncherExtras, instantApp, virtualPreload, enabledCaller,
-                            enabledComponents, disabledComponents, verifState, linkGeneration,
-                            installReason, harmfulAppWarning);
+                            hidden, suspended, suspendingPackage, suspendDialogInfo,
+                            suspendedAppExtras, suspendedLauncherExtras, instantApp, virtualPreload,
+                            enabledCaller, enabledComponents, disabledComponents, verifState,
+                            linkGeneration, installReason, harmfulAppWarning);
                 } else if (tagName.equals("preferred-activities")) {
                     readPreferredActivitiesLPw(parser, userId);
                 } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
@@ -2076,9 +2091,10 @@
                         serializer.attribute(null, ATTR_SUSPENDING_PACKAGE,
                                 ustate.suspendingPackage);
                     }
-                    if (ustate.dialogMessage != null) {
-                        serializer.attribute(null, ATTR_SUSPEND_DIALOG_MESSAGE,
-                                ustate.dialogMessage);
+                    if (ustate.dialogInfo != null) {
+                        serializer.startTag(null, TAG_SUSPENDED_DIALOG_INFO);
+                        ustate.dialogInfo.saveToXml(serializer);
+                        serializer.endTag(null, TAG_SUSPENDED_DIALOG_INFO);
                     }
                     if (ustate.suspendedAppExtras != null) {
                         serializer.startTag(null, TAG_SUSPENDED_APP_EXTRAS);
@@ -2618,6 +2634,10 @@
             writeKernelMappingLPr(ps);
         }
 
+        for (final SharedUserSetting sus : mSharedUsers.values()) {
+            knownSet.remove(sus.getSandboxName());
+        }
+
         // Remove any unclaimed mappings
         for (int i = 0; i < knownSet.size(); i++) {
             final String name = knownSet.valueAt(i);
@@ -2628,30 +2648,42 @@
         }
     }
 
+    void writeKernelMappingLPr(SharedUserSetting sus) {
+        if (mKernelMappingFilename == null || sus == null || sus.name == null) return;
+
+        writeKernelMappingLPr(sus.getSandboxName(), sus.userId, sus.getNotInstalledUserIds());
+    }
+
     void writeKernelMappingLPr(PackageSetting ps) {
         if (mKernelMappingFilename == null || ps == null || ps.name == null) return;
 
-        KernelPackageState cur = mKernelMapping.get(ps.name);
+        writeKernelMappingLPr(ps.name, ps.appId, ps.getNotInstalledUserIds());
+        if (ps.sharedUser != null) {
+            writeKernelMappingLPr(ps.sharedUser);
+        }
+    }
+
+    void writeKernelMappingLPr(String name, int appId, int[] excludedUserIds) {
+        KernelPackageState cur = mKernelMapping.get(name);
         final boolean firstTime = cur == null;
-        int[] excludedUserIds = ps.getNotInstalledUserIds();
         final boolean userIdsChanged = firstTime
                 || !Arrays.equals(excludedUserIds, cur.excludedUserIds);
 
         // Package directory
-        final File dir = new File(mKernelMappingFilename, ps.name);
+        final File dir = new File(mKernelMappingFilename, name);
 
         if (firstTime) {
             dir.mkdir();
             // Create a new mapping state
             cur = new KernelPackageState();
-            mKernelMapping.put(ps.name, cur);
+            mKernelMapping.put(name, cur);
         }
 
         // If mapping is incorrect or non-existent, write the appid file
-        if (cur.appId != ps.appId) {
+        if (cur.appId != appId) {
             final File appIdFile = new File(dir, "appid");
-            writeIntToFile(appIdFile, ps.appId);
-            if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + ps.name + " to " + ps.appId);
+            writeIntToFile(appIdFile, appId);
+            if (DEBUG_KERNEL) Slog.d(TAG, "Mapping " + name + " to " + appId);
         }
 
         if (userIdsChanged) {
@@ -2661,7 +2693,7 @@
                         excludedUserIds[i])) {
                     writeIntToFile(new File(dir, "excluded_userids"), excludedUserIds[i]);
                     if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + excludedUserIds[i] + " to "
-                            + ps.name + "/excluded_userids");
+                            + name + "/excluded_userids");
                 }
             }
             // Build the inclusion list -- the ids to remove from the exclusion list
@@ -2671,7 +2703,7 @@
                         writeIntToFile(new File(dir, "clear_userid"),
                                 cur.excludedUserIds[i]);
                         if (DEBUG_KERNEL) Slog.d(TAG, "Writing " + cur.excludedUserIds[i] + " to "
-                                + ps.name + "/clear_userid");
+                                + name + "/clear_userid");
 
                     }
                 }
@@ -4737,8 +4769,8 @@
                 final PackageUserState pus = ps.readUserState(user.id);
                 pw.print(" suspendingPackage=");
                 pw.print(pus.suspendingPackage);
-                pw.print(" dialogMessage=");
-                pw.print(pus.dialogMessage);
+                pw.print(" dialogInfo=");
+                pw.print(pus.dialogInfo);
             }
             pw.print(" stopped=");
             pw.print(ps.getStopped(user.id));
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index 1a8b2af..32826e5 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -23,6 +23,10 @@
 import android.util.ArraySet;
 import android.util.proto.ProtoOutputStream;
 
+import com.android.internal.util.ArrayUtils;
+
+import libcore.util.EmptyArray;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -144,6 +148,28 @@
         }
     }
 
+    /** Returns userIds which doesn't have any packages with this sharedUserId */
+    public int[] getNotInstalledUserIds() {
+        int[] excludedUserIds = null;
+        for (PackageSetting ps : packages) {
+            final int[] userIds = ps.getNotInstalledUserIds();
+            if (excludedUserIds == null) {
+                excludedUserIds = userIds;
+            } else {
+                for (int userId : excludedUserIds) {
+                    if (!ArrayUtils.contains(userIds, userId)) {
+                        excludedUserIds = ArrayUtils.removeInt(excludedUserIds, userId);
+                    }
+                }
+            }
+        }
+        return excludedUserIds == null ? EmptyArray.INT : excludedUserIds;
+    }
+
+    public String getSandboxName() {
+        return "shared:" + name;
+    }
+
     /** Updates all fields in this shared user setting from another. */
     public SharedUserSetting updateFrom(SharedUserSetting sharedUser) {
         copyFrom(sharedUser);
diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
index 1315502..dd04652 100644
--- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
+++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java
@@ -127,7 +127,8 @@
             UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE,
             UserManager.DISALLOW_AMBIENT_DISPLAY,
             UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT,
-            UserManager.DISALLOW_PRINTING
+            UserManager.DISALLOW_PRINTING,
+            UserManager.DISALLOW_CONFIG_PRIVATE_DNS
     });
 
     /**
@@ -163,7 +164,8 @@
      * User restrictions that cannot be set by profile owners. Applied to all users.
      */
     private static final Set<String> DEVICE_OWNER_ONLY_RESTRICTIONS = Sets.newArraySet(
-            UserManager.DISALLOW_USER_SWITCH
+            UserManager.DISALLOW_USER_SWITCH,
+            UserManager.DISALLOW_CONFIG_PRIVATE_DNS
     );
 
     /**
@@ -741,6 +743,10 @@
                 restriction = UserManager.DISALLOW_CONFIG_SCREEN_TIMEOUT;
                 break;
 
+            case android.provider.Settings.Global.PRIVATE_DNS_MODE:
+            case android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER:
+                restriction = UserManager.DISALLOW_CONFIG_PRIVATE_DNS;
+                break;
             default:
                 if (setting.startsWith(Settings.Global.DATA_ROAMING)) {
                     if ("0".equals(value)) {
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index 910ea73..1f05dc9 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -16,6 +16,8 @@
 
 package com.android.server.pm.dex;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.AppOpsManager;
 import android.content.Context;
@@ -57,8 +59,6 @@
 import dalvik.system.VMRuntime;
 
 import libcore.io.IoUtils;
-import libcore.util.NonNull;
-import libcore.util.Nullable;
 
 import java.io.File;
 import java.io.FileNotFoundException;
diff --git a/services/core/java/com/android/server/pm/dex/TEST_MAPPING b/services/core/java/com/android/server/pm/dex/TEST_MAPPING
index ad52559..c93af2a 100644
--- a/services/core/java/com/android/server/pm/dex/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/dex/TEST_MAPPING
@@ -1,19 +1,12 @@
 {
   "presubmit": [
     {
-      "name": "DexLoggerTests"
-    },
-    {
-      "name": "DexManagerTests"
-    },
-    {
-      "name": "DexoptOptionsTests"
-    },
-    {
-      "name": "DexoptUtilsTest"
-    },
-    {
-      "name": "PackageDexUsageTests"
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.pm.dex"
+        }
+      ]
     },
     {
       "name": "DexLoggerIntegrationTests"
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 8202580..e194d15 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -384,7 +384,7 @@
         }
         if (!isRuntime() && !isDevelopment()) {
             throw new SecurityException("Permission " + name
-                    + " is not a changeable permission type");
+                    + " requested by " + pkg.packageName + " is not a changeable permission type");
         }
     }
 
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 6f644dd..45cb477 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -31,9 +31,11 @@
 import android.content.pm.ApplicationInfo;
 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.PackageManagerInternal.PackagesProvider;
 import android.content.pm.PackageManagerInternal.SyncAdapterPackagesProvider;
+import android.content.pm.PermissionInfo;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.media.RingtoneManager;
@@ -1033,8 +1035,8 @@
 
             if (applicationInfo != null
                     && applicationInfo.targetSdkVersion < splitPerm.getTargetSdk()
-                    && permissionsWithoutSplits.contains(splitPerm.getRootPermission())) {
-                Collections.addAll(permissions, splitPerm.getNewPermissions());
+                    && permissionsWithoutSplits.contains(splitPerm.getSplitPermission())) {
+                permissions.addAll(splitPerm.getNewPermissions());
             }
         }
 
@@ -1182,6 +1184,11 @@
             final int permissionGrantCount = permissionGrants.size();
             for (int j = 0; j < permissionGrantCount; j++) {
                 DefaultPermissionGrant permissionGrant = permissionGrants.get(j);
+                if (!isPermissionDangerous(permissionGrant.name)) {
+                    Log.w(TAG, "Ignoring permission " + permissionGrant.name
+                            + " which isn't dangerous");
+                    continue;
+                }
                 if (permissions == null) {
                     permissions = new ArraySet<>();
                 } else {
@@ -1350,6 +1357,16 @@
                 && pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1;
     }
 
+    private boolean isPermissionDangerous(String name) {
+        try {
+            final PermissionInfo pi = mContext.getPackageManager().getPermissionInfo(name, 0);
+            return (pi.getProtection() == PermissionInfo.PROTECTION_DANGEROUS);
+        } catch (NameNotFoundException e) {
+            // When unknown assume it's dangerous to be on the safe side
+            return true;
+        }
+    }
+
     private static final class DefaultPermissionGrant {
         final String name;
         final boolean fixed;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 2557f46..c5cee32 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1655,11 +1655,9 @@
         }
         final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
         mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
-        if (keyguardShowing) {
-            // since it took two seconds of long press to bring this up,
-            // poke the wake lock so they have some time to see the dialog.
-            mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
-        }
+        // since it took two seconds of long press to bring this up,
+        // poke the wake lock so they have some time to see the dialog.
+        mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
     }
 
     boolean isDeviceProvisioned() {
@@ -2063,7 +2061,8 @@
                     }
                 });
         mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext);
-        mWindowManagerFuncs.registerPointerEventListener(mSystemGestures);
+        //TODO (b/111365687) : make system context per display.
+        mWindowManagerFuncs.registerPointerEventListener(mSystemGestures, DEFAULT_DISPLAY);
 
         mVibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
         mLongPressVibePattern = getLongIntArray(mContext.getResources(),
@@ -2260,13 +2259,16 @@
             WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
             lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
             wm.addView(mPointerLocationView, lp);
-            mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView);
+            //TODO (b/111365687) : make system context per display.
+            mWindowManagerFuncs.registerPointerEventListener(mPointerLocationView, DEFAULT_DISPLAY);
         }
     }
 
     private void disablePointerLocation() {
         if (mPointerLocationView != null) {
-            mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView);
+            //TODO (b/111365687) : make system context per display.
+            mWindowManagerFuncs.unregisterPointerEventListener(mPointerLocationView,
+                    DEFAULT_DISPLAY);
             WindowManager wm = (WindowManager) mContext.getSystemService(WINDOW_SERVICE);
             wm.removeView(mPointerLocationView);
             mPointerLocationView = null;
@@ -4777,6 +4779,7 @@
             pf.bottom = df.bottom = of.bottom = displayFrames.mUnrestricted.bottom;
             // ...with content insets above the nav bar
             cf.bottom = vf.bottom = displayFrames.mStable.bottom;
+            // TODO (b/111364446): Support showing IME on non-default displays
             if (mStatusBar != null && mFocusedWindow == mStatusBar && canReceiveInput(mStatusBar)) {
                 // The status bar forces the navigation bar while it's visible. Make sure the IME
                 // avoids the navigation bar in that case.
@@ -6047,6 +6050,19 @@
             }
         }
 
+        // Intercept the Accessibility keychord (CTRL + ALT + Z) for keyboard users.
+        if (mAccessibilityShortcutController.isAccessibilityShortcutAvailable(isKeyguardLocked())) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_Z: {
+                    if (down && event.isCtrlPressed() && event.isAltPressed()) {
+                        mHandler.sendMessage(mHandler.obtainMessage(MSG_ACCESSIBILITY_SHORTCUT));
+                        result &= ~ACTION_PASS_TO_USER;
+                    }
+                    break;
+                }
+            }
+        }
+
         if (useHapticFeedback) {
             performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false,
                     "Virtual Key - Press");
@@ -6848,37 +6864,6 @@
     }
 
     @Override
-    public int getUserRotationMode() {
-        return Settings.System.getIntForUser(mContext.getContentResolver(),
-                Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) != 0 ?
-                        WindowManagerPolicy.USER_ROTATION_FREE :
-                                WindowManagerPolicy.USER_ROTATION_LOCKED;
-    }
-
-    // User rotation: to be used when all else fails in assigning an orientation to the device
-    @Override
-    public void setUserRotationMode(int mode, int rot) {
-        ContentResolver res = mContext.getContentResolver();
-
-        // mUserRotationMode and mUserRotation will be assigned by the content observer
-        if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
-            Settings.System.putIntForUser(res,
-                    Settings.System.USER_ROTATION,
-                    rot,
-                    UserHandle.USER_CURRENT);
-            Settings.System.putIntForUser(res,
-                    Settings.System.ACCELEROMETER_ROTATION,
-                    0,
-                    UserHandle.USER_CURRENT);
-        } else {
-            Settings.System.putIntForUser(res,
-                    Settings.System.ACCELEROMETER_ROTATION,
-                    1,
-                    UserHandle.USER_CURRENT);
-        }
-    }
-
-    @Override
     public void setSafeMode(boolean safeMode) {
         mSafeMode = safeMode;
         if (safeMode) {
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 27ab3ef..db13cbc 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -82,7 +82,6 @@
 import android.view.IWindowManager;
 import android.view.InputEventReceiver;
 import android.view.KeyEvent;
-import android.view.Surface;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.view.WindowManagerPolicyConstants;
@@ -559,10 +558,10 @@
         public Object getWindowManagerLock();
 
         /** Register a system listener for touch events */
-        void registerPointerEventListener(PointerEventListener listener);
+        void registerPointerEventListener(PointerEventListener listener, int displayId);
 
         /** Unregister a system listener for touch events */
-        void unregisterPointerEventListener(PointerEventListener listener);
+        void unregisterPointerEventListener(PointerEventListener listener, int displayId);
 
         /**
          * @return The content insets of the docked divider window.
@@ -1483,26 +1482,6 @@
     public void keepScreenOnStoppedLw();
 
     /**
-     * Gets the current user rotation mode.
-     *
-     * @return The rotation mode.
-     *
-     * @see #USER_ROTATION_LOCKED
-     * @see #USER_ROTATION_FREE
-     */
-    @UserRotationMode
-    public int getUserRotationMode();
-
-    /**
-     * Inform the policy that the user has chosen a preferred orientation ("rotation lock").
-     *
-     * @param mode One of {@link #USER_ROTATION_LOCKED} or {@link #USER_ROTATION_FREE}.
-     * @param rotation One of {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
-     *                 {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
-     */
-    public void setUserRotationMode(@UserRotationMode int mode, @Surface.Rotation int rotation);
-
-    /**
      * Called when a new system UI visibility is being reported, allowing
      * the policy to adjust what is actually reported.
      * @param visibility The raw visibility reported by the status bar.
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
index 1cba1c7..a55b49f 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java
@@ -95,10 +95,22 @@
         mIsShowing = showing;
 
         mCallback.onShowingChanged();
-        try {
-            mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId);
-        } catch (RemoteException e) {
-            Slog.e(TAG, "Error informing keystore of screen lock", e);
+        int retry = 2;
+        while (retry > 0) {
+            try {
+                mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId);
+                break;
+            } catch (RemoteException e) {
+                if (retry == 2) {
+                    Slog.w(TAG, "Error informing keystore of screen lock. Keystore may have died"
+                            + " -> refreshing service token and retrying");
+                    mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager
+                            .getService("android.security.keystore"));
+                } else {
+                    Slog.e(TAG, "Error informing keystore of screen lock after retrying once", e);
+                }
+                --retry;
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/power/BatterySaverPolicy.java b/services/core/java/com/android/server/power/BatterySaverPolicy.java
index ed2b79e..4f8e6b6 100644
--- a/services/core/java/com/android/server/power/BatterySaverPolicy.java
+++ b/services/core/java/com/android/server/power/BatterySaverPolicy.java
@@ -75,6 +75,8 @@
     private static final String KEY_FORCE_BACKGROUND_CHECK = "force_background_check";
     private static final String KEY_OPTIONAL_SENSORS_DISABLED = "optional_sensors_disabled";
     private static final String KEY_AOD_DISABLED = "aod_disabled";
+    // Go into deep Doze as soon as the screen turns off.
+    private static final String KEY_QUICK_DOZE_ENABLED = "quick_doze_enabled";
     private static final String KEY_SEND_TRON_LOG = "send_tron_log";
 
     private static final String KEY_CPU_FREQ_INTERACTIVE = "cpufreq-i";
@@ -228,6 +230,12 @@
     private boolean mAodDisabled;
 
     /**
+     * Whether Quick Doze is enabled or not.
+     */
+    @GuardedBy("mLock")
+    private boolean mQuickDozeEnabled;
+
+    /**
      * Whether BatterySavingStats should send tron events.
      */
     @GuardedBy("mLock")
@@ -392,6 +400,7 @@
         mForceBackgroundCheck = parser.getBoolean(KEY_FORCE_BACKGROUND_CHECK, true);
         mOptionalSensorsDisabled = parser.getBoolean(KEY_OPTIONAL_SENSORS_DISABLED, true);
         mAodDisabled = parser.getBoolean(KEY_AOD_DISABLED, true);
+        mQuickDozeEnabled = parser.getBoolean(KEY_QUICK_DOZE_ENABLED, false);
         mSendTronLog = parser.getBoolean(KEY_SEND_TRON_LOG, false);
 
         // Get default value from Settings.Secure
@@ -434,6 +443,7 @@
         if (mLaunchBoostDisabled) sb.append("l");
         if (mOptionalSensorsDisabled) sb.append("S");
         if (mAodDisabled) sb.append("o");
+        if (mQuickDozeEnabled) sb.append("q");
         if (mSendTronLog) sb.append("t");
 
         sb.append(mGpsMode);
@@ -502,6 +512,9 @@
                 case ServiceType.AOD:
                     return builder.setBatterySaverEnabled(mAodDisabled)
                             .build();
+                case ServiceType.QUICK_DOZE:
+                    return builder.setBatterySaverEnabled(mQuickDozeEnabled)
+                            .build();
                 default:
                     return builder.setBatterySaverEnabled(realMode)
                             .build();
@@ -562,6 +575,7 @@
             pw.println("  " + KEY_FORCE_BACKGROUND_CHECK + "=" + mForceBackgroundCheck);
             pw.println("  " + KEY_OPTIONAL_SENSORS_DISABLED + "=" + mOptionalSensorsDisabled);
             pw.println("  " + KEY_AOD_DISABLED + "=" + mAodDisabled);
+            pw.println("  " + KEY_QUICK_DOZE_ENABLED + "=" + mQuickDozeEnabled);
             pw.println("  " + KEY_SEND_TRON_LOG + "=" + mSendTronLog);
             pw.println();
 
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index b3f2a27..43a9c78 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1079,18 +1079,39 @@
         return false;
     }
 
+    private static WorkChain getFirstNonEmptyWorkChain(WorkSource workSource) {
+        if (workSource.getWorkChains() == null) {
+            return null;
+        }
+
+        for (WorkChain workChain: workSource.getWorkChains()) {
+            if (workChain.getSize() > 0) {
+                return workChain;
+            }
+        }
+
+        return null;
+    }
+
     private void applyWakeLockFlagsOnAcquireLocked(WakeLock wakeLock, int uid) {
         if ((wakeLock.mFlags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0
                 && isScreenLock(wakeLock)) {
             String opPackageName;
             int opUid;
-            if (wakeLock.mWorkSource != null && wakeLock.mWorkSource.getName(0) != null) {
-                opPackageName = wakeLock.mWorkSource.getName(0);
-                opUid = wakeLock.mWorkSource.get(0);
+            if (wakeLock.mWorkSource != null && !wakeLock.mWorkSource.isEmpty()) {
+                WorkSource workSource = wakeLock.mWorkSource;
+                WorkChain workChain = getFirstNonEmptyWorkChain(workSource);
+                if (workChain != null) {
+                    opPackageName = workChain.getAttributionTag();
+                    opUid = workChain.getAttributionUid();
+                } else {
+                    opPackageName = workSource.getName(0) != null
+                            ? workSource.getName(0) : wakeLock.mPackageName;
+                    opUid = workSource.get(0);
+                }
             } else {
                 opPackageName = wakeLock.mPackageName;
-                opUid = wakeLock.mWorkSource != null ? wakeLock.mWorkSource.get(0)
-                        : wakeLock.mOwnerUid;
+                opUid = wakeLock.mOwnerUid;
             }
             wakeUpNoUpdateLocked(SystemClock.uptimeMillis(), wakeLock.mTag, opUid,
                     opPackageName, opUid);
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
index be24c71..5569822 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverController.java
@@ -243,7 +243,7 @@
     }
 
     /**
-     * Called by {@link PowerManagerService} to update the battery saver stete.
+     * Called by {@link PowerManagerService} to update the battery saver state.
      */
     public void enableBatterySaver(boolean enable, int reason) {
         synchronized (mLock) {
@@ -290,8 +290,8 @@
      * This method is called only in the following cases:
      * - When battery saver becomes activated.
      * - When battery saver becomes deactivated.
-     * - When battery saver is on the interactive state changes.
-     * - When battery saver is on the battery saver policy changes.
+     * - When battery saver is on and the interactive state changes.
+     * - When battery saver is on and the battery saver policy changes.
      */
     void handleBatterySaverStateChanged(boolean sendBroadcast, int reason) {
         final LowPowerModeListener[] listeners;
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index d0de940..f10fe58 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -15,6 +15,8 @@
  */
 package com.android.server.stats;
 
+import static com.android.internal.util.Preconditions.checkNotNull;
+
 import android.annotation.Nullable;
 import android.app.ActivityManagerInternal;
 import android.app.AlarmManager;
@@ -41,12 +43,15 @@
 import android.os.Bundle;
 import android.os.Environment;
 import android.os.FileUtils;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.IStatsCompanionService;
 import android.os.IStatsManager;
 import android.os.IStoraged;
 import android.os.IThermalEventListener;
 import android.os.IThermalService;
+import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
 import android.os.Process;
@@ -67,6 +72,7 @@
 import android.util.Log;
 import android.util.Slog;
 import android.util.StatsLog;
+import android.util.proto.ProtoOutputStream;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.app.procstats.IProcessStats;
@@ -82,6 +88,7 @@
 import com.android.internal.os.KernelWakelockStats;
 import com.android.internal.os.LooperStats;
 import com.android.internal.os.PowerProfile;
+import com.android.internal.os.ProcessCpuTracker;
 import com.android.internal.os.StoragedUidIoStatsReader;
 import com.android.internal.util.DumpUtils;
 import com.android.server.BinderCallsStatsService;
@@ -145,6 +152,13 @@
     public static final String EXTRA_LAST_REPORT_TIME = "android.app.extra.LAST_REPORT_TIME";
     public static final int DEATH_THRESHOLD = 10;
 
+
+    static final class CompanionHandler extends Handler {
+        CompanionHandler(Looper looper) {
+            super(looper);
+        }
+    }
+
     private final Context mContext;
     private final AlarmManager mAlarmManager;
     @GuardedBy("sStatsdLock")
@@ -161,15 +175,11 @@
     private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
     private IWifiManager mWifiManager = null;
     private TelephonyManager mTelephony = null;
-    private final StatFs mStatFsData = new StatFs(Environment.getDataDirectory().getAbsolutePath());
-    private final StatFs mStatFsSystem =
-            new StatFs(Environment.getRootDirectory().getAbsolutePath());
-    private final StatFs mStatFsTemp =
-            new StatFs(Environment.getDownloadCacheDirectory().getAbsolutePath());
     @GuardedBy("sStatsdLock")
     private final HashSet<Long> mDeathTimeMillis = new HashSet<>();
     @GuardedBy("sStatsdLock")
     private final HashMap<Long, String> mDeletedFiles = new HashMap<>();
+    private final CompanionHandler mHandler;
 
     private KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
     private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
@@ -185,6 +195,8 @@
     private static IThermalService sThermalService;
     private File mBaseDir =
             new File(SystemServiceManager.ensureSystemDir(), "stats_companion");
+    @GuardedBy("this")
+    ProcessCpuTracker mProcessCpuTracker = null;
 
     public StatsCompanionService(Context context) {
         super();
@@ -248,6 +260,11 @@
         } else {
             Slog.e(TAG, "cannot find thermalservice, no throttling push notifications");
         }
+
+        HandlerThread handlerThread = new HandlerThread(TAG);
+        handlerThread.start();
+        mHandler = new CompanionHandler(handlerThread.getLooper());
+
     }
 
     @Override
@@ -495,7 +512,7 @@
             // only fire when it awakens.
             // AlarmManager will automatically cancel any previous mAnomalyAlarmListener alarm.
             mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".anomaly",
-                    mAnomalyAlarmListener, null);
+                    mAnomalyAlarmListener, mHandler);
         } finally {
             Binder.restoreCallingIdentity(callingToken);
         }
@@ -526,7 +543,7 @@
             // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
             // only fire when it awakens.
             mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, TAG + ".periodic",
-                    mPeriodicAlarmListener, null);
+                    mPeriodicAlarmListener, mHandler);
         } finally {
             Binder.restoreCallingIdentity(callingToken);
         }
@@ -558,7 +575,7 @@
             // using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
             // only fire when it awakens.
             mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, nextPullTimeMs, TAG + ".pull",
-                    mPullingAlarmListener, null);
+                    mPullingAlarmListener, mHandler);
         } finally {
             Binder.restoreCallingIdentity(callingToken);
         }
@@ -753,7 +770,7 @@
     private void pullBluetoothBytesTransfer(
             int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
-        BluetoothActivityEnergyInfo info = pullBluetoothData();
+        BluetoothActivityEnergyInfo info = fetchBluetoothData();
         if (info.getUidTraffic() != null) {
             for (UidTraffic traffic : info.getUidTraffic()) {
                 StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
@@ -865,9 +882,12 @@
             int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
         long token = Binder.clearCallingIdentity();
-        if (mWifiManager == null) {
-            mWifiManager =
-                    IWifiManager.Stub.asInterface(ServiceManager.getService(Context.WIFI_SERVICE));
+        synchronized (this) {
+            if (mWifiManager == null) {
+                mWifiManager =
+                        IWifiManager.Stub.asInterface(
+                                ServiceManager.getService(Context.WIFI_SERVICE));
+            }
         }
         if (mWifiManager != null) {
             try {
@@ -897,8 +917,10 @@
             int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
         long token = Binder.clearCallingIdentity();
-        if (mTelephony == null) {
-            mTelephony = TelephonyManager.from(mContext);
+        synchronized (this) {
+            if (mTelephony == null) {
+                mTelephony = TelephonyManager.from(mContext);
+            }
         }
         if (mTelephony != null) {
             SynchronousResultReceiver modemReceiver = new SynchronousResultReceiver("telephony");
@@ -922,7 +944,7 @@
     private void pullBluetoothActivityInfo(
             int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
-        BluetoothActivityEnergyInfo info = pullBluetoothData();
+        BluetoothActivityEnergyInfo info = fetchBluetoothData();
         StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
         e.writeLong(info.getTimeStamp());
         e.writeInt(info.getBluetoothStackState());
@@ -933,7 +955,7 @@
         pulledData.add(e);
     }
 
-    private synchronized BluetoothActivityEnergyInfo pullBluetoothData() {
+    private synchronized BluetoothActivityEnergyInfo fetchBluetoothData() {
         final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
         if (adapter != null) {
             SynchronousResultReceiver bluetoothReceiver = new SynchronousResultReceiver(
@@ -982,6 +1004,23 @@
         }
     }
 
+    private void pullNativeProcessMemoryState(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        List<ProcessMemoryState> processMemoryStates = LocalServices.getService(
+                ActivityManagerInternal.class).getMemoryStateForNativeProcesses();
+        for (ProcessMemoryState processMemoryState : processMemoryStates) {
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+            e.writeInt(processMemoryState.uid);
+            e.writeString(processMemoryState.processName);
+            e.writeLong(processMemoryState.pgfault);
+            e.writeLong(processMemoryState.pgmajfault);
+            e.writeLong(processMemoryState.rssInBytes);
+            e.writeLong(processMemoryState.rssHighWatermarkInBytes);
+            pulledData.add(e);
+        }
+    }
+
     private void pullBinderCallsStats(
             int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
@@ -1053,6 +1092,11 @@
             e.writeLong(entry.totalLatencyMicros);
             e.writeLong(entry.cpuUsageMicros);
             e.writeBoolean(entry.isInteractive);
+            e.writeLong(entry.maxCpuUsageMicros);
+            e.writeLong(entry.maxLatencyMicros);
+            e.writeLong(entry.recordedDelayMessageCount);
+            e.writeLong(entry.delayMillis);
+            e.writeLong(entry.maxDelayMillis);
             pulledData.add(e);
         }
     }
@@ -1256,18 +1300,19 @@
         Binder.restoreCallingIdentity(token);
     }
 
-    long mLastProcStatsHighWaterMark = readProcStatsHighWaterMark();
-
-    private long readProcStatsHighWaterMark() {
+    // read high watermark for section
+    private long readProcStatsHighWaterMark(int section) {
         try {
-            File[] files = mBaseDir.listFiles();
+            File[] files = mBaseDir.listFiles((d, name) -> {
+                return name.toLowerCase().startsWith(String.valueOf(section) + '_');
+            });
             if (files == null || files.length == 0) {
                 return 0;
             }
             if (files.length > 1) {
                 Log.e(TAG, "Only 1 file expected for high water mark. Found " + files.length);
             }
-            return Long.valueOf(files[0].getName());
+            return Long.valueOf(files[0].getName().split("_")[1]);
         } catch (SecurityException e) {
             Log.e(TAG, "Failed to get procstats high watermark file.", e);
         } catch (NumberFormatException e) {
@@ -1279,32 +1324,37 @@
     private IProcessStats mProcessStats =
             IProcessStats.Stub.asInterface(ServiceManager.getService(ProcessStats.SERVICE_NAME));
 
-    private void pullProcessStats(
-            int tagId, long elapsedNanos, long wallClockNanos,
+    private void pullProcessStats(int section, int tagId, long elapsedNanos, long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
-        try {
-            List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
-            long highWaterMark = mProcessStats.getCommittedStats(
-                    mLastProcStatsHighWaterMark, ProcessStats.REPORT_ALL, true, statsFiles);
-            if (statsFiles.size() != 1) {
-                return;
+        synchronized (this) {
+            try {
+                long lastHighWaterMark = readProcStatsHighWaterMark(section);
+                List<ParcelFileDescriptor> statsFiles = new ArrayList<>();
+                long highWaterMark = mProcessStats.getCommittedStats(
+                        lastHighWaterMark, section, true, statsFiles);
+                if (statsFiles.size() != 1) {
+                    return;
+                }
+                InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(
+                        statsFiles.get(0));
+                int[] len = new int[1];
+                byte[] stats = readFully(stream, len);
+                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                        wallClockNanos);
+                e.writeStorage(Arrays.copyOf(stats, len[0]));
+                pulledData.add(e);
+                new File(mBaseDir.getAbsolutePath() + "/" + section + "_"
+                        + lastHighWaterMark).delete();
+                new File(
+                        mBaseDir.getAbsolutePath() + "/" + section + "_"
+                                + highWaterMark).createNewFile();
+            } catch (IOException e) {
+                Log.e(TAG, "Getting procstats failed: ", e);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Getting procstats failed: ", e);
+            } catch (SecurityException e) {
+                Log.e(TAG, "Getting procstats failed: ", e);
             }
-            InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(statsFiles.get(0));
-            int[] len = new int[1];
-            byte[] stats = readFully(stream, len);
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
-            e.writeStorage(Arrays.copyOf(stats, len[0]));
-            pulledData.add(e);
-            new File(mBaseDir.getAbsolutePath() + "/" + mLastProcStatsHighWaterMark).delete();
-            mLastProcStatsHighWaterMark = highWaterMark;
-            new File(
-                    mBaseDir.getAbsolutePath() + "/" + mLastProcStatsHighWaterMark).createNewFile();
-        } catch (IOException e) {
-            Log.e(TAG, "Getting procstats failed: ", e);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Getting procstats failed: ", e);
-        } catch (SecurityException e) {
-            Log.e(TAG, "Getting procstats failed: ", e);
         }
     }
 
@@ -1336,12 +1386,28 @@
         }
     }
 
+    private void pullPowerProfile(
+            int tagId, long elapsedNanos, long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        PowerProfile powerProfile = new PowerProfile(mContext);
+        checkNotNull(powerProfile);
+
+        StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                wallClockNanos);
+        ProtoOutputStream proto = new ProtoOutputStream();
+        powerProfile.writeToProto(proto);
+        proto.flush();
+        e.writeStorage(proto.getBytes());
+        pulledData.add(e);
+    }
+
     private void pullDiskIo(int tagId, long elapsedNanos, final long wallClockNanos,
             List<StatsLogEventWrapper> pulledData) {
         mStoragedUidIoStatsReader.readAbsolute((uid, fgCharsRead, fgCharsWrite, fgBytesRead,
                 fgBytesWrite, bgCharsRead, bgCharsWrite, bgBytesRead, bgBytesWrite,
                 fgFsync, bgFsync) -> {
-            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos, wallClockNanos);
+            StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                    wallClockNanos);
             e.writeInt(uid);
             e.writeLong(fgCharsRead);
             e.writeLong(fgCharsWrite);
@@ -1357,6 +1423,27 @@
         });
     }
 
+    private void pullProcessCpuTime(int tagId, long elapsedNanos, final long wallClockNanos,
+            List<StatsLogEventWrapper> pulledData) {
+        synchronized (this) {
+            if (mProcessCpuTracker == null) {
+                mProcessCpuTracker = new ProcessCpuTracker(false);
+                mProcessCpuTracker.init();
+            }
+            mProcessCpuTracker.update();
+            for (int i = 0; i < mProcessCpuTracker.countStats(); i++) {
+                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
+                StatsLogEventWrapper e = new StatsLogEventWrapper(tagId, elapsedNanos,
+                        wallClockNanos);
+                e.writeInt(st.uid);
+                e.writeString(st.name);
+                e.writeLong(st.base_utime);
+                e.writeLong(st.base_stime);
+                pulledData.add(e);
+            }
+        }
+    }
+
     /**
      * Pulls various data.
      */
@@ -1438,6 +1525,10 @@
                 pullProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
+            case StatsLog.NATIVE_PROCESS_MEMORY_STATE: {
+                pullNativeProcessMemoryState(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
             case StatsLog.BINDER_CALLS: {
                 pullBinderCallsStats(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
@@ -1471,13 +1562,26 @@
                 break;
             }
             case StatsLog.PROC_STATS: {
-                pullProcessStats(tagId, elapsedNanos, wallClockNanos, ret);
+                pullProcessStats(ProcessStats.REPORT_ALL, tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
+            case StatsLog.PROC_STATS_PKG_PROC: {
+                pullProcessStats(ProcessStats.REPORT_PKG_PROC_STATS, tagId, elapsedNanos,
+                        wallClockNanos, ret);
                 break;
             }
             case StatsLog.DISK_IO: {
                 pullDiskIo(tagId, elapsedNanos, wallClockNanos, ret);
                 break;
             }
+            case StatsLog.POWER_PROFILE: {
+                pullPowerProfile(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
+            case StatsLog.PROCESS_CPU_TIME: {
+                pullProcessCpuTime(tagId, elapsedNanos, wallClockNanos, ret);
+                break;
+            }
             default:
                 Slog.w(TAG, "No such tagId data as " + tagId);
                 return null;
@@ -1539,7 +1643,8 @@
         public void onStart() {
             mStatsCompanionService = new StatsCompanionService(getContext());
             try {
-                publishBinderService(Context.STATS_COMPANION_SERVICE, mStatsCompanionService);
+                publishBinderService(Context.STATS_COMPANION_SERVICE,
+                        mStatsCompanionService);
                 if (DEBUG) Slog.d(TAG, "Published " + Context.STATS_COMPANION_SERVICE);
             } catch (Exception e) {
                 Slog.e(TAG, "Failed to publishBinderService", e);
@@ -1564,18 +1669,22 @@
     }
 
     /**
-     * Tells statsd that statscompanion is ready. If the binder call returns, link to statsd.
+     * Tells statsd that statscompanion is ready. If the binder call returns, link to
+     * statsd.
      */
     private void sayHiToStatsd() {
         synchronized (sStatsdLock) {
             if (sStatsd != null) {
                 Slog.e(TAG, "Trying to fetch statsd, but it was already fetched",
-                        new IllegalStateException("sStatsd is not null when being fetched"));
+                        new IllegalStateException(
+                                "sStatsd is not null when being fetched"));
                 return;
             }
             sStatsd = fetchStatsdService();
             if (sStatsd == null) {
-                Slog.i(TAG, "Could not yet find statsd to tell it that StatsCompanion is alive.");
+                Slog.i(TAG,
+                        "Could not yet find statsd to tell it that StatsCompanion is "
+                                + "alive.");
                 return;
             }
             if (DEBUG) Slog.d(TAG, "Saying hi to statsd");
@@ -1593,10 +1702,12 @@
                 filter.addAction(Intent.ACTION_PACKAGE_ADDED);
                 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
                 filter.addDataScheme("package");
-                mContext.registerReceiverAsUser(mAppUpdateReceiver, UserHandle.ALL, filter, null,
+                mContext.registerReceiverAsUser(mAppUpdateReceiver, UserHandle.ALL, filter,
+                        null,
                         null);
 
-                // Setup receiver for user initialize (which happens once for a new user) and
+                // Setup receiver for user initialize (which happens once for a new user)
+                // and
                 // if a user is removed.
                 filter = new IntentFilter(Intent.ACTION_USER_INITIALIZE);
                 filter.addAction(Intent.ACTION_USER_REMOVED);
@@ -1610,7 +1721,8 @@
                         mShutdownEventReceiver, UserHandle.ALL, filter, null, null);
                 final long token = Binder.clearCallingIdentity();
                 try {
-                    // Pull the latest state of UID->app name, version mapping when statsd starts.
+                    // Pull the latest state of UID->app name, version mapping when
+                    // statsd starts.
                     informAllUidsLocked(mContext);
                 } finally {
                     restoreCallingIdentity(token);
@@ -1672,7 +1784,8 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
 
         synchronized (sStatsdLock) {
-            writer.println("Number of configuration files deleted: " + mDeletedFiles.size());
+            writer.println(
+                    "Number of configuration files deleted: " + mDeletedFiles.size());
             if (mDeletedFiles.size() > 0) {
                 writer.println("  timestamp, deleted file name");
             }
@@ -1680,7 +1793,8 @@
                     SystemClock.currentThreadTimeMillis() - SystemClock.elapsedRealtime();
             for (Long elapsedMillis : mDeletedFiles.keySet()) {
                 long deletionMillis = lastBootMillis + elapsedMillis;
-                writer.println("  " + deletionMillis + ", " + mDeletedFiles.get(elapsedMillis));
+                writer.println(
+                        "  " + deletionMillis + ", " + mDeletedFiles.get(elapsedMillis));
             }
         }
     }
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index d36ab3f..5ce8145 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -28,7 +28,6 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.service.textclassifier.ITextClassificationCallback;
 import android.service.textclassifier.ITextClassifierService;
 import android.service.textclassifier.ITextLinksCallback;
@@ -41,7 +40,6 @@
 import android.view.textclassifier.TextClassificationContext;
 import android.view.textclassifier.TextClassificationManager;
 import android.view.textclassifier.TextClassificationSessionId;
-import android.view.textclassifier.TextClassifier;
 import android.view.textclassifier.TextLinks;
 import android.view.textclassifier.TextSelection;
 
@@ -275,6 +273,20 @@
         IndentingPrintWriter pw = new IndentingPrintWriter(fout, "  ");
         TextClassificationManager tcm = mContext.getSystemService(TextClassificationManager.class);
         tcm.dump(pw);
+
+        pw.printPair("context", mContext); pw.println();
+        synchronized (mLock) {
+            int size = mUserStates.size();
+            pw.print("Number user states: "); pw.println(size);
+            if (size > 0) {
+                for (int i = 0; i < size; i++) {
+                    pw.increaseIndent();
+                    UserState userState = mUserStates.valueAt(i);
+                    pw.print(i); pw.print(":"); userState.dump(pw); pw.println();
+                    pw.decreaseIndent();
+                }
+            }
+        }
     }
 
     private static final class PendingRequest implements IBinder.DeathRecipient {
@@ -431,6 +443,15 @@
             return willBind;
         }
 
+        private void dump(IndentingPrintWriter pw) {
+            pw.printPair("context", mContext);
+            pw.printPair("userId", mUserId);
+            synchronized (mLock) {
+                pw.printPair("binding", mBinding);
+                pw.printPair("numberRequests", mPendingRequests.size());
+            }
+        }
+
         private final class TextClassifierServiceConnection implements ServiceConnection {
             @Override
             public void onServiceConnected(ComponentName name, IBinder service) {
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index e449111..9edb3d0 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -71,7 +71,7 @@
 import java.util.Set;
 
 /**
- * This class contains the accessibility related logic of the window manger.
+ * This class contains the accessibility related logic of the window manager.
  */
 final class AccessibilityController {
 
@@ -1043,7 +1043,8 @@
                 // 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.
-                if (mService.mCurrentFocus == null) {
+                // TODO(b/112273690): Support multiple displays
+                if (mService.getDefaultDisplayContentLocked().mCurrentFocus == null) {
                     return;
                 }
 
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index bcf9212..443d6fe 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UserIdInt;
 import android.app.AppProtoEnums;
 import android.app.IActivityManager;
 import android.app.IApplicationThread;
@@ -28,18 +29,26 @@
 import android.content.res.CompatibilityInfo;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.service.voice.IVoiceInteractionSession;
 import android.util.SparseIntArray;
 
+import android.util.proto.ProtoOutputStream;
 import com.android.internal.app.IVoiceInteractor;
+import com.android.server.am.ActivityServiceConnectionsHolder;
 import com.android.server.am.PendingIntentRecord;
 import com.android.server.am.SafeActivityOptions;
 import com.android.server.am.TaskRecord;
+import com.android.server.am.UserState;
 import com.android.server.am.WindowProcessController;
 
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
 
 /**
  * Activity Task manager local system service interface.
@@ -305,13 +314,13 @@
     public abstract boolean showStrictModeViolationDialog();
     public abstract void showSystemReadyErrorDialogsIfNeeded();
 
-    public abstract long inputDispatchingTimedOut(int pid, boolean aboveSystem, String reason);
     public abstract void onProcessMapped(int pid, WindowProcessController proc);
     public abstract void onProcessUnMapped(int pid);
 
     public abstract void onPackageDataCleared(String name);
     public abstract void onPackageUninstalled(String name);
     public abstract void onPackageAdded(String name, boolean replacing);
+    public abstract void onPackageReplaced(ApplicationInfo aInfo);
 
     public abstract CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai);
 
@@ -332,4 +341,110 @@
             int callingUid, int userId, IBinder token, String resultWho,
             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
             Bundle bOptions);
+
+    /** @return the service connection holder for a given activity token. */
+    public abstract ActivityServiceConnectionsHolder getServiceConnectionsHolder(IBinder token);
+
+    /** @return The intent used to launch the home activity. */
+    public abstract Intent getHomeIntent();
+    public abstract boolean startHomeActivity(int userId, String reason);
+    /** @return true if the given process is the factory test process. */
+    public abstract boolean isFactoryTestProcess(WindowProcessController wpc);
+    public abstract void updateTopComponentForFactoryTest();
+    public abstract void handleAppDied(WindowProcessController wpc, boolean restarting,
+            Runnable finishInstrumentationCallback);
+    public abstract void closeSystemDialogs(String reason);
+
+    /** Removes all components (e.g. activities, recents, ...) belonging to a disabled package. */
+    public abstract void cleanupDisabledPackageComponents(
+            String packageName, Set<String> disabledClasses, int userId, boolean booted);
+
+    /** Called whenever AM force stops a package. */
+    public abstract boolean onForceStopPackage(String packageName, boolean doit,
+            boolean evenPersistent, int userId);
+    /**
+     * Resumes all top activities in the system if they aren't resumed already.
+     * @param scheduleIdle If the idle message should be schedule after the top activities are
+     *                     resumed.
+     */
+    public abstract void resumeTopActivities(boolean scheduleIdle);
+
+    /** Called by AM just before it binds to an application process. */
+    public abstract void preBindApplication(WindowProcessController wpc);
+
+    /** Called by AM when an application process attaches. */
+    public abstract boolean attachApplication(WindowProcessController wpc) throws RemoteException;
+
+    /** @see IActivityManager#notifyLockedProfile(int) */
+    public abstract void notifyLockedProfile(@UserIdInt int userId, int currentUserId);
+
+    /** @see IActivityManager#startConfirmDeviceCredentialIntent(Intent, Bundle) */
+    public abstract void startConfirmDeviceCredentialIntent(Intent intent, Bundle options);
+
+    /** Writes current activity states to the proto stream. */
+    public abstract void writeActivitiesToProto(ProtoOutputStream proto);
+
+    /**
+     * Saves the current activity manager state and includes the saved state in the next dump of
+     * activity manager.
+     */
+    public abstract void saveANRState(String reason);
+
+    /** Clears the previously saved activity manager ANR state. */
+    public abstract void clearSavedANRState();
+
+    /** Dump the current state based on the command. */
+    public abstract void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args,
+            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage);
+
+    /** Dump the current state for inclusion in process dump. */
+    public abstract boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
+            String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
+            int wakefulness);
+
+    /** Writes the current window process states to the proto stream. */
+    public abstract void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage);
+
+    /** Dump the current activities state. */
+    public abstract boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
+            String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
+            boolean dumpFocusedStackOnly);
+
+    /** @return true if it the activity management system is okay with GC running now. */
+    public abstract boolean canGcNow();
+
+    /** @return the process for the top-most resumed activity in the system. */
+    public abstract WindowProcessController getTopApp();
+
+    /** Generate oom-score-adjustment rank for all tasks in the system based on z-order. */
+    public abstract void rankTaskLayersIfNeeded();
+
+    /** Destroy all activities. */
+    public abstract void scheduleDestroyAllActivities(String reason);
+
+    /** Remove user association with activities. */
+    public abstract void removeUser(int userId);
+
+    /** Switch current focused user for activities. */
+    public abstract boolean switchUser(int userId, UserState userState);
+
+    /** Called whenever an app crashes. */
+    public abstract void onHandleAppCrash(WindowProcessController wpc);
+
+    /**
+     * Finish the topmost activities in all stacks that belong to the crashed app.
+     * @param crashedApp The app that crashed.
+     * @param reason Reason to perform this action.
+     * @return The task id that was finished in this stack, or INVALID_TASK_ID if none was finished.
+     */
+    public abstract int finishTopCrashedActivities(
+            WindowProcessController crashedApp, String reason);
+
+    public abstract void onUidActive(int uid, int procState);
+    public abstract void onUidInactive(int uid);
+    public abstract void onActiveUidsCleared();
+    public abstract void onUidProcStateChanged(int uid, int procState);
+
+    public abstract void onUidAddedToPendingTempWhitelist(int uid, String tag);
+    public abstract void onUidRemovedFromPendingTempWhitelist(int uid);
 }
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index d73606f..a9d0978 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -77,6 +77,7 @@
 import static com.android.server.wm.AppTransitionProto.LAST_USED_APP_TRANSITION;
 
 import android.annotation.DrawableRes;
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.content.ComponentName;
@@ -93,6 +94,7 @@
 import android.graphics.drawable.Drawable;
 import android.os.Binder;
 import android.os.Debug;
+import android.os.Handler;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
@@ -120,8 +122,8 @@
 
 import com.android.internal.R;
 import com.android.internal.util.DumpUtils.Dump;
+import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.AttributeCache;
-import com.android.server.wm.WindowManagerService.H;
 import com.android.server.wm.animation.ClipRectLRAnimation;
 import com.android.server.wm.animation.ClipRectTBAnimation;
 import com.android.server.wm.animation.CurvedTranslateAnimation;
@@ -252,9 +254,13 @@
 
     private RemoteAnimationController mRemoteAnimationController;
 
+    final Handler mHandler;
+    final Runnable mHandleAppTransitionTimeoutRunnable = () -> handleAppTransitionTimeout();
+
     AppTransition(Context context, WindowManagerService service) {
         mContext = context;
         mService = service;
+        mHandler = new Handler(service.mH.getLooper());
         mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
                 com.android.internal.R.interpolator.linear_out_slow_in);
         mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -1349,7 +1355,8 @@
 
                 @Override
                 public void onAnimationEnd(Animation animation) {
-                    mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK, callback).sendToTarget();
+                    mHandler.sendMessage(PooledLambda.obtainMessage(
+                            AppTransition::doAnimationCallback, callback));
                 }
 
                 @Override
@@ -1756,7 +1763,7 @@
 
     void postAnimationCallback() {
         if (mNextAppTransitionCallback != null) {
-            mService.mH.sendMessage(mService.mH.obtainMessage(H.DO_ANIMATION_CALLBACK,
+            mHandler.sendMessage(PooledLambda.obtainMessage(AppTransition::doAnimationCallback,
                     mNextAppTransitionCallback));
             mNextAppTransitionCallback = null;
         }
@@ -1869,7 +1876,7 @@
             clear();
             mNextAppTransitionType = NEXT_TRANSIT_TYPE_REMOTE;
             mRemoteAnimationController = new RemoteAnimationController(mService,
-                    remoteAnimationAdapter, mService.mH);
+                    remoteAnimationAdapter, mHandler);
         }
     }
 
@@ -2162,8 +2169,8 @@
         }
         boolean prepared = prepare();
         if (isTransitionSet()) {
-            mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
-            mService.mH.sendEmptyMessageDelayed(H.APP_TRANSITION_TIMEOUT, APP_TRANSITION_TIMEOUT_MS);
+            removeAppTransitionTimeoutCallbacks();
+            mHandler.postDelayed(mHandleAppTransitionTimeoutRunnable, APP_TRANSITION_TIMEOUT_MS);
         }
         return prepared;
     }
@@ -2208,4 +2215,32 @@
         return mGridLayoutRecentsEnabled
                 || orientation == Configuration.ORIENTATION_PORTRAIT;
     }
+
+    private void handleAppTransitionTimeout() {
+        synchronized (mService.mWindowMap) {
+            if (isTransitionSet() || !mService.mOpeningApps.isEmpty()
+                    || !mService.mClosingApps.isEmpty()) {
+                if (DEBUG_APP_TRANSITIONS) {
+                    Slog.v(TAG_WM, "*** APP TRANSITION TIMEOUT."
+                            + " isTransitionSet()="
+                            + mService.mAppTransition.isTransitionSet()
+                            + " mOpeningApps.size()=" + mService.mOpeningApps.size()
+                            + " mClosingApps.size()=" + mService.mClosingApps.size());
+                }
+                setTimeout();
+                mService.mWindowPlacerLocked.performSurfacePlacement();
+            }
+        }
+    }
+
+    private static void doAnimationCallback(@NonNull IRemoteCallback callback) {
+        try {
+            ((IRemoteCallback) callback).sendResult(null);
+        } catch (RemoteException e) {
+        }
+    }
+
+    void removeAppTransitionTimeoutCallbacks() {
+        mHandler.removeCallbacks(mHandleAppTransitionTimeoutRunnable);
+    }
 }
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 36280dd..330c54c 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -407,8 +407,7 @@
                 if (mService.mAppTransition.getAppTransition()
                         == WindowManager.TRANSIT_TASK_OPEN_BEHIND) {
                     // We're launchingBehind, add the launching activity to mOpeningApps.
-                    final WindowState win =
-                            mService.getDefaultDisplayContentLocked().findFocusedWindow();
+                    final WindowState win = mContainer.getDisplayContent().findFocusedWindow();
                     if (win != null) {
                         final AppWindowToken focusedToken = win.mAppToken;
                         if (focusedToken != null) {
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index fc76102..e38e229 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -102,6 +102,7 @@
 import android.view.animation.Animation;
 
 import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.input.InputApplicationHandle;
 import com.android.server.policy.WindowManagerPolicy.StartingSurface;
@@ -679,11 +680,12 @@
         removed = true;
         stopFreezingScreen(true, true);
 
-        if (mService.mFocusedApp == this) {
-            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this);
-            mService.mFocusedApp = null;
+        final DisplayContent dc = getDisplayContent();
+        if (dc.mFocusedApp == this) {
+            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this
+                   + " displayId=" + dc.getDisplayId());
+            dc.setFocusedApp(null);
             mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
-            getDisplayContent().getInputMonitor().setFocusedAppLw(null);
         }
 
         if (!delayed) {
@@ -1064,6 +1066,18 @@
         }
     }
 
+    @Override
+    void onDisplayChanged(DisplayContent dc) {
+        DisplayContent prevDc = mDisplayContent;
+        super.onDisplayChanged(dc);
+        if (prevDc != null && prevDc.mFocusedApp == this) {
+            prevDc.setFocusedApp(null);
+            if (dc.getTopStack().getTopChild().getTopChild() == this) {
+                dc.setFocusedApp(this);
+            }
+        }
+    }
+
     /**
      * Freezes the task bounds. The size of this task reported the app will be fixed to the bounds
      * freezed by {@link Task#prepareFreezingBounds} until {@link #unfreezeBounds} gets called, even
@@ -1728,6 +1742,30 @@
         return boundsLayer;
     }
 
+    /** Get position and crop region of animation. */
+    @VisibleForTesting
+    void getAnimationBounds(Point outPosition, Rect outBounds) {
+        outPosition.set(0, 0);
+        outBounds.setEmpty();
+
+        final TaskStack stack = getStack();
+        final Task task = getTask();
+        if (task != null && task.inFreeformWindowingMode()) {
+            task.getRelativePosition(outPosition);
+        } else if (stack != null) {
+            stack.getRelativePosition(outPosition);
+        }
+
+        // Always use stack bounds in order to have the ability to animate outside the task region.
+        // It also needs to be consistent when {@link #mNeedsAnimationBoundsLayer} is set that crops
+        // according to the bounds.
+        if (stack != null) {
+            stack.getBounds(outBounds);
+        }
+        // We have the relative position so the local position can be removed from bounds.
+        outBounds.offsetTo(0, 0);
+    }
+
     boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
             boolean isVoiceInteraction) {
 
@@ -1746,14 +1784,7 @@
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
         if (okToAnimate()) {
             final AnimationAdapter adapter;
-            final TaskStack stack = getStack();
-            mTmpPoint.set(0, 0);
-            mTmpRect.setEmpty();
-            if (stack != null) {
-                stack.getRelativePosition(mTmpPoint);
-                stack.getBounds(mTmpRect);
-                mTmpRect.offsetTo(0, 0);
-            }
+            getAnimationBounds(mTmpPoint, mTmpRect);
 
             // Delaying animation start isn't compatible with remote animations at all.
             if (mService.mAppTransition.getRemoteAnimationController() != null
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a762fe9..ca23360 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -70,6 +70,7 @@
 import static com.android.server.wm.DisplayContentProto.DISPLAY_INFO;
 import static com.android.server.wm.DisplayContentProto.DOCKED_STACK_DIVIDER_CONTROLLER;
 import static com.android.server.wm.DisplayContentProto.DPI;
+import static com.android.server.wm.DisplayContentProto.FOCUSED_APP;
 import static com.android.server.wm.DisplayContentProto.ID;
 import static com.android.server.wm.DisplayContentProto.IME_WINDOWS;
 import static com.android.server.wm.DisplayContentProto.PINNED_STACK_CONTROLLER;
@@ -91,19 +92,23 @@
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 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.WindowManagerService.CUSTOM_SCREEN_ROTATION;
+import static com.android.server.wm.WindowManagerService.H.REPORT_FOCUS_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;
 import static com.android.server.wm.WindowManagerService.MAX_ANIMATION_DURATION;
 import static com.android.server.wm.WindowManagerService.SEAMLESS_ROTATION_TIMEOUT_DURATION;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_REMOVING_FOCUS;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_ASSIGN_LAYERS;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_ACTIVE;
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
@@ -113,8 +118,6 @@
 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.WindowSurfacePlacer.SET_WALLPAPER_MAY_CHANGE;
-import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates;
 
 import android.annotation.CallSuper;
 import android.annotation.NonNull;
@@ -142,16 +145,19 @@
 import android.view.DisplayCutout;
 import android.view.DisplayInfo;
 import android.view.Gravity;
+import android.view.InputChannel;
 import android.view.InputDevice;
 import android.view.MagnificationSpec;
 import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 import android.view.SurfaceSession;
+import android.view.WindowManagerPolicyConstants.PointerEventListener;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.ToBooleanFunction;
 import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.wm.utils.DisplayRotationUtil;
 import com.android.server.wm.utils.RotationCache;
 import com.android.server.wm.utils.WmDisplayCutout;
 
@@ -334,6 +340,7 @@
     private final Matrix mTmpMatrix = new Matrix();
     private final Region mTmpRegion = new Region();
 
+
     /** Used for handing back size of display */
     private final Rect mTmpBounds = new Rect();
 
@@ -371,6 +378,36 @@
     private final SurfaceSession mSession = new SurfaceSession();
 
     /**
+     * Window that is currently interacting with the user. This window is responsible for receiving
+     * key events and pointer events from the user.
+     */
+    WindowState mCurrentFocus = null;
+
+    /**
+     * The last focused window that we've notified the client that the focus is changed.
+     */
+    WindowState mLastFocus = null;
+
+    /**
+     * Windows that have lost input focus and are waiting for the new focus window to be displayed
+     * before they are told about this.
+     */
+    ArrayList<WindowState> mLosingFocus = new ArrayList<>();
+
+    /**
+     * The foreground app of this display. Windows below this app cannot be the focused window. If
+     * the user taps on the area outside of the task of the focused app, we will notify AM about the
+     * new task the user wants to interact with.
+     */
+    AppWindowToken mFocusedApp = null;
+
+    /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
+    final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
+
+    /** Windows removed since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
+    final ArrayList<WindowState> mWinRemovedSinceNullFocus = new ArrayList<>();
+
+    /**
      * We organize all top-level Surfaces in to the following layers.
      * mOverlayLayer contains a few Surfaces which are always on top of others
      * and omitted from Screen-Magnification, for example the strict mode flash or
@@ -412,11 +449,15 @@
     /** Caches the value whether told display manager that we have content. */
     private boolean mLastHasContent;
 
+    private DisplayRotationUtil mRotationUtil = new DisplayRotationUtil();
+
     /**
      * The input method window for this display.
      */
     WindowState mInputMethodWindow;
 
+    private final PointerEventDispatcher mPointerEventDispatcher;
+
     private final Consumer<WindowState> mUpdateWindowsForAnimator = w -> {
         WindowStateAnimator winAnimator = w.mWinAnimator;
         final AppWindowToken atoken = w.mAppToken;
@@ -466,7 +507,7 @@
     };
 
     private final ToBooleanFunction<WindowState> mFindFocusedWindow = w -> {
-        final AppWindowToken focusedApp = mService.mFocusedApp;
+        final AppWindowToken focusedApp = mFocusedApp;
         if (DEBUG_FOCUS) Slog.v(TAG_WM, "Looking for focus: " + w
                 + ", flags=" + w.mAttrs.flags + ", canReceive=" + w.canReceiveKeys());
 
@@ -625,8 +666,6 @@
         final boolean obscuredChanged = w.mObscured !=
                 mTmpApplySurfaceChangesTransactionState.obscured;
         final RootWindowContainer root = mService.mRoot;
-        // Only used if default window
-        final boolean someoneLosingFocus = !mService.mLosingFocus.isEmpty();
 
         // Update effect.
         w.mObscured = mTmpApplySurfaceChangesTransactionState.obscured;
@@ -717,9 +756,8 @@
             }
         }
 
-        if (isDefaultDisplay && someoneLosingFocus && w == mService.mCurrentFocus
-                && w.isDisplayedLw()) {
-            mTmpApplySurfaceChangesTransactionState.focusDisplayed = true;
+        if (!mLosingFocus.isEmpty() && w.isFocused() && w.isDisplayedLw()) {
+            mService.mH.obtainMessage(REPORT_LOSING_FOCUS, this).sendToTarget();
         }
 
         w.updateResizingWindowIfNeeded();
@@ -799,6 +837,15 @@
         mDisplayReady = true;
 
         mInputMonitor = new InputMonitor(service, mDisplayId);
+
+        if (mService.mInputManager != null) {
+            final InputChannel inputChannel = mService.mInputManager.monitorInput("Display "
+                    + mDisplayId, mDisplayId);
+            mPointerEventDispatcher = inputChannel != null
+                    ? new PointerEventDispatcher(inputChannel) : null;
+        } else {
+            mPointerEventDispatcher = null;
+        }
     }
 
     boolean isReady() {
@@ -1252,6 +1299,19 @@
 
         mDisplayFrames.onDisplayInfoUpdated(mDisplayInfo,
                 calculateDisplayCutoutForRotation(mDisplayInfo.rotation));
+
+        // Tap Listeners are supported for:
+        // 1. All physical displays (multi-display).
+        // 2. VirtualDisplays on VR, AA (and everything else).
+        if (mPointerEventDispatcher != null && mTapDetector == null) {
+            if (DEBUG_DISPLAY) {
+                Slog.d(TAG,
+                        "Registering PointerEventListener for DisplayId: " + mDisplayId);
+            }
+            mTapDetector = new TaskTapPointerEventListener(mService, this);
+            registerPointerEventListener(mTapDetector);
+            registerPointerEventListener(mService.mMousePositionTracker);
+        }
     }
 
     /**
@@ -1343,21 +1403,12 @@
                     cutout, mInitialDisplayWidth, mInitialDisplayHeight);
         }
         final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
-        final List<Rect> bounds = WmDisplayCutout.computeSafeInsets(
+        final Rect[] newBounds = mRotationUtil.getRotatedBounds(
+                WmDisplayCutout.computeSafeInsets(
                         cutout, mInitialDisplayWidth, mInitialDisplayHeight)
-                .getDisplayCutout().getBoundingRects();
-        transformPhysicalToLogicalCoordinates(rotation, mInitialDisplayWidth, mInitialDisplayHeight,
-                mTmpMatrix);
-        final Region region = Region.obtain();
-        for (int i = 0; i < bounds.size(); i++) {
-            final Rect rect = bounds.get(i);
-            final RectF rectF = new RectF(bounds.get(i));
-            mTmpMatrix.mapRect(rectF);
-            rectF.round(rect);
-            region.op(rect, Op.UNION);
-        }
-
-        return WmDisplayCutout.computeSafeInsets(DisplayCutout.fromBounds(region),
+                        .getDisplayCutout().getBoundingRectsAll(),
+                rotation, mInitialDisplayWidth, mInitialDisplayHeight);
+        return WmDisplayCutout.computeSafeInsets(DisplayCutout.fromBounds(newBounds),
                 rotated ? mInitialDisplayHeight : mInitialDisplayWidth,
                 rotated ? mInitialDisplayWidth : mInitialDisplayHeight);
     }
@@ -2038,9 +2089,25 @@
         layoutAndAssignWindowLayersIfNeeded();
     }
 
-    int taskIdFromPoint(int x, int y) {
+    /**
+     * Used to obtain task ID when user taps on coordinate (x, y) in this display, and outside
+     * current task in focus.
+     *
+     * This returns the task ID of the foremost task at (x, y) if the task is not home. Otherwise it
+     * returns -1.
+     *
+     * @param x horizontal coordinate of the tap position
+     * @param y vertical coordinate of the tap position
+     * @return the task ID if a non-home task is found; -1 if not
+     */
+    int taskForTapOutside(int x, int y) {
         for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
             final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
+            if (stack.isActivityTypeHome() && !stack.inMultiWindowMode()) {
+                // We skip not only home stack, but also everything behind home because user can't
+                // see them when home stack is isn't in multi-window mode.
+                break;
+            }
             final int taskId = stack.taskIdFromPoint(x, y);
             if (taskId != -1) {
                 return taskId;
@@ -2070,22 +2137,22 @@
         return null;
     }
 
-    void setTouchExcludeRegion(Task focusedTask) {
-        // The provided task is the task on this display with focus, so if WindowManagerService's
-        // focused app is not on this display, focusedTask will be null.
+    void updateTouchExcludeRegion() {
+        final Task focusedTask = (mFocusedApp != null ? mFocusedApp.getTask() : null);
         if (focusedTask == null) {
             mTouchExcludeRegion.setEmpty();
         } else {
             mTouchExcludeRegion.set(mBaseDisplayRect);
             final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
             mTmpRect2.setEmpty();
-            for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
+            for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0;
+                    --stackNdx) {
                 final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
                 stack.setTouchExcludeRegion(focusedTask, delta, mTouchExcludeRegion,
                         mDisplayFrames.mContent, mTmpRect2);
             }
             // If we removed the focused task above, add it back and only leave its
-            // outside touch area in the exclusion. TapDectector is not interested in
+            // outside touch area in the exclusion. TapDetector is not interested in
             // any touch inside the focused task itself.
             if (!mTmpRect2.isEmpty()) {
                 mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION);
@@ -2096,12 +2163,7 @@
             // events to be intercepted and used to change focus. This would likely cause a
             // disappearance of the input method.
             mInputMethodWindow.getTouchableRegion(mTmpRegion);
-            if (mInputMethodWindow.getDisplayId() == mDisplayId) {
-                mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
-            } else {
-                // IME is on a different display, so we need to update its tap detector.
-                setTouchExcludeRegion(null /* focusedTask */);
-            }
+            mTouchExcludeRegion.op(mTmpRegion, Op.UNION);
         }
         for (int i = mTapExcludedWindows.size() - 1; i >= 0; i--) {
             final WindowState win = mTapExcludedWindows.get(i);
@@ -2150,13 +2212,10 @@
         try {
             super.removeImmediately();
             if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Removing display=" + this);
-            if (mService.canDispatchPointerEvents()) {
-                if (mTapDetector != null) {
-                    mService.unregisterPointerEventListener(mTapDetector);
-                }
-                if (mDisplayId == DEFAULT_DISPLAY && mService.mMousePositionTracker != null) {
-                    mService.unregisterPointerEventListener(mService.mMousePositionTracker);
-                }
+            if (mPointerEventDispatcher != null && mTapDetector != null) {
+                unregisterPointerEventListener(mTapDetector);
+                unregisterPointerEventListener(mService.mMousePositionTracker);
+                mTapDetector = null;
             }
             mService.mAnimator.removeDisplayLocked(mDisplayId);
             mWindowingLayer.release();
@@ -2372,6 +2431,9 @@
         }
         mDisplayFrames.writeToProto(proto, DISPLAY_FRAMES);
         proto.write(SURFACE_SIZE, mSurfaceSize);
+        if (mFocusedApp != null) {
+            mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
+        }
         proto.end(token);
     }
 
@@ -2412,6 +2474,27 @@
         pw.print(prefix);
         pw.print("mDeferredRotationPauseCount="); pw.println(mDeferredRotationPauseCount);
 
+        pw.print("  mCurrentFocus="); pw.println(mCurrentFocus);
+        if (mLastFocus != mCurrentFocus) {
+            pw.print("  mLastFocus="); pw.println(mLastFocus);
+        }
+        if (mLosingFocus.size() > 0) {
+            pw.println();
+            pw.println("  Windows losing focus:");
+            for (int i = mLosingFocus.size() - 1; i >= 0; i--) {
+                final WindowState w = mLosingFocus.get(i);
+                pw.print("  Losing #"); pw.print(i); pw.print(' ');
+                pw.print(w);
+                if (dumpAll) {
+                    pw.println(":");
+                    w.dump(pw, "    ", true);
+                } else {
+                    pw.println();
+                }
+            }
+        }
+        pw.print("  mFocusedApp="); pw.println(mFocusedApp);
+
         pw.println();
         pw.println(prefix + "Application tokens in top down Z order:");
         for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
@@ -2543,6 +2626,132 @@
         return mTmpWindow;
     }
 
+
+    /**
+     * Update the focused window and make some adjustments if the focus has changed.
+     *
+     * @param mode Indicates the situation we are in. Possible modes are:
+     *             {@link WindowManagerService#UPDATE_FOCUS_NORMAL},
+     *             {@link WindowManagerService#UPDATE_FOCUS_PLACING_SURFACES},
+     *             {@link WindowManagerService#UPDATE_FOCUS_WILL_PLACE_SURFACES},
+     *             {@link WindowManagerService#UPDATE_FOCUS_REMOVING_FOCUS}
+     * @param updateInputWindows Whether to sync the window information to the input module.
+     * @return {@code true} if the focused window has changed.
+     */
+    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows, boolean focusFound) {
+        final WindowState newFocus = findFocusedWindow();
+        if (mCurrentFocus == newFocus) {
+            return false;
+        }
+        mService.mH.obtainMessage(REPORT_FOCUS_CHANGE, this).sendToTarget();
+        boolean imWindowChanged = false;
+        // TODO (b/111080190): Multi-Session IME
+        if (!focusFound) {
+            final WindowState imWindow = mInputMethodWindow;
+            if (imWindow != null) {
+                final WindowState prevTarget = mService.mInputMethodTarget;
+
+                final WindowState newTarget = computeImeTarget(true /* updateImeTarget*/);
+                imWindowChanged = prevTarget != newTarget;
+
+                if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
+                        && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) {
+                    assignWindowLayers(false /* setLayoutNeeded */);
+                }
+            }
+        }
+
+        if (imWindowChanged) {
+            mService.mWindowsChanged = true;
+            setLayoutNeeded();
+        }
+
+        if (DEBUG_FOCUS_LIGHT || mService.localLOGV) Slog.v(TAG_WM, "Changing focus from "
+                + mCurrentFocus + " to " + newFocus + " displayId=" + getDisplayId()
+                + " Callers=" + Debug.getCallers(4));
+        final WindowState oldFocus = mCurrentFocus;
+        mCurrentFocus = newFocus;
+        mLosingFocus.remove(newFocus);
+
+        if (newFocus != null) {
+            mWinAddedSinceNullFocus.clear();
+            mWinRemovedSinceNullFocus.clear();
+
+            if (newFocus.canReceiveKeys()) {
+                // Displaying a window implicitly causes dispatching to be unpaused.
+                // This is to protect against bugs if someone pauses dispatching but
+                // forgets to resume.
+                newFocus.mToken.paused = false;
+            }
+        }
+
+        // System UI is only shown on the default display.
+        int focusChanged = isDefaultDisplay
+                ? mService.mPolicy.focusChangedLw(oldFocus, newFocus) : 0;
+
+        if (imWindowChanged && oldFocus != mInputMethodWindow) {
+            // Focus of the input method window changed. Perform layout if needed.
+            if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
+                performLayout(true /*initial*/,  updateInputWindows);
+                focusChanged &= ~FINISH_LAYOUT_REDO_LAYOUT;
+            } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
+                // Client will do the layout, but we need to assign layers
+                // for handleNewWindowLocked() below.
+                assignWindowLayers(false /* setLayoutNeeded */);
+            }
+        }
+
+        if ((focusChanged & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
+            // The change in focus caused us to need to do a layout.  Okay.
+            setLayoutNeeded();
+            if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
+                performLayout(true /*initial*/, updateInputWindows);
+            } else if (mode == UPDATE_FOCUS_REMOVING_FOCUS) {
+                mService.mRoot.performSurfacePlacement(false);
+            }
+        }
+
+        if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
+            // If we defer assigning layers, then the caller is responsible for doing this part.
+            getInputMonitor().setInputFocusLw(newFocus, updateInputWindows);
+        }
+
+        adjustForImeIfNeeded();
+
+        // We may need to schedule some toast windows to be removed. The toasts for an app that
+        // does not have input focus are removed within a timeout to prevent apps to redress
+        // other apps' UI.
+        scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
+
+        if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
+            pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
+        }
+        return true;
+    }
+
+    /**
+     * Set the new focused app to this display.
+     *
+     * @param newFocus the new focused AppWindowToken.
+     * @return true if the focused app is changed.
+     */
+    boolean setFocusedApp(AppWindowToken newFocus) {
+        if (newFocus != null) {
+            final DisplayContent appDisplay = newFocus.getDisplayContent();
+            if (appDisplay != this) {
+                throw new IllegalStateException(newFocus + " is not on " + getName()
+                        + " but " + ((appDisplay != null) ? appDisplay.getName() : "none"));
+            }
+        }
+        if (mFocusedApp == newFocus) {
+            return false;
+        }
+        mFocusedApp = newFocus;
+        getInputMonitor().setFocusedAppLw(newFocus);
+        updateTouchExcludeRegion();
+        return true;
+    }
+
     /** Updates the layer assignment of windows on this display. */
     void assignWindowLayers(boolean setLayoutNeeded) {
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "assignWindowLayers");
@@ -2906,8 +3115,8 @@
 
         if (DEBUG_INPUT_METHOD) {
             Slog.i(TAG_WM, "Desired input method target: " + imFocus);
-            Slog.i(TAG_WM, "Current focus: " + mService.mCurrentFocus);
-            Slog.i(TAG_WM, "Last focus: " + mService.mLastFocus);
+            Slog.i(TAG_WM, "Current focus: " + mCurrentFocus + " displayId=" + mDisplayId);
+            Slog.i(TAG_WM, "Last focus: " + mLastFocus + " displayId=" + mDisplayId);
         }
 
         if (DEBUG_INPUT_METHOD) {
@@ -2975,7 +3184,7 @@
     }
 
     // TODO: Super crazy long method that should be broken down...
-    boolean applySurfaceChangesTransaction(boolean recoveringMemory) {
+    void applySurfaceChangesTransaction(boolean recoveringMemory) {
 
         final int dw = mDisplayInfo.logicalWidth;
         final int dh = mDisplayInfo.logicalHeight;
@@ -3059,8 +3268,6 @@
             // can now be shown.
             atoken.updateAllDrawn();
         }
-
-        return mTmpApplySurfaceChangesTransactionState.focusDisplayed;
     }
 
     private void updateBounds() {
@@ -3314,7 +3521,6 @@
         boolean displayHasContent;
         boolean obscured;
         boolean syswin;
-        boolean focusDisplayed;
         float preferredRefreshRate;
         int preferredModeId;
 
@@ -3322,7 +3528,6 @@
             displayHasContent = false;
             obscured = false;
             syswin = false;
-            focusDisplayed = false;
             preferredRefreshRate = 0;
             preferredModeId = 0;
         }
@@ -4227,4 +4432,16 @@
     boolean getLastHasContent() {
         return mLastHasContent;
     }
+
+    void registerPointerEventListener(@NonNull PointerEventListener listener) {
+        if (mPointerEventDispatcher != null) {
+            mPointerEventDispatcher.registerInputEventListener(listener);
+        }
+    }
+
+    void unregisterPointerEventListener(@NonNull PointerEventListener listener) {
+        if (mPointerEventDispatcher != null) {
+            mPointerEventDispatcher.unregisterInputEventListener(listener);
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index bd82553..847cff9 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -55,6 +55,7 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayRotation" : TAG_WM;
 
     private final WindowManagerService mService;
+    private final DisplayContent mDisplayContent;
     private final DisplayPolicy mDisplayPolicy;
     private final Context mContext;
     private final Object mLock;
@@ -106,6 +107,7 @@
     DisplayRotation(WindowManagerService service, DisplayContent displayContent,
             DisplayPolicy displayPolicy, Context context, Object lock) {
         mService = service;
+        mDisplayContent = displayContent;
         mDisplayPolicy = displayPolicy;
         mContext = context;
         mLock = lock;
@@ -225,6 +227,70 @@
         }
     }
 
+    void restoreUserRotation(int userRotationMode, int userRotation) {
+        if (userRotationMode != WindowManagerPolicy.USER_ROTATION_FREE
+                && userRotationMode != WindowManagerPolicy.USER_ROTATION_LOCKED) {
+            Slog.w(TAG, "Trying to restore an invalid user rotation mode " + userRotationMode
+                    + " for " + mDisplayContent);
+            userRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+        }
+        if (userRotation < Surface.ROTATION_0 || userRotation > Surface.ROTATION_270) {
+            Slog.w(TAG, "Trying to restore an invalid user rotation " + userRotation
+                    + " for " + mDisplayContent);
+            userRotation = Surface.ROTATION_0;
+        }
+        mUserRotationMode = userRotationMode;
+        mUserRotation = userRotation;
+    }
+
+    private void setUserRotation(int userRotationMode, int userRotation) {
+        if (isDefaultDisplay) {
+            // We'll be notified via settings listener, so we don't need to update internal values.
+            final ContentResolver res = mContext.getContentResolver();
+            final int accelerometerRotation =
+                    userRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED ? 0 : 1;
+            Settings.System.putIntForUser(res, Settings.System.ACCELEROMETER_ROTATION,
+                    accelerometerRotation, UserHandle.USER_CURRENT);
+            Settings.System.putIntForUser(res, Settings.System.USER_ROTATION, userRotation,
+                    UserHandle.USER_CURRENT);
+            return;
+        }
+
+        boolean changed = false;
+        if (mUserRotationMode != userRotationMode) {
+            mUserRotationMode = userRotationMode;
+            changed = true;
+        }
+        if (mUserRotation != userRotation) {
+            mUserRotation = userRotation;
+            changed = true;
+        }
+        mService.mDisplaySettings.setUserRotation(mDisplayContent, userRotationMode, userRotation);
+        if (changed) {
+            mService.updateRotation(true /* alwaysSendConfiguration */,
+                    false /* forceRelayout */);
+            mService.mDisplaySettings.writeSettingsLocked();
+        }
+    }
+
+    void freezeRotation(int rotation) {
+        rotation = (rotation == -1) ? mDisplayContent.getRotation() : rotation;
+        setUserRotation(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation);
+    }
+
+    void thawRotation() {
+        setUserRotation(WindowManagerPolicy.USER_ROTATION_FREE, mUserRotation);
+    }
+
+    boolean isRotationFrozen() {
+        if (!isDefaultDisplay) {
+            return mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED;
+        }
+
+        return Settings.System.getIntForUser(mContext.getContentResolver(),
+                Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) == 0;
+    }
+
     /** @return true if com.android.internal.R.bool#config_forceDefaultOrientation is true. */
     boolean isDefaultOrientationForced() {
         return mForceDefaultOrientation;
@@ -381,9 +447,6 @@
      * @param orientation An orientation constant, such as
      * {@link android.content.pm.ActivityInfo#SCREEN_ORIENTATION_LANDSCAPE}.
      * @param lastRotation The most recently used rotation.
-     * @param defaultDisplay Flag indicating whether the rotation is computed for the default
-     *                       display. Currently for all non-default displays sensors, docking mode,
-     *                       rotation lock and other factors are ignored.
      * @return The surface rotation to use.
      */
     int rotationForOrientation(int orientation, int lastRotation) {
@@ -418,8 +481,8 @@
         final int preferredRotation;
         if (!isDefaultDisplay) {
             // For secondary displays we ignore things like displays sensors, docking mode and
-            // rotation lock, and always prefer a default rotation.
-            preferredRotation = Surface.ROTATION_0;
+            // rotation lock, and always prefer user rotation.
+            preferredRotation = mUserRotation;
         } else if (lidState == LID_OPEN && mLidOpenRotation >= 0) {
             // Ignore sensor when lid switch is open and rotation is forced.
             preferredRotation = mLidOpenRotation;
diff --git a/services/core/java/com/android/server/wm/DisplaySettings.java b/services/core/java/com/android/server/wm/DisplaySettings.java
index bbb690f..28dc008 100644
--- a/services/core/java/com/android/server/wm/DisplaySettings.java
+++ b/services/core/java/com/android/server/wm/DisplaySettings.java
@@ -20,20 +20,23 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
 import android.app.WindowConfiguration;
-import android.content.Context;
-import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.os.Environment;
-import android.provider.Settings;
 import android.util.AtomicFile;
 import android.util.Slog;
 import android.util.Xml;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.Surface;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
+import com.android.server.policy.WindowManagerPolicy;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -43,10 +46,6 @@
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
 /**
  * Current persistent settings about a display
  */
@@ -58,15 +57,25 @@
     private final HashMap<String, Entry> mEntries = new HashMap<String, Entry>();
 
     private static class Entry {
-        private final String name;
-        private int overscanLeft;
-        private int overscanTop;
-        private int overscanRight;
-        private int overscanBottom;
-        private int windowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+        private final String mName;
+        private int mOverscanLeft;
+        private int mOverscanTop;
+        private int mOverscanRight;
+        private int mOverscanBottom;
+        private int mWindowingMode = WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+        private int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+        private int mUserRotation = Surface.ROTATION_0;
 
         private Entry(String _name) {
-            name = _name;
+            mName = _name;
+        }
+
+        private boolean isEmpty() {
+            return mOverscanLeft == 0 && mOverscanTop == 0 && mOverscanRight == 0
+                    && mOverscanBottom == 0
+                    && mWindowingMode == WindowConfiguration.WINDOWING_MODE_UNDEFINED
+                    && mUserRotationMode == WindowManagerPolicy.USER_ROTATION_FREE
+                    && mUserRotation == Surface.ROTATION_0;
         }
     }
 
@@ -90,13 +99,30 @@
         return entry;
     }
 
+    private Entry getOrCreateEntry(String uniqueId, String name) {
+        Entry entry = getEntry(uniqueId, name);
+        if (entry == null) {
+            entry = new Entry(uniqueId);
+            mEntries.put(uniqueId, entry);
+        }
+        return entry;
+    }
+
+    private void removeEntryIfEmpty(String uniqueId, String name) {
+        final Entry entry = getEntry(uniqueId, name);
+        if (entry.isEmpty()) {
+            mEntries.remove(uniqueId);
+            mEntries.remove(name);
+        }
+    }
+
     private void getOverscanLocked(String name, String uniqueId, Rect outRect) {
         final Entry entry = getEntry(name, uniqueId);
         if (entry != null) {
-            outRect.left = entry.overscanLeft;
-            outRect.top = entry.overscanTop;
-            outRect.right = entry.overscanRight;
-            outRect.bottom = entry.overscanBottom;
+            outRect.left = entry.mOverscanLeft;
+            outRect.top = entry.mOverscanTop;
+            outRect.right = entry.mOverscanRight;
+            outRect.bottom = entry.mOverscanBottom;
         } else {
             outRect.set(0, 0, 0, 0);
         }
@@ -104,28 +130,22 @@
 
     void setOverscanLocked(String uniqueId, String name, int left, int top, int right,
             int bottom) {
-        if (left == 0 && top == 0 && right == 0 && bottom == 0) {
-            // Right now all we are storing is overscan; if there is no overscan,
-            // we have no need for the entry.
-            mEntries.remove(uniqueId);
-            // Legacy name might have been in used, so we need to clear it.
-            mEntries.remove(name);
+        Entry entry = mEntries.get(uniqueId);
+        if (left == 0 && top == 0 && right == 0 && bottom == 0 && entry == null) {
+            // All default value, no action needed.
             return;
         }
-        Entry entry = mEntries.get(uniqueId);
-        if (entry == null) {
-            entry = new Entry(uniqueId);
-            mEntries.put(uniqueId, entry);
-        }
-        entry.overscanLeft = left;
-        entry.overscanTop = top;
-        entry.overscanRight = right;
-        entry.overscanBottom = bottom;
+        entry = getOrCreateEntry(uniqueId, name);
+        entry.mOverscanLeft = left;
+        entry.mOverscanTop = top;
+        entry.mOverscanRight = right;
+        entry.mOverscanBottom = bottom;
+        removeEntryIfEmpty(uniqueId, name);
     }
 
     private int getWindowingModeLocked(String name, String uniqueId, int displayId) {
         final Entry entry = getEntry(name, uniqueId);
-        int windowingMode = entry != null ? entry.windowingMode
+        int windowingMode = entry != null ? entry.mWindowingMode
                 : WindowConfiguration.WINDOWING_MODE_UNDEFINED;
         // This display used to be in freeform, but we don't support freeform anymore, so fall
         // back to fullscreen.
@@ -148,6 +168,36 @@
         return windowingMode;
     }
 
+    void setUserRotation(DisplayContent dc, int rotationMode, int rotation) {
+        final DisplayInfo displayInfo = dc.getDisplayInfo();
+
+        final String uniqueId = displayInfo.uniqueId;
+        final String name = displayInfo.name;
+        Entry entry = getEntry(displayInfo.name, uniqueId);
+        if (rotationMode == WindowManagerPolicy.USER_ROTATION_FREE
+                && rotation == Surface.ROTATION_0 && entry == null) {
+            // All default values. No action needed.
+            return;
+        }
+
+        entry = getOrCreateEntry(uniqueId, name);
+        entry.mUserRotationMode = rotationMode;
+        entry.mUserRotation = rotation;
+        removeEntryIfEmpty(uniqueId, name);
+    }
+
+    private void restoreUserRotation(DisplayContent dc) {
+        final DisplayInfo info = dc.getDisplayInfo();
+
+        final Entry entry = getEntry(info.name, info.uniqueId);
+        final int userRotationMode = entry != null ? entry.mUserRotationMode
+                : WindowManagerPolicy.USER_ROTATION_FREE;
+        final int userRotation = entry != null ? entry.mUserRotation
+                : Surface.ROTATION_0;
+
+        dc.getDisplayRotation().restoreUserRotation(userRotationMode, userRotation);
+    }
+
     void applySettingsToDisplayLocked(DisplayContent dc) {
         final DisplayInfo displayInfo = dc.getDisplayInfo();
 
@@ -161,6 +211,8 @@
         displayInfo.overscanTop = rect.top;
         displayInfo.overscanRight = rect.right;
         displayInfo.overscanBottom = rect.bottom;
+
+        restoreUserRotation(dc);
     }
 
     void readSettingsLocked() {
@@ -244,12 +296,16 @@
         String name = parser.getAttributeValue(null, "name");
         if (name != null) {
             Entry entry = new Entry(name);
-            entry.overscanLeft = getIntAttribute(parser, "overscanLeft");
-            entry.overscanTop = getIntAttribute(parser, "overscanTop");
-            entry.overscanRight = getIntAttribute(parser, "overscanRight");
-            entry.overscanBottom = getIntAttribute(parser, "overscanBottom");
-            entry.windowingMode = getIntAttribute(parser, "windowingMode",
+            entry.mOverscanLeft = getIntAttribute(parser, "overscanLeft");
+            entry.mOverscanTop = getIntAttribute(parser, "overscanTop");
+            entry.mOverscanRight = getIntAttribute(parser, "overscanRight");
+            entry.mOverscanBottom = getIntAttribute(parser, "overscanBottom");
+            entry.mWindowingMode = getIntAttribute(parser, "windowingMode",
                     WindowConfiguration.WINDOWING_MODE_UNDEFINED);
+            entry.mUserRotationMode = getIntAttribute(parser, "userRotationMode",
+                    WindowManagerPolicy.USER_ROTATION_FREE);
+            entry.mUserRotation = getIntAttribute(parser, "userRotation",
+                    Surface.ROTATION_0);
             mEntries.put(name, entry);
         }
         XmlUtils.skipCurrentTag(parser);
@@ -272,21 +328,28 @@
 
             for (Entry entry : mEntries.values()) {
                 out.startTag(null, "display");
-                out.attribute(null, "name", entry.name);
-                if (entry.overscanLeft != 0) {
-                    out.attribute(null, "overscanLeft", Integer.toString(entry.overscanLeft));
+                out.attribute(null, "name", entry.mName);
+                if (entry.mOverscanLeft != 0) {
+                    out.attribute(null, "overscanLeft", Integer.toString(entry.mOverscanLeft));
                 }
-                if (entry.overscanTop != 0) {
-                    out.attribute(null, "overscanTop", Integer.toString(entry.overscanTop));
+                if (entry.mOverscanTop != 0) {
+                    out.attribute(null, "overscanTop", Integer.toString(entry.mOverscanTop));
                 }
-                if (entry.overscanRight != 0) {
-                    out.attribute(null, "overscanRight", Integer.toString(entry.overscanRight));
+                if (entry.mOverscanRight != 0) {
+                    out.attribute(null, "overscanRight", Integer.toString(entry.mOverscanRight));
                 }
-                if (entry.overscanBottom != 0) {
-                    out.attribute(null, "overscanBottom", Integer.toString(entry.overscanBottom));
+                if (entry.mOverscanBottom != 0) {
+                    out.attribute(null, "overscanBottom", Integer.toString(entry.mOverscanBottom));
                 }
-                if (entry.windowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
-                    out.attribute(null, "windowingMode", Integer.toString(entry.windowingMode));
+                if (entry.mWindowingMode != WindowConfiguration.WINDOWING_MODE_UNDEFINED) {
+                    out.attribute(null, "windowingMode", Integer.toString(entry.mWindowingMode));
+                }
+                if (entry.mUserRotationMode != WindowManagerPolicy.USER_ROTATION_FREE) {
+                    out.attribute(null, "userRotationMode",
+                            Integer.toString(entry.mUserRotationMode));
+                }
+                if (entry.mUserRotation != Surface.ROTATION_0) {
+                    out.attribute(null, "userRotation", Integer.toString(entry.mUserRotation));
                 }
                 out.endTag(null, "display");
             }
diff --git a/services/core/java/com/android/server/wm/DisplayWindowController.java b/services/core/java/com/android/server/wm/DisplayWindowController.java
index 76b6dbe..ab87759 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowController.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowController.java
@@ -17,11 +17,14 @@
 package com.android.server.wm;
 
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
 import android.content.res.Configuration;
 import android.os.Binder;
+import android.os.IBinder;
 import android.util.Slog;
 import android.view.Display;
 
@@ -124,6 +127,42 @@
         }
     }
 
+    /**
+     * Sets a focused app on this display.
+     *
+     * @param token Specifies which app should be focused.
+     * @param moveFocusNow Specifies if we should update the focused window immediately.
+     */
+    public void setFocusedApp(IBinder token, boolean moveFocusNow) {
+        synchronized (mWindowMap) {
+            if (mContainer == null) {
+                if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "setFocusedApp: could not find displayId="
+                        + mDisplayId);
+                return;
+            }
+            final AppWindowToken newFocus;
+            if (token == null) {
+                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Clearing focused app, displayId="
+                        + mDisplayId);
+                newFocus = null;
+            } else {
+                newFocus = mRoot.getAppWindowToken(token);
+                if (newFocus == null) {
+                    Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token
+                            + ", displayId=" + mDisplayId);
+                }
+                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Set focused app to: " + newFocus
+                        + " moveFocusNow=" + moveFocusNow + " displayId=" + mDisplayId);
+            }
+
+            final boolean changed = mContainer.setFocusedApp(newFocus);
+            if (moveFocusNow && changed) {
+                mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
+                        true /*updateInputWindows*/);
+            }
+        }
+    }
+
     @Override
     public String toString() {
         return "{DisplayWindowController displayId=" + mDisplayId + "}";
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index b5e2f01..10d77e5 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -108,7 +108,7 @@
         }
 
         // All the calls below need to happen without the WM lock held since they call into AM.
-        mService.mAmInternal.saveANRState(reason);
+        mService.mAtmInternal.saveANRState(reason);
 
         if (appWindowToken != null && appWindowToken.appToken != null) {
             // Notify the activity manager about the timeout and let it decide whether
@@ -125,7 +125,7 @@
         } else if (windowState != null) {
             // Notify the activity manager about the timeout and let it decide whether
             // to abort dispatching or keep waiting.
-            long timeout = mService.mAtmInternal.inputDispatchingTimedOut(
+            long timeout = mService.mAmInternal.inputDispatchingTimedOut(
                     windowState.mSession.mPid, aboveSystem, reason);
             if (timeout >= 0) {
                 // The activity manager declined to abort dispatching.
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index ef3a770..ed3e6c6 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -64,7 +64,6 @@
     // Array of window handles to provide to the input dispatcher.
     private InputWindowHandle[] mInputWindowHandles;
     private int mInputWindowHandleCount;
-    private InputWindowHandle mFocusedInputWindowHandle;
 
     private boolean mDisableWallpaperTouchEvents;
     private final Rect mTmpRect = new Rect();
@@ -229,16 +228,12 @@
                     + child + ", " + inputWindowHandle);
         }
         addInputWindowHandle(inputWindowHandle);
-        if (hasFocus) {
-            mFocusedInputWindowHandle = inputWindowHandle;
-        }
     }
 
     private void clearInputWindowHandlesLw() {
         while (mInputWindowHandleCount != 0) {
             mInputWindowHandles[--mInputWindowHandleCount] = null;
         }
-        mFocusedInputWindowHandle = null;
     }
 
     void setUpdateInputWindowsNeededLw() {
@@ -325,13 +320,13 @@
     public void setFocusedAppLw(AppWindowToken newApp) {
         // Focused app has changed.
         if (newApp == null) {
-            mService.mInputManager.setFocusedApplication(null);
+            mService.mInputManager.setFocusedApplication(mDisplayId, null);
         } else {
             final InputApplicationHandle handle = newApp.mInputApplicationHandle;
             handle.name = newApp.toString();
             handle.dispatchingTimeoutNanos = newApp.mInputDispatchingTimeoutNanos;
 
-            mService.mInputManager.setFocusedApplication(handle);
+            mService.mInputManager.setFocusedApplication(mDisplayId, handle);
         }
     }
 
@@ -370,8 +365,7 @@
     void onRemoved() {
         // If DisplayContent removed, we need find a way to remove window handles of this display
         // from InputDispatcher, so pass an empty InputWindowHandles to remove them.
-        mService.mInputManager.setInputWindows(mInputWindowHandles, mFocusedInputWindowHandle,
-                mDisplayId);
+        mService.mInputManager.setInputWindows(mInputWindowHandles, mDisplayId);
     }
 
     private final class UpdateInputForAllWindowsConsumer implements Consumer<WindowState> {
@@ -414,8 +408,7 @@
             }
 
             // Send windows to native code.
-            mService.mInputManager.setInputWindows(mInputWindowHandles, mFocusedInputWindowHandle,
-                    mDisplayId);
+            mService.mInputManager.setInputWindows(mInputWindowHandles, mDisplayId);
 
             clearInputWindowHandlesLw();
 
@@ -435,7 +428,6 @@
             final int flags = w.mAttrs.flags;
             final int privateFlags = w.mAttrs.privateFlags;
             final int type = w.mAttrs.type;
-            // TODO(b/111361570): multi-display focus, one focus window per display.
             final boolean hasFocus = w.isFocused();
             final boolean isVisible = w.isVisibleLw();
 
@@ -443,14 +435,14 @@
                 final RecentsAnimationController recentsAnimationController =
                         mService.getRecentsAnimationController();
                 if (recentsAnimationController != null
-                        && recentsAnimationController.hasInputConsumerForApp(w.mAppToken)) {
+                        && recentsAnimationController.shouldApplyInputConsumer(w.mAppToken)) {
                     if (recentsAnimationController.updateInputConsumerForApp(
                             recentsAnimationInputConsumer.mWindowHandle, hasFocus)) {
                         addInputWindowHandle(recentsAnimationInputConsumer.mWindowHandle);
                         mAddRecentsAnimationInputConsumerHandle = false;
                     }
-                    // Skip adding the window below regardless of whether there is an input consumer
-                    // to handle it
+                    // If the target app window does not yet exist, then we don't add the input
+                    // consumer window, but also don't add the app window below.
                     return;
                 }
             }
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 278d2b8..b64d4f8 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -582,6 +582,9 @@
         pw.print(prefix + "  defaultBounds=");
         getDefaultBounds(INVALID_SNAP_FRACTION).printShortString(pw);
         pw.println();
+        pw.println(prefix + "  mDefaultMinSize=" + mDefaultMinSize);
+        pw.println(prefix + "  mDefaultStackGravity=" + mDefaultStackGravity);
+        pw.println(prefix + "  mDefaultAspectRatio=" + mDefaultAspectRatio);
         mService.getStackBounds(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mTmpRect);
         pw.print(prefix + "  movementBounds="); getMovementBounds(mTmpRect).printShortString(pw);
         pw.println();
@@ -591,6 +594,9 @@
         pw.println(prefix + "  mShelfHeight=" + mShelfHeight);
         pw.println(prefix + "  mReentrySnapFraction=" + mReentrySnapFraction);
         pw.println(prefix + "  mIsMinimized=" + mIsMinimized);
+        pw.println(prefix + "  mAspectRatio=" + mAspectRatio);
+        pw.println(prefix + "  mMinAspectRatio=" + mMinAspectRatio);
+        pw.println(prefix + "  mMaxAspectRatio=" + mMaxAspectRatio);
         if (mActions.isEmpty()) {
             pw.println(prefix + "  mActions=[]");
         } else {
@@ -602,7 +608,7 @@
             }
             pw.println(prefix + "  ]");
         }
-        pw.println(prefix + " mDisplayInfo=" + mDisplayInfo);
+        pw.println(prefix + "  mDisplayInfo=" + mDisplayInfo);
     }
 
     void writeToProto(ProtoOutputStream proto, long fieldId) {
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 6fef1630..5c80759 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -458,10 +458,9 @@
         mRunner = null;
         mCanceled = true;
 
-        // Clear associated input consumers
+        // Update the input windows after the animation is complete
         final InputMonitor inputMonitor =
                 mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
-        inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
         inputMonitor.updateInputWindowsLw(true /*force*/);
 
         // We have deferred all notifications to the target app as a part of the recents animation,
@@ -494,6 +493,11 @@
     @Override
     public void binderDied() {
         cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "binderDied");
+
+        // Clear associated input consumers on runner death
+        final InputMonitor inputMonitor =
+                mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
+        inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
     }
 
     void checkAnimationReady(WallpaperController wallpaperController) {
@@ -516,8 +520,14 @@
                 && isTargetOverWallpaper();
     }
 
-    boolean hasInputConsumerForApp(AppWindowToken appToken) {
-        return mInputConsumerEnabled && isAnimatingApp(appToken);
+    /**
+     * @return Whether to use the input consumer to override app input to route home/recents.
+     */
+    boolean shouldApplyInputConsumer(AppWindowToken appToken) {
+        // Only apply the input consumer if it is enabled, it is not the target (home/recents)
+        // being revealed with the transition, and we are actively animating the app as a part of
+        // the animation
+        return mInputConsumerEnabled && mTargetAppToken != appToken && isAnimatingApp(appToken);
     }
 
     boolean updateInputConsumerForApp(InputWindowHandle inputWindowHandle,
@@ -675,6 +685,7 @@
         final String innerPrefix = prefix + "  ";
         pw.print(prefix); pw.println(RecentsAnimationController.class.getSimpleName() + ":");
         pw.print(innerPrefix); pw.println("mPendingStart=" + mPendingStart);
+        pw.print(innerPrefix); pw.println("mPendingAnimations=" + mPendingAnimations.size());
         pw.print(innerPrefix); pw.println("mCanceled=" + mCanceled);
         pw.print(innerPrefix); pw.println("mInputConsumerEnabled=" + mInputConsumerEnabled);
         pw.print(innerPrefix); pw.println("mSplitScreenMinimized=" + mSplitScreenMinimized);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index a9571be..c8977be 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -17,19 +17,20 @@
 package com.android.server.wm;
 
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
 import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE;
 import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
 import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
 
-import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
 import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
 import static com.android.server.wm.RootWindowContainerProto.DISPLAYS;
 import static com.android.server.wm.RootWindowContainerProto.WINDOWS;
 import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
@@ -41,9 +42,9 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
 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.WindowManagerService.H.REPORT_LOSING_FOCUS;
 import static com.android.server.wm.WindowManagerService.H.SEND_NEW_CONFIGURATION;
 import static com.android.server.wm.WindowManagerService.H.WINDOW_FREEZE_TIMEOUT;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
 import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_NONE;
@@ -124,6 +125,10 @@
 
     private String mCloseSystemDialogsReason;
 
+    // The ID of the display which is responsible for receiving display-unspecified key and pointer
+    // events.
+    private int mTopFocusedDisplayId = INVALID_DISPLAY;
+
     // Only a seperate transaction until we seperate the apply surface changes
     // transaction from the global transaction.
     private final SurfaceControl.Transaction mDisplayTransaction = new SurfaceControl.Transaction();
@@ -153,23 +158,40 @@
         mWallpaperController = new WallpaperController(mService);
     }
 
-    WindowState computeFocusedWindow() {
-        // While the keyguard is showing, we must focus anything besides the main display.
-        // Otherwise we risk input not going to the keyguard when the user expects it to.
-        final boolean forceDefaultDisplay = mService.isKeyguardShowingAndNotOccluded();
-
+    boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
+        boolean changed = false;
+        int topFocusedDisplayId = INVALID_DISPLAY;
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final DisplayContent dc = mChildren.get(i);
-            final WindowState win = dc.findFocusedWindow();
-            if (win != null) {
-                if (forceDefaultDisplay && !dc.isDefaultDisplay) {
-                    EventLog.writeEvent(0x534e4554, "71786287", win.mOwnerUid, "");
-                    continue;
-                }
-                return win;
+            changed |= dc.updateFocusedWindowLocked(mode, updateInputWindows,
+                    topFocusedDisplayId != INVALID_DISPLAY /* focusFound */);
+            if (topFocusedDisplayId == INVALID_DISPLAY && dc.mCurrentFocus != null) {
+                topFocusedDisplayId = dc.getDisplayId();
             }
         }
-        return null;
+        if (topFocusedDisplayId == INVALID_DISPLAY) {
+            topFocusedDisplayId = DEFAULT_DISPLAY;
+        }
+        if (mTopFocusedDisplayId != topFocusedDisplayId) {
+            mTopFocusedDisplayId = topFocusedDisplayId;
+            mService.mInputManager.setFocusedDisplay(topFocusedDisplayId);
+            if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "New topFocusedDisplayId="
+                    + topFocusedDisplayId);
+        }
+        final WindowState topFocusedWindow = getTopFocusedDisplayContent().mCurrentFocus;
+        mService.mInputManager.setFocusedWindow(
+                topFocusedWindow != null ? topFocusedWindow.mInputWindowHandle : null);
+        return changed;
+    }
+
+    DisplayContent getTopFocusedDisplayContent() {
+        return getDisplayContent(mTopFocusedDisplayId == INVALID_DISPLAY
+                ? DEFAULT_DISPLAY : mTopFocusedDisplayId);
+    }
+
+    @Override
+    void onChildPositionChanged() {
+        mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateInputWindows */);
     }
 
     DisplayContent getDisplayContent(int displayId) {
@@ -206,21 +228,6 @@
             mService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(
                     displayId, dc.getDisplayInfo());
             dc.configureDisplayPolicy();
-
-            // Tap Listeners are supported for:
-            // 1. All physical displays (multi-display).
-            // 2. VirtualDisplays on VR, AA (and everything else).
-            if (mService.canDispatchPointerEvents()) {
-                if (DEBUG_DISPLAY) {
-                    Slog.d(TAG,
-                            "Registering PointerEventListener for DisplayId: " + displayId);
-                }
-                dc.mTapDetector = new TaskTapPointerEventListener(mService, dc);
-                mService.registerPointerEventListener(dc.mTapDetector);
-                if (displayId == DEFAULT_DISPLAY) {
-                    mService.registerPointerEventListener(mService.mMousePositionTracker);
-                }
-            }
         }
 
         return dc;
@@ -636,7 +643,6 @@
             if (mService.updateFocusedWindowLocked(UPDATE_FOCUS_PLACING_SURFACES,
                     false /*updateInputWindows*/)) {
                 updateInputWindowsNeeded = true;
-                defaultDisplay.pendingLayoutChanges |= FINISH_LAYOUT_REDO_ANIM;
             }
         }
 
@@ -646,7 +652,7 @@
                     defaultDisplay.pendingLayoutChanges);
         }
 
-        final ArraySet<DisplayContent> touchExcludeRegionUpdateDisplays = handleResizingWindows();
+        handleResizingWindows();
 
         if (DEBUG_ORIENTATION && mService.mDisplayFrozen) Slog.v(TAG,
                 "With display frozen, orientationChangeComplete=" + mOrientationChangeComplete);
@@ -765,17 +771,7 @@
                 dc.getInputMonitor().updateInputWindowsLw(false /*force*/);
             });
         }
-        mService.setFocusTaskRegionLocked(null);
-        if (touchExcludeRegionUpdateDisplays != null) {
-            final DisplayContent focusedDc = mService.mFocusedApp != null
-                    ? mService.mFocusedApp.getDisplayContent() : null;
-            for (DisplayContent dc : touchExcludeRegionUpdateDisplays) {
-                // The focused DisplayContent was recalcuated in setFocusTaskRegionLocked
-                if (focusedDc != dc) {
-                    dc.setTouchExcludeRegion(null /* focusedTask */);
-                }
-            }
-        }
+        forAllDisplays(DisplayContent::updateTouchExcludeRegion);
 
         // Check to see if we are now in a state where the screen should
         // be enabled, because the window obscured flags have changed.
@@ -808,16 +804,10 @@
                     mService.getDefaultDisplayRotation());
         }
 
-        boolean focusDisplayed = false;
-
         final int count = mChildren.size();
         for (int j = 0; j < count; ++j) {
             final DisplayContent dc = mChildren.get(j);
-            focusDisplayed |= dc.applySurfaceChangesTransaction(recoveringMemory);
-        }
-
-        if (focusDisplayed) {
-            mService.mH.sendEmptyMessage(REPORT_LOSING_FOCUS);
+            dc.applySurfaceChangesTransaction(recoveringMemory);
         }
 
         // Give the display manager a chance to adjust properties like display rotation if it needs
@@ -828,12 +818,8 @@
 
     /**
      * Handles resizing windows during surface placement.
-     *
-     * @return A set of any DisplayContent whose touch exclude region needs to be recalculated due
-     *         to a tap-exclude window resizing, or null if no such DisplayContents were found.
      */
-    private ArraySet<DisplayContent> handleResizingWindows() {
-        ArraySet<DisplayContent> touchExcludeRegionUpdateSet = null;
+    private void handleResizingWindows() {
         for (int i = mService.mResizingWindows.size() - 1; i >= 0; i--) {
             WindowState win = mService.mResizingWindows.get(i);
             if (win.mAppFreezing) {
@@ -842,15 +828,7 @@
             }
             win.reportResized();
             mService.mResizingWindows.remove(i);
-            if (WindowManagerService.excludeWindowTypeFromTapOutTask(win.mAttrs.type)) {
-                final DisplayContent dc = win.getDisplayContent();
-                if (touchExcludeRegionUpdateSet == null) {
-                    touchExcludeRegionUpdateSet = new ArraySet<>();
-                }
-                touchExcludeRegionUpdateSet.add(dc);
-            }
         }
-        return touchExcludeRegionUpdateSet;
     }
 
     /**
@@ -1004,6 +982,10 @@
         }
     }
 
+    void dumpTopFocusedDisplayId(PrintWriter pw) {
+        pw.print("  mTopFocusedDisplayId="); pw.println(mTopFocusedDisplayId);
+    }
+
     void dumpLayoutNeededDisplayIds(PrintWriter pw) {
         if (!isLayoutNeeded()) {
             return;
diff --git a/services/core/java/com/android/server/wm/TaskPositioningController.java b/services/core/java/com/android/server/wm/TaskPositioningController.java
index 33416f6..25148d1 100644
--- a/services/core/java/com/android/server/wm/TaskPositioningController.java
+++ b/services/core/java/com/android/server/wm/TaskPositioningController.java
@@ -88,7 +88,7 @@
                     }
                     taskId = task.mTaskId;
                 } else {
-                    taskId = displayContent.taskIdFromPoint(x, y);
+                    taskId = displayContent.taskForTapOutside(x, y);
                 }
             }
             if (taskId >= 0) {
@@ -131,9 +131,9 @@
         // of the app, it may not have focus since there might be other windows
         // on top (eg. a dialog window).
         WindowState transferFocusFromWin = win;
-        if (mService.mCurrentFocus != null && mService.mCurrentFocus != win
-                && mService.mCurrentFocus.mAppToken == win.mAppToken) {
-            transferFocusFromWin = mService.mCurrentFocus;
+        if (displayContent.mCurrentFocus != null && displayContent.mCurrentFocus != win
+                && displayContent.mCurrentFocus.mAppToken == win.mAppToken) {
+            transferFocusFromWin = displayContent.mCurrentFocus;
         }
         if (!mInputManager.transferTouchFocus(
                 transferFocusFromWin.mInputChannel, mTaskPositioner.mServerChannel)) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index b7507a4..ef63b9b 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -29,13 +29,13 @@
 import android.graphics.Bitmap;
 import android.graphics.GraphicBuffer;
 import android.graphics.PixelFormat;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
+import android.graphics.RenderNode;
 import android.os.Environment;
 import android.os.Handler;
 import android.util.ArraySet;
 import android.util.Slog;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
 import android.view.SurfaceControl;
 import android.view.ThreadedRenderer;
 import android.view.WindowManager.LayoutParams;
@@ -371,7 +371,7 @@
         final RenderNode node = RenderNode.create("TaskSnapshotController", null);
         node.setLeftTopRightBottom(0, 0, width, height);
         node.setClipToBounds(false);
-        final DisplayListCanvas c = node.start(width, height);
+        final RecordingCanvas c = node.start(width, height);
         c.drawColor(color);
         decorPainter.setInsets(mainWindow.getContentInsets(), mainWindow.getStableInsets());
         decorPainter.drawDecors(c, null /* statusBarExcludeFrame */);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
index 21e807e..6fd1795 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java
@@ -17,6 +17,7 @@
 package com.android.server.wm;
 
 import static android.graphics.Bitmap.CompressFormat.*;
+
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
@@ -361,6 +362,7 @@
 
             // For snapshots with reduced resolution, do not create or save full sized bitmaps
             if (mSnapshot.isReducedResolution()) {
+                swBitmap.recycle();
                 return true;
             }
 
@@ -373,6 +375,8 @@
                 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/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
index f1e1592..52f8510 100644
--- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java
@@ -19,12 +19,12 @@
 import android.graphics.Rect;
 import android.graphics.Region;
 import android.hardware.input.InputManager;
+import android.os.Handler;
 import android.view.MotionEvent;
 import android.view.WindowManagerPolicyConstants.PointerEventListener;
 
 import com.android.server.wm.WindowManagerService.H;
 
-import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.PointerIcon.TYPE_NOT_SPECIFIED;
 import static android.view.PointerIcon.TYPE_HORIZONTAL_DOUBLE_ARROW;
 import static android.view.PointerIcon.TYPE_VERTICAL_DOUBLE_ARROW;
@@ -36,6 +36,8 @@
     final private Region mTouchExcludeRegion = new Region();
     private final WindowManagerService mService;
     private final DisplayContent mDisplayContent;
+    private final Handler mHandler;
+    private final Runnable mMoveDisplayToTop;
     private final Rect mTmpRect = new Rect();
     private int mPointerIconType = TYPE_NOT_SPECIFIED;
 
@@ -43,6 +45,13 @@
             DisplayContent displayContent) {
         mService = service;
         mDisplayContent = displayContent;
+        mHandler = new Handler(mService.mH.getLooper());
+        mMoveDisplayToTop = () -> {
+            synchronized (mService.mWindowMap) {
+                mDisplayContent.getParent().positionChildAt(WindowContainer.POSITION_TOP,
+                        mDisplayContent, true /* includingParents */);
+            }
+        };
     }
 
     @Override
@@ -61,6 +70,7 @@
                         mService.mTaskPositioningController.handleTapOutsideTask(
                                 mDisplayContent, x, y);
                     }
+                    mHandler.post(mMoveDisplayToTop);
                 }
             }
             break;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 4883f97..46999a2 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -273,6 +273,7 @@
             parent.mTreeWeight += child.mTreeWeight;
             parent = parent.getParent();
         }
+        onChildPositionChanged();
     }
 
     /**
@@ -298,6 +299,7 @@
             parent.mTreeWeight -= child.mTreeWeight;
             parent = parent.getParent();
         }
+        onChildPositionChanged();
     }
 
     /**
@@ -455,9 +457,15 @@
                 mChildren.remove(child);
                 mChildren.add(position, child);
         }
+        onChildPositionChanged();
     }
 
     /**
+     * Notify that a child's position has changed. Possible changes are adding or removing a child.
+     */
+    void onChildPositionChanged() { }
+
+    /**
      * Update override configuration and recalculate full config.
      * @see #mOverrideConfiguration
      * @see #mFullConfiguration
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 5410676..b096bf2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -430,14 +430,25 @@
     public abstract boolean isUidFocused(int uid);
 
     /**
-     * Checks whether the specified process has IME focus or not.
+     * Checks whether the specified IME client has IME focus or not.
      *
      * @param uid UID of the process to be queried
      * @param pid PID of the process to be queried
-     * @return {@code true} if a process that is identified by {@code uid} and {@code pid} has IME
-     *         focus
+     * @param displayId Display ID reported from the client. Note that this method also verifies
+     *                  whether the specified process is allowed to access to this display or not
+     * @return {@code true} if the IME client specified with {@code uid}, {@code pid}, and
+     *         {@code displayId} has IME focus
      */
-    public abstract boolean isInputMethodClientFocus(int uid, int pid);
+    public abstract boolean isInputMethodClientFocus(int uid, int pid, int displayId);
+
+    /**
+     * Checks whether the given {@code uid} is allowed to use the given {@code displayId} or not.
+     *
+     * @param displayId Display ID to be checked
+     * @param uid UID to be checked.
+     * @return {@code true} if the given {@code uid} is allowed to use the given {@code displayId}
+     */
+    public abstract boolean isUidAllowedOnDisplay(int displayId, int uid);
 
     /**
      * Return the display Id for given window.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 942e47b..5642b1f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -45,8 +45,8 @@
 import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
 import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -499,12 +499,6 @@
     final ArrayList<WindowState> mDestroyPreservedSurface = new ArrayList<>();
 
     /**
-     * Windows that have lost input focus and are waiting for the new
-     * focus window to be displayed before they are told about this.
-     */
-    ArrayList<WindowState> mLosingFocus = new ArrayList<>();
-
-    /**
      * This is set when we have run out of memory, and will either be an empty
      * list or contain windows that need to be force removed.
      */
@@ -639,14 +633,6 @@
      */
     final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper());
 
-    WindowState mCurrentFocus = null;
-    WindowState mLastFocus = null;
-
-    /** Windows added since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
-    private final ArrayList<WindowState> mWinAddedSinceNullFocus = new ArrayList<>();
-    /** Windows removed since {@link #mCurrentFocus} was set to null. Used for ANR blaming. */
-    private final ArrayList<WindowState> mWinRemovedSinceNullFocus = new ArrayList<>();
-
     /** This just indicates the window the input method is on top of, not
      * necessarily the window its input is going to. */
     WindowState mInputMethodTarget = null;
@@ -721,9 +707,6 @@
         }
     }
 
-    // TODO: Move to RootWindowContainer
-    AppWindowToken mFocusedApp = null;
-
     PowerManager mPowerManager;
     PowerManagerInternal mPowerManagerInternal;
 
@@ -770,8 +753,6 @@
     final ArrayMap<AnimationAdapter, SurfaceAnimator> mAnimationTransferMap = new ArrayMap<>();
     final BoundsAnimationController mBoundsAnimationController;
 
-    private final PointerEventDispatcher mPointerEventDispatcher;
-
     private WindowContentFrameStats mTempWindowRenderStats;
 
     private final LatencyTracker mLatencyTracker;
@@ -962,14 +943,6 @@
 
         LocalServices.addService(WindowManagerPolicy.class, mPolicy);
 
-        if(mInputManager != null) {
-            final InputChannel inputChannel = mInputManager.monitorInput(TAG_WM);
-            mPointerEventDispatcher = inputChannel != null
-                    ? new PointerEventDispatcher(inputChannel) : null;
-        } else {
-            mPointerEventDispatcher = null;
-        }
-
         mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
 
         mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy);
@@ -1371,8 +1344,8 @@
                 // the screen after the activity goes away.
                 if (addToastWindowRequiresToken
                         || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0
-                        || mCurrentFocus == null
-                        || mCurrentFocus.mOwnerUid != callingUid) {
+                        || displayContent.mCurrentFocus == null
+                        || displayContent.mCurrentFocus.mOwnerUid != callingUid) {
                     mH.sendMessageDelayed(
                             mH.obtainMessage(H.WINDOW_HIDE_TIMEOUT, win),
                             win.mAttrs.hideTimeoutMilliseconds);
@@ -1382,8 +1355,8 @@
             // From now on, no exceptions or errors allowed!
 
             res = WindowManagerGlobal.ADD_OKAY;
-            if (mCurrentFocus == null) {
-                mWinAddedSinceNullFocus.add(win);
+            if (displayContent.mCurrentFocus == null) {
+                displayContent.mWinAddedSinceNullFocus.add(win);
             }
 
             if (excludeWindowTypeFromTapOutTask(type)) {
@@ -1504,7 +1477,7 @@
             win.getParent().assignChildLayers();
 
             if (focusChanged) {
-                displayContent.getInputMonitor().setInputFocusLw(mCurrentFocus,
+                displayContent.getInputMonitor().setInputFocusLw(displayContent.mCurrentFocus,
                         false /*updateInputWindows*/);
             }
             displayContent.getInputMonitor().updateInputWindowsLw(false /*force*/);
@@ -1679,8 +1652,9 @@
 
         win.resetAppOpsState();
 
-        if (mCurrentFocus == null) {
-            mWinRemovedSinceNullFocus.add(win);
+        final DisplayContent dc = win.getDisplayContent();
+        if (dc.mCurrentFocus == null) {
+            dc.mWinRemovedSinceNullFocus.add(win);
         }
         mPendingRemove.remove(win);
         mResizingWindows.remove(win);
@@ -1716,7 +1690,6 @@
             atoken.postWindowRemoveStartingWindowCleanup(win);
         }
 
-        final DisplayContent dc = win.getDisplayContent();
         if (win.mAttrs.type == TYPE_WALLPAPER) {
             dc.mWallpaperController.clearLastWallpaperTimeoutTime();
             dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
@@ -1945,7 +1918,7 @@
                     mAccessibilityController.onSomeWindowResizedOrMovedLocked();
                 }
 
-                if ((flagChanges & PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
+                if ((flagChanges & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0) {
                     updateNonSystemOverlayWindowsVisibilityIfNeeded(
                             win, win.mWinAnimator.getShown());
                 }
@@ -1978,9 +1951,9 @@
             boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0
                     || becameVisible;
             final boolean isDefaultDisplay = win.isDefaultDisplay();
-            boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
+            boolean focusMayChange = win.mViewVisibility != viewVisibility
                     || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
-                    || (!win.mRelayoutCalled));
+                    || (!win.mRelayoutCalled);
 
             boolean wallpaperMayMove = win.mViewVisibility != viewVisibility
                     && (win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
@@ -2025,8 +1998,7 @@
                 }
                 result |= RELAYOUT_RES_SURFACE_CHANGED;
                 if (!win.mWillReplaceWindow) {
-                    focusMayChange = tryStartExitingAnimation(win, winAnimator, isDefaultDisplay,
-                            focusMayChange);
+                    focusMayChange = tryStartExitingAnimation(win, winAnimator, focusMayChange);
                 }
             }
 
@@ -2051,7 +2023,7 @@
                     return 0;
                 }
                 if ((result & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
-                    focusMayChange = isDefaultDisplay;
+                    focusMayChange = true;
                 }
                 final DisplayContent displayContent = win.getDisplayContent();
                 if (win.mAttrs.type == TYPE_INPUT_METHOD
@@ -2199,7 +2171,7 @@
     }
 
     private boolean tryStartExitingAnimation(WindowState win, WindowStateAnimator winAnimator,
-            boolean isDefaultDisplay, boolean focusMayChange) {
+            boolean focusMayChange) {
         // Try starting an animation; if there isn't one, we
         // can destroy the surface right away.
         int transit = WindowManagerPolicy.TRANSIT_EXIT;
@@ -2207,7 +2179,7 @@
             transit = WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
         }
         if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
-            focusMayChange = isDefaultDisplay;
+            focusMayChange = true;
             win.mAnimatingExit = true;
         } else if (win.isAnimating()) {
             // Currently in a hide animation... turn this into
@@ -2504,57 +2476,6 @@
         }
     }
 
-    void setFocusTaskRegionLocked(AppWindowToken previousFocus) {
-        final Task focusedTask = mFocusedApp != null ? mFocusedApp.getTask() : null;
-        final Task previousTask = previousFocus != null ? previousFocus.getTask() : null;
-        final DisplayContent focusedDisplayContent =
-                focusedTask != null ? focusedTask.getDisplayContent() : null;
-        final DisplayContent previousDisplayContent =
-                previousTask != null ? previousTask.getDisplayContent() : null;
-        if (previousDisplayContent != null && previousDisplayContent != focusedDisplayContent) {
-            previousDisplayContent.setTouchExcludeRegion(null);
-        }
-        if (focusedDisplayContent != null) {
-            focusedDisplayContent.setTouchExcludeRegion(focusedTask);
-        }
-    }
-
-    @Override
-    public void setFocusedApp(IBinder token, boolean moveFocusNow) {
-        if (!checkCallingPermission(MANAGE_APP_TOKENS, "setFocusedApp()")) {
-            throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
-        }
-
-        synchronized(mWindowMap) {
-            final AppWindowToken newFocus;
-            if (token == null) {
-                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Clearing focused app, was " + mFocusedApp);
-                newFocus = null;
-            } else {
-                newFocus = mRoot.getAppWindowToken(token);
-                if (newFocus == null) {
-                    Slog.w(TAG_WM, "Attempted to set focus to non-existing app token: " + token);
-                }
-                if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Set focused app to: " + newFocus
-                        + " old focus=" + mFocusedApp + " moveFocusNow=" + moveFocusNow);
-            }
-
-            final boolean changed = mFocusedApp != newFocus;
-            if (changed) {
-                AppWindowToken prev = mFocusedApp;
-                mFocusedApp = newFocus;
-                mFocusedApp.getDisplayContent().getInputMonitor().setFocusedAppLw(newFocus);
-                setFocusTaskRegionLocked(prev);
-            }
-
-            if (moveFocusNow && changed) {
-                final long origId = Binder.clearCallingIdentity();
-                updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
-                Binder.restoreCallingIdentity(origId);
-            }
-        }
-    }
-
     @Override
     public void prepareAppTransition(@TransitionType int transit, boolean alwaysKeepCurrent) {
         prepareAppTransition(transit, alwaysKeepCurrent, 0 /* flags */, false /* forceOverride */);
@@ -2754,8 +2675,9 @@
     public void cleanupRecentsAnimation(@RecentsAnimationController.ReorderMode int reorderMode) {
         synchronized (mWindowMap) {
             if (mRecentsAnimationController != null) {
-                mRecentsAnimationController.cleanupAnimation(reorderMode);
+                final RecentsAnimationController controller = mRecentsAnimationController;
                 mRecentsAnimationController = null;
+                controller.cleanupAnimation(reorderMode);
                 mAppTransition.updateBooster();
             }
         }
@@ -3195,18 +3117,23 @@
     }
 
     @Override
-    public void registerPointerEventListener(PointerEventListener listener) {
-        mPointerEventDispatcher.registerInputEventListener(listener);
+    public void registerPointerEventListener(PointerEventListener listener, int displayId) {
+        synchronized (mWindowMap) {
+            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+            if (displayContent != null) {
+                displayContent.registerPointerEventListener(listener);
+            }
+        }
     }
 
     @Override
-    public void unregisterPointerEventListener(PointerEventListener listener) {
-        mPointerEventDispatcher.unregisterInputEventListener(listener);
-    }
-
-    /** Check if the service is set to dispatch pointer events. */
-    boolean canDispatchPointerEvents() {
-        return mPointerEventDispatcher != null;
+    public void unregisterPointerEventListener(PointerEventListener listener, int displayId) {
+        synchronized (mWindowMap) {
+            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+            if (displayContent != null) {
+                displayContent.unregisterPointerEventListener(listener);
+            }
+        }
     }
 
     // Called by window manager policy. Not exposed externally.
@@ -3741,14 +3668,19 @@
         }
     }
 
+    @Override
+    public void freezeRotation(int rotation) {
+        freezeDisplayRotation(Display.DEFAULT_DISPLAY, rotation);
+    }
+
     /**
      * Freeze rotation changes.  (Enable "rotation lock".)
      * Persists across reboots.
-     * @param rotation The desired rotation to freeze to, or -1 to use the
-     * current rotation.
+     * @param displayId The ID of the display to freeze.
+     * @param rotation The desired rotation to freeze to, or -1 to use the current rotation.
      */
     @Override
-    public void freezeRotation(int rotation) {
+    public void freezeDisplayRotation(int displayId, int rotation) {
         // TODO(multi-display): Track which display is rotated.
         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                 "freezeRotation()")) {
@@ -3759,14 +3691,16 @@
                     + "rotation constant.");
         }
 
-        final int defaultDisplayRotation = getDefaultDisplayRotation();
-        if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "freezeRotation: mRotation="
-                + defaultDisplayRotation);
-
         long origId = Binder.clearCallingIdentity();
         try {
-            mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED,
-                    rotation == -1 ? defaultDisplayRotation : rotation);
+            synchronized (mWindowMap) {
+                final DisplayContent display = mRoot.getDisplayContent(displayId);
+                if (display == null) {
+                    Slog.w(TAG, "Trying to freeze rotation for a missing display.");
+                    return;
+                }
+                display.getDisplayRotation().freezeRotation(rotation);
+            }
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
@@ -3774,12 +3708,17 @@
         updateRotationUnchecked(false, false);
     }
 
+    @Override
+    public void thawRotation() {
+        thawDisplayRotation(Display.DEFAULT_DISPLAY);
+    }
+
     /**
      * Thaw rotation changes.  (Disable "rotation lock".)
      * Persists across reboots.
      */
     @Override
-    public void thawRotation() {
+    public void thawDisplayRotation(int displayId) {
         if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
                 "thawRotation()")) {
             throw new SecurityException("Requires SET_ORIENTATION permission");
@@ -3790,8 +3729,14 @@
 
         long origId = Binder.clearCallingIdentity();
         try {
-            mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE,
-                    777); // rot not used
+            synchronized (mWindowMap) {
+                final DisplayContent display = mRoot.getDisplayContent(displayId);
+                if (display == null) {
+                    Slog.w(TAG, "Trying to thaw rotation for a missing display.");
+                    return;
+                }
+                display.getDisplayRotation().thawRotation();
+            }
         } finally {
             Binder.restoreCallingIdentity(origId);
         }
@@ -3799,6 +3744,23 @@
         updateRotationUnchecked(false, false);
     }
 
+    @Override
+    public boolean isRotationFrozen() {
+        return isDisplayRotationFrozen(Display.DEFAULT_DISPLAY);
+    }
+
+    @Override
+    public boolean isDisplayRotationFrozen(int displayId) {
+        synchronized (mWindowMap) {
+            final DisplayContent display = mRoot.getDisplayContent(displayId);
+            if (display == null) {
+                Slog.w(TAG, "Trying to thaw rotation for a missing display.");
+                return false;
+            }
+            return display.getDisplayRotation().isRotationFrozen();
+        }
+    }
+
     /**
      * Recalculate the current rotation.
      *
@@ -3868,11 +3830,6 @@
     }
 
     @Override
-    public boolean isRotationFrozen() {
-        return mPolicy.getUserRotationMode() == WindowManagerPolicy.USER_ROTATION_LOCKED;
-    }
-
-    @Override
     public int watchRotation(IRotationWatcher watcher, int displayId) {
         final DisplayContent displayContent;
         synchronized (mWindowMap) {
@@ -4395,7 +4352,8 @@
     }
 
     private WindowState getFocusedWindowLocked() {
-        return mCurrentFocus;
+        // Return the focused window in the focused display.
+        return mRoot.getTopFocusedDisplayContent().mCurrentFocus;
     }
 
     TaskStack getImeFocusStackLocked() {
@@ -4403,8 +4361,11 @@
         // Also don't use mInputMethodTarget's stack, because some window with FLAG_NOT_FOCUSABLE
         // and FLAG_ALT_FOCUSABLE_IM flags both set might be set to IME target so they're moved
         // to make room for IME, but the window is not the focused window that's taking input.
-        return (mFocusedApp != null && mFocusedApp.getTask() != null) ?
-                mFocusedApp.getTask().mStack : null;
+        // TODO (b/111080190): Consider the case of multiple IMEs on multi-display.
+        final DisplayContent topFocusedDisplay = mRoot.getTopFocusedDisplayContent();
+        final AppWindowToken focusedApp = topFocusedDisplay.mFocusedApp;
+        return (focusedApp != null && focusedApp.getTask() != null)
+                ? focusedApp.getTask().mStack : null;
     }
 
     public boolean detectSafeMode() {
@@ -4542,7 +4503,6 @@
         public static final int REPORT_LOSING_FOCUS = 3;
         public static final int WINDOW_FREEZE_TIMEOUT = 11;
 
-        public static final int APP_TRANSITION_TIMEOUT = 13;
         public static final int PERSIST_ANIMATION_SCALE = 14;
         public static final int FORCE_GC = 15;
         public static final int ENABLE_SCREEN = 16;
@@ -4554,7 +4514,6 @@
         public static final int BOOT_TIMEOUT = 23;
         public static final int WAITING_FOR_DRAWN_TIMEOUT = 24;
         public static final int SHOW_STRICT_MODE_VIOLATION = 25;
-        public static final int DO_ANIMATION_CALLBACK = 26;
 
         public static final int CLIENT_FREEZE_TIMEOUT = 30;
         public static final int NOTIFY_ACTIVITY_DRAWN = 32;
@@ -4601,6 +4560,7 @@
             }
             switch (msg.what) {
                 case REPORT_FOCUS_CHANGE: {
+                    final DisplayContent displayContent = (DisplayContent) msg.obj;
                     WindowState lastFocus;
                     WindowState newFocus;
 
@@ -4608,24 +4568,22 @@
 
                     synchronized(mWindowMap) {
                         // TODO(multidisplay): Accessibility supported only of default desiplay.
-                        if (mAccessibilityController != null && getDefaultDisplayContentLocked()
-                                .getDisplayId() == DEFAULT_DISPLAY) {
+                        if (mAccessibilityController != null && displayContent.isDefaultDisplay) {
                             accessibilityController = mAccessibilityController;
                         }
 
-                        lastFocus = mLastFocus;
-                        newFocus = mCurrentFocus;
+                        lastFocus = displayContent.mLastFocus;
+                        newFocus = displayContent.mCurrentFocus;
                         if (lastFocus == newFocus) {
                             // Focus is not changing, so nothing to do.
                             return;
                         }
-                        mLastFocus = newFocus;
+                        displayContent.mLastFocus = newFocus;
                         if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Focus moving from " + lastFocus +
-                                " to " + newFocus);
-                        if (newFocus != null && lastFocus != null
-                                && !newFocus.isDisplayedLw()) {
-                            //Slog.i(TAG_WM, "Delaying loss of focus...");
-                            mLosingFocus.add(lastFocus);
+                                " to " + newFocus + " displayId=" + displayContent.getDisplayId());
+                        if (newFocus != null && lastFocus != null && !newFocus.isDisplayedLw()) {
+                            if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Delaying loss of focus...");
+                            displayContent.mLosingFocus.add(lastFocus);
                             lastFocus = null;
                         }
                     }
@@ -4636,8 +4594,6 @@
                         accessibilityController.onWindowFocusChangedNotLocked();
                     }
 
-                    //System.out.println("Changing focus from " + lastFocus
-                    //                   + " to " + newFocus);
                     if (newFocus != null) {
                         if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Gaining focus: " + newFocus);
                         newFocus.reportFocusChangedSerialized(true, mInTouchMode);
@@ -4651,15 +4607,16 @@
                 } break;
 
                 case REPORT_LOSING_FOCUS: {
+                    final DisplayContent displayContent = (DisplayContent) msg.obj;
                     ArrayList<WindowState> losers;
 
                     synchronized(mWindowMap) {
-                        losers = mLosingFocus;
-                        mLosingFocus = new ArrayList<WindowState>();
+                        losers = displayContent.mLosingFocus;
+                        displayContent.mLosingFocus = new ArrayList<>();
                     }
 
                     final int N = losers.size();
-                    for (int i=0; i<N; i++) {
+                    for (int i = 0; i < N; i++) {
                         if (DEBUG_FOCUS_LIGHT) Slog.i(TAG_WM, "Losing delayed focus: " +
                                 losers.get(i));
                         losers.get(i).reportFocusChangedSerialized(false, mInTouchMode);
@@ -4674,21 +4631,6 @@
                     break;
                 }
 
-                case APP_TRANSITION_TIMEOUT: {
-                    synchronized (mWindowMap) {
-                        if (mAppTransition.isTransitionSet() || !mOpeningApps.isEmpty()
-                                    || !mClosingApps.isEmpty()) {
-                            if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "*** APP TRANSITION TIMEOUT."
-                                    + " isTransitionSet()=" + mAppTransition.isTransitionSet()
-                                    + " mOpeningApps.size()=" + mOpeningApps.size()
-                                    + " mClosingApps.size()=" + mClosingApps.size());
-                            mAppTransition.setTimeout();
-                            mWindowPlacerLocked.performSurfacePlacement();
-                        }
-                    }
-                    break;
-                }
-
                 case PERSIST_ANIMATION_SCALE: {
                     Settings.Global.putFloat(mContext.getContentResolver(),
                             Settings.Global.WINDOW_ANIMATION_SCALE, mWindowAnimationScaleSetting);
@@ -4841,14 +4783,6 @@
                     break;
                 }
 
-                case DO_ANIMATION_CALLBACK: {
-                    try {
-                        ((IRemoteCallback)msg.obj).sendResult(null);
-                    } catch (RemoteException e) {
-                    }
-                    break;
-                }
-
                 case NOTIFY_ACTIVITY_DRAWN:
                     try {
                         mActivityTaskManager.notifyActivityDrawn((IBinder) msg.obj);
@@ -4908,7 +4842,7 @@
                     synchronized (mWindowMap) {
                         mLastANRState = null;
                     }
-                    mAmInternal.clearSavedANRState();
+                    mAtmInternal.clearSavedANRState();
                 }
                 break;
                 case WALLPAPER_DRAW_PENDING_TIMEOUT: {
@@ -5553,89 +5487,11 @@
         }
     }
 
-    // TODO: Move to DisplayContent
     boolean updateFocusedWindowLocked(int mode, boolean updateInputWindows) {
-        WindowState newFocus = mRoot.computeFocusedWindow();
-        if (mCurrentFocus != newFocus) {
-            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
-            // This check makes sure that we don't already have the focus
-            // change message pending.
-            mH.removeMessages(H.REPORT_FOCUS_CHANGE);
-            mH.sendEmptyMessage(H.REPORT_FOCUS_CHANGE);
-            final DisplayContent displayContent = (newFocus != null) ? newFocus.getDisplayContent()
-                    : getDefaultDisplayContentLocked();
-            boolean imWindowChanged = false;
-            if (displayContent.mInputMethodWindow != null) {
-                final WindowState prevTarget = mInputMethodTarget;
-
-                final WindowState newTarget =
-                        displayContent.computeImeTarget(true /* updateImeTarget*/);
-                imWindowChanged = prevTarget != newTarget;
-
-                if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS
-                        && mode != UPDATE_FOCUS_WILL_PLACE_SURFACES) {
-                    displayContent.assignWindowLayers(false /* setLayoutNeeded */);
-                }
-            }
-
-            if (imWindowChanged) {
-                mWindowsChanged = true;
-                displayContent.setLayoutNeeded();
-                newFocus = mRoot.computeFocusedWindow();
-            }
-
-            if (DEBUG_FOCUS_LIGHT || localLOGV) Slog.v(TAG_WM, "Changing focus from " +
-                    mCurrentFocus + " to " + newFocus + " Callers=" + Debug.getCallers(4));
-            final WindowState oldFocus = mCurrentFocus;
-            mCurrentFocus = newFocus;
-            mLosingFocus.remove(newFocus);
-
-            if (mCurrentFocus != null) {
-                mWinAddedSinceNullFocus.clear();
-                mWinRemovedSinceNullFocus.clear();
-            }
-
-            int focusChanged = mPolicy.focusChangedLw(oldFocus, newFocus);
-
-            if (imWindowChanged && oldFocus != displayContent.mInputMethodWindow) {
-                // Focus of the input method window changed. Perform layout if needed.
-                if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
-                    displayContent.performLayout(true /*initial*/,  updateInputWindows);
-                    focusChanged &= ~FINISH_LAYOUT_REDO_LAYOUT;
-                } else if (mode == UPDATE_FOCUS_WILL_PLACE_SURFACES) {
-                    // Client will do the layout, but we need to assign layers
-                    // for handleNewWindowLocked() below.
-                    displayContent.assignWindowLayers(false /* setLayoutNeeded */);
-                }
-            }
-
-            if ((focusChanged & FINISH_LAYOUT_REDO_LAYOUT) != 0) {
-                // The change in focus caused us to need to do a layout.  Okay.
-                displayContent.setLayoutNeeded();
-                if (mode == UPDATE_FOCUS_PLACING_SURFACES) {
-                    displayContent.performLayout(true /*initial*/, updateInputWindows);
-                } else if (mode == UPDATE_FOCUS_REMOVING_FOCUS) {
-                    mRoot.performSurfacePlacement(false);
-                }
-            }
-
-            if (mode != UPDATE_FOCUS_WILL_ASSIGN_LAYERS) {
-                // If we defer assigning layers, then the caller is responsible for
-                // doing this part.
-                displayContent.getInputMonitor().setInputFocusLw(mCurrentFocus, updateInputWindows);
-            }
-
-            displayContent.adjustForImeIfNeeded();
-
-            // We may need to schedule some toast windows to be removed. The toasts for an app that
-            // does not have input focus are removed within a timeout to prevent apps to redress
-            // other apps' UI.
-            displayContent.scheduleToastWindowsTimeoutIfNeededLocked(oldFocus, newFocus);
-
-            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-            return true;
-        }
-        return false;
+        Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "wmUpdateFocus");
+        boolean changed = mRoot.updateFocusedWindowLocked(mode, updateInputWindows);
+        Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+        return changed;
     }
 
     void startFreezingDisplayLocked(int exitAnim, int enterAnim) {
@@ -6197,11 +6053,12 @@
     void writeToProtoLocked(ProtoOutputStream proto, boolean trim) {
         mPolicy.writeToProto(proto, POLICY);
         mRoot.writeToProto(proto, ROOT_WINDOW_CONTAINER, trim);
-        if (mCurrentFocus != null) {
-            mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW);
+        final DisplayContent topFocusedDisplayContent = mRoot.getTopFocusedDisplayContent();
+        if (topFocusedDisplayContent.mCurrentFocus != null) {
+            topFocusedDisplayContent.mCurrentFocus.writeIdentifierToProto(proto, FOCUSED_WINDOW);
         }
-        if (mFocusedApp != null) {
-            mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
+        if (topFocusedDisplayContent.mFocusedApp != null) {
+            topFocusedDisplayContent.mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
         }
         final WindowState imeWindow = mRoot.getCurrentInputMethodWindow();
         if (imeWindow != null) {
@@ -6299,23 +6156,6 @@
                 }
             }
         }
-        if (mLosingFocus.size() > 0) {
-            pw.println();
-            pw.println("  Windows losing focus:");
-            for (int i=mLosingFocus.size()-1; i>=0; i--) {
-                WindowState w = mLosingFocus.get(i);
-                if (windows == null || windows.contains(w)) {
-                    pw.print("  Losing #"); pw.print(i); pw.print(' ');
-                            pw.print(w);
-                    if (dumpAll) {
-                        pw.println(":");
-                        w.dump(pw, "    ", true);
-                    } else {
-                        pw.println();
-                    }
-                }
-            }
-        }
         if (mResizingWindows.size() > 0) {
             pw.println();
             pw.println("  Windows waiting to resize:");
@@ -6344,11 +6184,7 @@
         pw.println();
         pw.print("  mGlobalConfiguration="); pw.println(mRoot.getConfiguration());
         pw.print("  mHasPermanentDpad="); pw.println(mHasPermanentDpad);
-        pw.print("  mCurrentFocus="); pw.println(mCurrentFocus);
-        if (mLastFocus != mCurrentFocus) {
-            pw.print("  mLastFocus="); pw.println(mLastFocus);
-        }
-        pw.print("  mFocusedApp="); pw.println(mFocusedApp);
+        mRoot.dumpTopFocusedDisplayId(pw);
         if (mInputMethodTarget != null) {
             pw.print("  mInputMethodTarget="); pw.println(mInputMethodTarget);
         }
@@ -6479,11 +6315,17 @@
         if (reason != null) {
             pw.println("  Reason: " + reason);
         }
-        if (!mWinAddedSinceNullFocus.isEmpty()) {
-            pw.println("  Windows added since null focus: " + mWinAddedSinceNullFocus);
-        }
-        if (!mWinRemovedSinceNullFocus.isEmpty()) {
-            pw.println("  Windows removed since null focus: " + mWinRemovedSinceNullFocus);
+        for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
+            final DisplayContent dc = mRoot.getChildAt(i);
+            final int displayId = dc.getDisplayId();
+            if (!dc.mWinAddedSinceNullFocus.isEmpty()) {
+                pw.println("  Windows added in display #" + displayId + " since null focus: "
+                        + dc.mWinAddedSinceNullFocus);
+            }
+            if (!dc.mWinRemovedSinceNullFocus.isEmpty()) {
+                pw.println("  Windows removed in display #" + displayId + " since null focus: "
+                        + dc.mWinRemovedSinceNullFocus);
+            }
         }
         pw.println();
         dumpWindowsNoHeaderLocked(pw, true, null);
@@ -6818,9 +6660,9 @@
     @Override
     public void setDockedStackDividerTouchRegion(Rect touchRegion) {
         synchronized (mWindowMap) {
-            getDefaultDisplayContentLocked().getDockedDividerController()
-                    .setTouchRegion(touchRegion);
-            setFocusTaskRegionLocked(null);
+            final DisplayContent dc = getDefaultDisplayContentLocked();
+            dc.getDockedDividerController().setTouchRegion(touchRegion);
+            dc.updateTouchExcludeRegion();
         }
     }
 
@@ -7373,21 +7215,32 @@
         @Override
         public boolean isUidFocused(int uid) {
             synchronized (mWindowMap) {
-                return mCurrentFocus != null ? uid == mCurrentFocus.getOwningUid() : false;
+                for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
+                    final DisplayContent displayContent = mRoot.getChildAt(i);
+                    if (displayContent.mCurrentFocus != null
+                            && uid == displayContent.mCurrentFocus.getOwningUid()) {
+                        return true;
+                    }
+                }
+                return false;
             }
         }
 
         @Override
-        public boolean isInputMethodClientFocus(int uid, int pid) {
+        public boolean isInputMethodClientFocus(int uid, int pid, int displayId) {
+            if (displayId == Display.INVALID_DISPLAY) {
+                return false;
+            }
             synchronized (mWindowMap) {
-                // Check all displays if any input method window has focus.
-                for (int i = mRoot.mChildren.size() - 1; i >= 0; --i) {
-                    final DisplayContent displayContent = mRoot.mChildren.get(i);
-                    if (displayContent.isInputMethodClientFocus(uid, pid)) {
-                        return true;
-                    }
+                final DisplayContent displayContent = mRoot.getTopFocusedDisplayContent();
+                if (displayContent == null
+                        || displayContent.getDisplayId() != displayId
+                        || !displayContent.hasAccess(uid)) {
+                    return false;
                 }
-
+                if (displayContent.isInputMethodClientFocus(uid, pid)) {
+                    return true;
+                }
                 // Okay, how about this...  what is the current focus?
                 // It seems in some cases we may not have moved the IM
                 // target window, such as when it was in a pop-up window,
@@ -7396,8 +7249,9 @@
                 // press home.  Sometimes the IME won't go down.)
                 // Would be nice to fix this more correctly, but it's
                 // way at the end of a release, and this should be good enough.
-                if (mCurrentFocus != null && mCurrentFocus.mSession.mUid == uid
-                        && mCurrentFocus.mSession.mPid == pid) {
+                final WindowState currentFocus = displayContent.mCurrentFocus;
+                if (currentFocus != null && currentFocus.mSession.mUid == uid
+                        && currentFocus.mSession.mPid == pid) {
                     return true;
                 }
             }
@@ -7405,6 +7259,20 @@
         }
 
         @Override
+        public boolean isUidAllowedOnDisplay(int displayId, int uid) {
+            if (displayId == Display.DEFAULT_DISPLAY) {
+                return true;
+            }
+            if (displayId == Display.INVALID_DISPLAY) {
+                return false;
+            }
+            synchronized (mWindowMap) {
+                final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+                return displayContent != null && displayContent.hasAccess(uid);
+            }
+        }
+
+        @Override
         public int getDisplayIdForWindow(IBinder windowToken) {
             synchronized (mWindowMap) {
                 final WindowState window = mWindowMap.get(windowToken);
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 831418b..bf2d0df 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -26,6 +26,7 @@
 import android.util.DisplayMetrics;
 import android.view.Display;
 import android.view.IWindowManager;
+import android.view.Surface;
 
 import java.io.PrintWriter;
 import java.util.regex.Matcher;
@@ -73,6 +74,8 @@
                     // trace files can be written.
                     return mInternal.mWindowTracing.onShellCommand(this,
                             getNextArgRequired());
+                case "set-user-rotation":
+                    return runSetDisplayUserRotation(pw);
                 default:
                     return handleDefaultCommands(cmd);
             }
@@ -262,6 +265,36 @@
         return Integer.parseInt(s);
     }
 
+    private int runSetDisplayUserRotation(PrintWriter pw) {
+        final String lockMode = getNextArgRequired();
+
+        int displayId = Display.DEFAULT_DISPLAY;
+        String arg = getNextArg();
+        if ("-d".equals(arg)) {
+            displayId = Integer.parseInt(getNextArgRequired());
+            arg = getNextArg();
+        }
+
+        if ("free".equals(lockMode)) {
+            mInternal.thawDisplayRotation(displayId);
+            return 0;
+        }
+
+        if (!lockMode.equals("lock")) {
+            getErrPrintWriter().println("Error: lock mode needs to be either free or lock.");
+            return -1;
+        }
+
+        try {
+            final int rotation = arg != null ? Integer.parseInt(arg) : Surface.ROTATION_0;
+            mInternal.freezeDisplayRotation(displayId, rotation);
+            return 0;
+        } catch (IllegalArgumentException e) {
+            getErrPrintWriter().println("Error: " + e.getMessage());
+            return -1;
+        }
+    }
+
     @Override
     public void onHelp() {
         PrintWriter pw = getOutPrintWriter();
@@ -279,6 +312,8 @@
         pw.println("    Set display scaling mode.");
         pw.println("  dismiss-keyguard");
         pw.println("    Dismiss the keyguard, prompting user for auth if necessary.");
+        pw.println("  set-user-rotation [free|lock] [-d DISPLAY_ID] [rotation]");
+        pw.println("    Set user rotation mode and user rotation.");
         if (!IS_USER) {
             pw.println("  tracing (start | stop)");
             pw.println("    Start or stop window tracing.");
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index a4bac31..f16008d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -46,12 +46,12 @@
 import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
 import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
@@ -1833,7 +1833,7 @@
         if (startingWindow && DEBUG_STARTING_WINDOW) Slog.d(TAG_WM,
                 "Starting window removed " + this);
 
-        if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && this == mService.mCurrentFocus)
+        if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && isFocused())
             Slog.v(TAG_WM, "Remove " + this + " client="
                         + Integer.toHexString(System.identityHashCode(mClient.asBinder()))
                         + ", surfaceController=" + mWinAnimator.mSurfaceController + " Callers="
@@ -1945,7 +1945,7 @@
             if (wasVisible && mService.updateOrientationFromAppTokensLocked(displayId)) {
                 mService.mH.obtainMessage(SEND_NEW_CONFIGURATION, displayId).sendToTarget();
             }
-            mService.updateFocusedWindowLocked(mService.mCurrentFocus == this
+            mService.updateFocusedWindowLocked(isFocused()
                             ? UPDATE_FOCUS_REMOVING_FOCUS
                             : UPDATE_FOCUS_NORMAL,
                     true /*updateInputWindows*/);
@@ -2180,7 +2180,7 @@
             mPolicyVisibility = mPolicyVisibilityAfterAnim;
             if (!mPolicyVisibility) {
                 mWinAnimator.hide("checkPolicyVisibilityChange");
-                if (mService.mCurrentFocus == this) {
+                if (isFocused()) {
                     if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
                             "setAnimationLocked: setting mFocusMayChange true");
                     mService.mFocusMayChange = true;
@@ -2256,7 +2256,7 @@
     private Configuration getProcessGlobalConfiguration() {
         // For child windows we want to use the pid for the parent window in case the the child
         // window was added from another process.
-        final int pid = isChildWindow() ? getParentWindow().mSession.mPid : mSession.mPid;
+        final int pid = getParentWindow() != null ? getParentWindow().mSession.mPid : mSession.mPid;
         mTempConfiguration.setTo(mService.mProcessConfigurations.get(
                 pid, mService.mRoot.getConfiguration()));
         return mTempConfiguration;
@@ -2482,6 +2482,7 @@
             }
         }
         mPolicyVisibilityAfterAnim = false;
+        final boolean isFocused = isFocused();
         if (!doAnimation) {
             if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
             mPolicyVisibility = false;
@@ -2489,7 +2490,7 @@
             // for it to be displayed before enabling the display, that
             // we allow the display to be enabled now.
             mService.enableScreenIfNeededLocked();
-            if (mService.mCurrentFocus == this) {
+            if (isFocused) {
                 if (DEBUG_FOCUS_LIGHT) Slog.i(TAG,
                         "WindowState.hideLw: setting mFocusMayChange true");
                 mService.mFocusMayChange = true;
@@ -2498,7 +2499,7 @@
         if (requestAnim) {
             mService.scheduleAnimationLocked();
         }
-        if (mService.mCurrentFocus == this) {
+        if (isFocused) {
             mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false /* updateImWindows */);
         }
         return true;
@@ -2994,10 +2995,8 @@
         }
     }
 
-    public boolean isFocused() {
-        synchronized(mService.mWindowMap) {
-            return mService.mCurrentFocus == this;
-        }
+    boolean isFocused() {
+        return getDisplayContent().mCurrentFocus == this;
     }
 
     @Override
@@ -3471,7 +3470,7 @@
      * this window is visible.
      */
     boolean hideNonSystemOverlayWindowsWhenVisible() {
-        return (mAttrs.privateFlags & PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0
+        return (mAttrs.privateFlags & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS) != 0
                 && mSession.mCanHideNonSystemOverlayWindows;
     }
 
@@ -4435,7 +4434,12 @@
         @Override
         public boolean isFocused() {
             final WindowState outer = mOuter.get();
-            return outer != null && outer.isFocused();
+            if (outer != null) {
+                synchronized (outer.mService.mWindowMap) {
+                    return outer.isFocused();
+                }
+            }
+            return false;
         }
     }
 
@@ -4663,10 +4667,7 @@
 
         mTapExcludeRegionHolder.updateRegion(regionId, left, top, width, height);
         // Trigger touch exclude region update on current display.
-        final boolean isAppFocusedOnDisplay = mService.mFocusedApp != null
-                && mService.mFocusedApp.getDisplayContent() == currentDisplay;
-        currentDisplay.setTouchExcludeRegion(isAppFocusedOnDisplay ? mService.mFocusedApp.getTask()
-                : null);
+        currentDisplay.updateTouchExcludeRegion();
     }
 
     /** Union the region with current tap exclude region that this window provides. */
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 080a3a2..e13a70a 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -69,7 +69,6 @@
 import android.view.animation.Animation;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.wm.WindowManagerService.H;
 
 import java.io.PrintWriter;
 import java.util.function.Predicate;
@@ -252,7 +251,7 @@
         mService.mSkipAppTransitionAnimation = false;
         mService.mNoAnimationNotifyOnTransitionFinished.clear();
 
-        mService.mH.removeMessages(H.APP_TRANSITION_TIMEOUT);
+        mService.mAppTransition.removeAppTransitionTimeoutCallbacks();
 
         final DisplayContent displayContent = mService.getDefaultDisplayContentLocked();
 
@@ -763,6 +762,7 @@
 
     private void processApplicationsAnimatingInPlace(int transit) {
         if (transit == TRANSIT_TASK_IN_PLACE) {
+            // TODO (b/111362605): non-default-display transition.
             // Find the focused window
             final WindowState win = mService.getDefaultDisplayContentLocked().findFocusedWindow();
             if (win != null) {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index fefd305..0cf79b6 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -255,6 +255,7 @@
         super.removeImmediately();
     }
 
+    @Override
     void onDisplayChanged(DisplayContent dc) {
         dc.reParentWindowToken(this);
         mDisplayContent = dc;
diff --git a/services/core/java/com/android/server/wm/utils/DisplayRotationUtil.java b/services/core/java/com/android/server/wm/utils/DisplayRotationUtil.java
new file mode 100644
index 0000000..9f307bb
--- /dev/null
+++ b/services/core/java/com/android/server/wm/utils/DisplayRotationUtil.java
@@ -0,0 +1,96 @@
+/*
+ * 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.wm.utils;
+
+import static android.view.DisplayCutout.BOUNDS_POSITION_LENGTH;
+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 com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates;
+
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Utility to compute bounds after rotating the screen.
+ */
+public class DisplayRotationUtil {
+    private final Matrix mTmpMatrix = new Matrix();
+
+    private static int getRotationToBoundsOffset(int rotation) {
+        switch (rotation) {
+            case ROTATION_0:
+                return 0;
+            case ROTATION_90:
+                return -1;
+            case ROTATION_180:
+                return 2;
+            case ROTATION_270:
+                return 1;
+            default:
+                // should not happen
+                return 0;
+        }
+    }
+
+    @VisibleForTesting
+    static int getBoundIndexFromRotation(int i, int rotation) {
+        return Math.floorMod(i + getRotationToBoundsOffset(rotation),
+                BOUNDS_POSITION_LENGTH);
+    }
+
+    /**
+     * Compute bounds after rotating teh screen.
+     *
+     * @param bounds Bounds before the rotation. The array must contain exactly 4 non-null elements.
+     * @param rotation rotation constant defined in android.view.Surface.
+     * @param initialDisplayWidth width of the display before the rotation.
+     * @param initialDisplayHeight height of the display before the rotation.
+     * @return Bounds after the rotation.
+     *
+     * @hide
+     */
+    public Rect[] getRotatedBounds(
+            Rect[] bounds, int rotation, int initialDisplayWidth, int initialDisplayHeight) {
+        if (bounds.length != BOUNDS_POSITION_LENGTH) {
+            throw new IllegalArgumentException(
+                    "bounds must have exactly 4 elements: bounds=" + bounds);
+        }
+        if (rotation == ROTATION_0) {
+            return bounds;
+        }
+        transformPhysicalToLogicalCoordinates(rotation, initialDisplayWidth, initialDisplayHeight,
+                mTmpMatrix);
+        Rect[] newBounds = new Rect[BOUNDS_POSITION_LENGTH];
+        for (int i = 0; i < bounds.length; i++) {
+
+            final Rect rect = bounds[i];
+            if (!rect.isEmpty()) {
+                final RectF rectF = new RectF(rect);
+                mTmpMatrix.mapRect(rectF);
+                rectF.round(rect);
+            }
+            newBounds[getBoundIndexFromRotation(i, rotation)] = rect;
+        }
+        return newBounds;
+    }
+}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 157b634..15a3a1a3 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -8,6 +8,7 @@
         "-Wall",
         "-Werror",
         "-Wno-unused-parameter",
+        "-Wthread-safety",
 
         "-DEGL_EGLEXT_PROTOTYPES",
         "-DGL_GLEXT_PROTOTYPES",
@@ -29,9 +30,7 @@
         "com_android_server_devicepolicy_CryptoTestHelper.cpp",
         "com_android_server_HardwarePropertiesManagerService.cpp",
         "com_android_server_hdmi_HdmiCecController.cpp",
-        "com_android_server_input_InputApplicationHandle.cpp",
         "com_android_server_input_InputManagerService.cpp",
-        "com_android_server_input_InputWindowHandle.cpp",
         "com_android_server_lights_LightsService.cpp",
         "com_android_server_location_GnssLocationProvider.cpp",
         "com_android_server_locksettings_SyntheticPasswordManager.cpp",
@@ -100,6 +99,7 @@
         "libutils",
         "libhwui",
         "libbpf",
+        "libnetdbpf",
         "libnetdutils",
         "android.hardware.audio.common@2.0",
         "android.hardware.broadcastradio@1.0",
diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp
index 3901ceb..dc0d53b 100644
--- a/services/core/jni/com_android_server_SystemServer.cpp
+++ b/services/core/jni/com_android_server_SystemServer.cpp
@@ -17,6 +17,7 @@
 #include <jni.h>
 #include <nativehelper/JNIHelp.h>
 
+#include <binder/IServiceManager.h>
 #include <hidl/HidlTransportSupport.h>
 
 #include <schedulerservice/SchedulingPolicyService.h>
@@ -34,7 +35,8 @@
     char propBuf[PROPERTY_VALUE_MAX];
     property_get("system_init.startsensorservice", propBuf, "1");
     if (strcmp(propBuf, "1") == 0) {
-        SensorService::instantiate();
+        SensorService::publish(false /* allowIsolated */,
+                               IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
     }
 
 }
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 42ade38..3943dba 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -60,10 +60,12 @@
 #include <nativehelper/ScopedUtfChars.h>
 
 #include "com_android_server_power_PowerManagerService.h"
-#include "com_android_server_input_InputApplicationHandle.h"
-#include "com_android_server_input_InputWindowHandle.h"
+#include "android_hardware_input_InputApplicationHandle.h"
+#include "android_hardware_input_InputWindowHandle.h"
 #include "android_hardware_display_DisplayViewport.h"
 
+#include <vector>
+
 #define INDENT "  "
 
 using android::base::StringPrintf;
@@ -144,8 +146,8 @@
 
 static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
         const sp<InputApplicationHandle>& inputApplicationHandle) {
-    if (inputApplicationHandle == NULL) {
-        return NULL;
+    if (inputApplicationHandle == nullptr) {
+        return nullptr;
     }
     return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
             getInputApplicationHandleObjLocalRef(env);
@@ -153,8 +155,8 @@
 
 static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
         const sp<InputWindowHandle>& inputWindowHandle) {
-    if (inputWindowHandle == NULL) {
-        return NULL;
+    if (inputWindowHandle == nullptr) {
+        return nullptr;
     }
     return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
             getInputWindowHandleObjLocalRef(env);
@@ -182,6 +184,15 @@
     loadSystemIconAsSpriteWithPointerIcon(env, contextObj, style, &pointerIcon, outSpriteIcon);
 }
 
+static void updatePointerControllerFromViewport(
+        sp<PointerController> controller, const DisplayViewport* const viewport) {
+    if (controller != nullptr && viewport != nullptr) {
+        const int32_t width = viewport->logicalRight - viewport->logicalLeft;
+        const int32_t height = viewport->logicalBottom - viewport->logicalTop;
+        controller->setDisplayViewport(width, height, viewport->orientation);
+    }
+}
+
 enum {
     WM_ACTION_PASS_TO_USER = 1,
 };
@@ -203,15 +214,15 @@
 
     void dump(std::string& dump);
 
-    void setVirtualDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray);
-    void setDisplayViewport(int32_t viewportType, const DisplayViewport& viewport);
+    void setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray);
 
     status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
-            const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
+            const sp<InputWindowHandle>& inputWindowHandle, int32_t displayId);
     status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
 
     void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray, int32_t displayId);
-    void setFocusedApplication(JNIEnv* env, jobject applicationHandleObj);
+    void setFocusedApplication(JNIEnv* env, int32_t displayId, jobject applicationHandleObj);
+    void setFocusedDisplay(JNIEnv* env, int32_t displayId);
     void setInputDispatchMode(bool enabled, bool frozen);
     void setSystemUiVisibility(int32_t visibility);
     void setPointerSpeed(int32_t speed);
@@ -277,9 +288,7 @@
     Mutex mLock;
     struct Locked {
         // Display size information.
-        DisplayViewport internalViewport;
-        DisplayViewport externalViewport;
-        Vector<DisplayViewport> virtualViewports;
+        std::vector<DisplayViewport> viewports;
 
         // System UI visibility.
         int32_t systemUiVisibility;
@@ -304,7 +313,7 @@
 
         // Input devices to be disabled
         SortedVector<int32_t> disabledInputDevices;
-    } mLocked;
+    } mLocked GUARDED_BY(mLock);
 
     std::atomic<bool> mInteractive;
 
@@ -384,8 +393,17 @@
     return false;
 }
 
-void NativeInputManager::setVirtualDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray) {
-    Vector<DisplayViewport> viewports;
+static const DisplayViewport* findInternalViewport(const std::vector<DisplayViewport>& viewports) {
+    for (const DisplayViewport& v : viewports) {
+        if (v.type == ViewportType::VIEWPORT_INTERNAL) {
+            return &v;
+        }
+    }
+    return nullptr;
+}
+
+void NativeInputManager::setDisplayViewports(JNIEnv* env, jobjectArray viewportObjArray) {
+    std::vector<DisplayViewport> viewports;
 
     if (viewportObjArray) {
         jsize length = env->GetArrayLength(viewportObjArray);
@@ -397,63 +415,38 @@
 
             DisplayViewport viewport;
             android_hardware_display_DisplayViewport_toNative(env, viewportObj, &viewport);
-            ALOGI("Viewport [%d] to add: %s", (int) length, viewport.uniqueId.c_str());
-            viewports.push(viewport);
+            ALOGI("Viewport [%d] to add: %s", (int) i, viewport.uniqueId.c_str());
+            viewports.push_back(viewport);
 
             env->DeleteLocalRef(viewportObj);
         }
     }
 
+    const DisplayViewport* newInternalViewport = findInternalViewport(viewports);
     {
         AutoMutex _l(mLock);
-        mLocked.virtualViewports = viewports;
+        const DisplayViewport* oldInternalViewport = findInternalViewport(mLocked.viewports);
+        // Internal viewport has changed if there wasn't one earlier, and there is one now, or,
+        // if they are different.
+        const bool internalViewportChanged = (newInternalViewport != nullptr) &&
+                (oldInternalViewport == nullptr || (*oldInternalViewport != *newInternalViewport));
+        if (internalViewportChanged) {
+            sp<PointerController> controller = mLocked.pointerController.promote();
+            updatePointerControllerFromViewport(controller, newInternalViewport);
+        }
+        mLocked.viewports = viewports;
     }
 
     mInputManager->getReader()->requestRefreshConfiguration(
             InputReaderConfiguration::CHANGE_DISPLAY_INFO);
 }
 
-void NativeInputManager::setDisplayViewport(int32_t type, const DisplayViewport& viewport) {
-    bool changed = false;
-    {
-        AutoMutex _l(mLock);
-
-        ViewportType viewportType = static_cast<ViewportType>(type);
-        DisplayViewport* v = NULL;
-        if (viewportType == ViewportType::VIEWPORT_EXTERNAL) {
-            v = &mLocked.externalViewport;
-        } else if (viewportType == ViewportType::VIEWPORT_INTERNAL) {
-            v = &mLocked.internalViewport;
-        }
-
-        if (v != NULL && *v != viewport) {
-            changed = true;
-            *v = viewport;
-
-            if (viewportType == ViewportType::VIEWPORT_INTERNAL) {
-                sp<PointerController> controller = mLocked.pointerController.promote();
-                if (controller != NULL) {
-                    controller->setDisplayViewport(
-                            viewport.logicalRight - viewport.logicalLeft,
-                            viewport.logicalBottom - viewport.logicalTop,
-                            viewport.orientation);
-                }
-            }
-        }
-    }
-
-    if (changed) {
-        mInputManager->getReader()->requestRefreshConfiguration(
-                InputReaderConfiguration::CHANGE_DISPLAY_INFO);
-    }
-}
-
 status_t NativeInputManager::registerInputChannel(JNIEnv* /* env */,
-        const sp<InputChannel>& inputChannel,
-        const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
+        const sp<InputChannel>& inputChannel, const sp<InputWindowHandle>& inputWindowHandle,
+                int32_t displayId) {
     ATRACE_CALL();
-    return mInputManager->getDispatcher()->registerInputChannel(
-            inputChannel, inputWindowHandle, monitor);
+    return mInputManager->getDispatcher()->registerInputChannel(inputChannel, inputWindowHandle,
+            displayId);
 }
 
 status_t NativeInputManager::unregisterInputChannel(JNIEnv* /* env */,
@@ -479,7 +472,7 @@
         jsize length = env->GetArrayLength(excludedDeviceNames);
         for (jsize i = 0; i < length; i++) {
             jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i));
-            const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
+            const char* deviceNameChars = env->GetStringUTFChars(item, nullptr);
             outConfig->excludedDeviceNames.push_back(deviceNameChars);
             env->ReleaseStringUTFChars(item, deviceNameChars);
             env->DeleteLocalRef(item);
@@ -526,11 +519,7 @@
 
         outConfig->pointerCapture = mLocked.pointerCapture;
 
-        outConfig->setPhysicalDisplayViewport(ViewportType::VIEWPORT_INTERNAL,
-                mLocked.internalViewport);
-        outConfig->setPhysicalDisplayViewport(ViewportType::VIEWPORT_EXTERNAL,
-                mLocked.externalViewport);
-        outConfig->setVirtualDisplayViewports(mLocked.virtualViewports);
+        outConfig->setDisplayViewports(mLocked.viewports);
 
         outConfig->disabledDevices = mLocked.disabledInputDevices;
     } // release lock
@@ -541,25 +530,22 @@
     AutoMutex _l(mLock);
 
     sp<PointerController> controller = mLocked.pointerController.promote();
-    if (controller == NULL) {
+    if (controller == nullptr) {
         ensureSpriteControllerLocked();
 
         controller = new PointerController(this, mLooper, mLocked.spriteController);
         mLocked.pointerController = controller;
 
-        DisplayViewport& v = mLocked.internalViewport;
-        controller->setDisplayViewport(
-                v.logicalRight - v.logicalLeft,
-                v.logicalBottom - v.logicalTop,
-                v.orientation);
+        const DisplayViewport* internalViewport = findInternalViewport(mLocked.viewports);
+        updatePointerControllerFromViewport(controller, internalViewport);
 
         updateInactivityTimeoutLocked(controller);
     }
     return controller;
 }
 
-void NativeInputManager::ensureSpriteControllerLocked() {
-    if (mLocked.spriteController == NULL) {
+void NativeInputManager::ensureSpriteControllerLocked() REQUIRES(mLock) {
+    if (mLocked.spriteController == nullptr) {
         JNIEnv* env = jniEnv();
         jint layer = env->CallIntMethod(mServiceObj, gServiceClassInfo.getPointerLayer);
         if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
@@ -575,7 +561,7 @@
 
     size_t count = inputDevices.size();
     jobjectArray inputDevicesObjArray = env->NewObjectArray(
-            count, gInputDeviceClassInfo.clazz, NULL);
+            count, gInputDeviceClassInfo.clazz, nullptr);
     if (inputDevicesObjArray) {
         bool error = false;
         for (size_t i = 0; i < count; i++) {
@@ -750,7 +736,7 @@
 
             sp<InputWindowHandle> windowHandle =
                     android_server_InputWindowHandle_getHandle(env, windowHandleObj);
-            if (windowHandle != NULL) {
+            if (windowHandle != nullptr) {
                 windowHandles.push(windowHandle);
             }
             env->DeleteLocalRef(windowHandleObj);
@@ -786,10 +772,15 @@
     }
 }
 
-void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationHandleObj) {
+void NativeInputManager::setFocusedApplication(JNIEnv* env, int32_t displayId,
+        jobject applicationHandleObj) {
     sp<InputApplicationHandle> applicationHandle =
             android_server_InputApplicationHandle_getHandle(env, applicationHandleObj);
-    mInputManager->getDispatcher()->setFocusedApplication(applicationHandle);
+    mInputManager->getDispatcher()->setFocusedApplication(displayId, applicationHandle);
+}
+
+void NativeInputManager::setFocusedDisplay(JNIEnv* env, int32_t displayId) {
+    mInputManager->getDispatcher()->setFocusedDisplay(displayId);
 }
 
 void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
@@ -803,13 +794,14 @@
         mLocked.systemUiVisibility = visibility;
 
         sp<PointerController> controller = mLocked.pointerController.promote();
-        if (controller != NULL) {
+        if (controller != nullptr) {
             updateInactivityTimeoutLocked(controller);
         }
     }
 }
 
-void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
+void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller)
+        REQUIRES(mLock) {
     bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
     controller->setInactivityTimeout(lightsOut
             ? PointerController::INACTIVITY_TIMEOUT_SHORT
@@ -894,7 +886,7 @@
 void NativeInputManager::setPointerIconType(int32_t iconId) {
     AutoMutex _l(mLock);
     sp<PointerController> controller = mLocked.pointerController.promote();
-    if (controller != NULL) {
+    if (controller != nullptr) {
         controller->updatePointerIcon(iconId);
     }
 }
@@ -902,7 +894,7 @@
 void NativeInputManager::reloadPointerIcons() {
     AutoMutex _l(mLock);
     sp<PointerController> controller = mLocked.pointerController.promote();
-    if (controller != NULL) {
+    if (controller != nullptr) {
         controller->reloadPointerResources();
     }
 }
@@ -910,7 +902,7 @@
 void NativeInputManager::setCustomPointerIcon(const SpriteIcon& icon) {
     AutoMutex _l(mLock);
     sp<PointerController> controller = mLocked.pointerController.promote();
-    if (controller != NULL) {
+    if (controller != nullptr) {
         controller->setCustomPointerIcon(icon);
     }
 }
@@ -1122,7 +1114,7 @@
                     gServiceClassInfo.dispatchUnhandledKey,
                     inputWindowHandleObj, keyEventObj, policyFlags);
             if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
-                fallbackKeyEventObj = NULL;
+                fallbackKeyEventObj = nullptr;
             }
             android_view_KeyEvent_recycle(env, keyEventObj);
             env->DeleteLocalRef(keyEventObj);
@@ -1235,7 +1227,7 @@
 static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
         jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
     sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
-    if (messageQueue == NULL) {
+    if (messageQueue == nullptr) {
         jniThrowRuntimeException(env, "MessageQueue is not initialized.");
         return 0;
     }
@@ -1255,37 +1247,10 @@
     }
 }
 
-static void nativeSetVirtualDisplayViewports(JNIEnv* env, jclass /* clazz */, jlong ptr,
+static void nativeSetDisplayViewports(JNIEnv* env, jclass /* clazz */, jlong ptr,
         jobjectArray viewportObjArray) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
-    im->setVirtualDisplayViewports(env, viewportObjArray);
-}
-
-static void nativeSetDisplayViewport(JNIEnv* env, jclass /* clazz */, jlong ptr,
-        jint viewportType, jint displayId, jint orientation,
-        jint logicalLeft, jint logicalTop, jint logicalRight, jint logicalBottom,
-        jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom,
-        jint deviceWidth, jint deviceHeight, jstring uniqueId) {
-    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
-
-    DisplayViewport v;
-    v.displayId = displayId;
-    v.orientation = orientation;
-    v.logicalLeft = logicalLeft;
-    v.logicalTop = logicalTop;
-    v.logicalRight = logicalRight;
-    v.logicalBottom = logicalBottom;
-    v.physicalLeft = physicalLeft;
-    v.physicalTop = physicalTop;
-    v.physicalRight = physicalRight;
-    v.physicalBottom = physicalBottom;
-    v.deviceWidth = deviceWidth;
-    v.deviceHeight = deviceHeight;
-    if (uniqueId != nullptr) {
-        v.uniqueId = ScopedUtfChars(env, uniqueId).c_str();
-    }
-
-    im->setDisplayViewport(viewportType, v);
+    im->setDisplayViewports(env, viewportObjArray);
 }
 
 static jint nativeGetScanCodeState(JNIEnv* /* env */, jclass /* clazz */,
@@ -1316,8 +1281,8 @@
         jlong ptr, jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
-    uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
+    int32_t* codes = env->GetIntArrayElements(keyCodes, nullptr);
+    uint8_t* flags = env->GetBooleanArrayElements(outFlags, nullptr);
     jsize numCodes = env->GetArrayLength(keyCodes);
     jboolean result;
     if (numCodes == env->GetArrayLength(keyCodes)) {
@@ -1351,12 +1316,12 @@
 }
 
 static void nativeRegisterInputChannel(JNIEnv* env, jclass /* clazz */,
-        jlong ptr, jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
+        jlong ptr, jobject inputChannelObj, jobject inputWindowHandleObj, jint displayId) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
     sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
             inputChannelObj);
-    if (inputChannel == NULL) {
+    if (inputChannel == nullptr) {
         throwInputChannelNotInitialized(env);
         return;
     }
@@ -1365,7 +1330,7 @@
             android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
 
     status_t status = im->registerInputChannel(
-            env, inputChannel, inputWindowHandle, monitor);
+            env, inputChannel, inputWindowHandle, displayId);
     if (status) {
         std::string message;
         message += StringPrintf("Failed to register input channel.  status=%d", status);
@@ -1373,7 +1338,8 @@
         return;
     }
 
-    if (! monitor) {
+    // If inputWindowHandle is null and displayId >= 0, treat inputChannel as monitor.
+    if (inputWindowHandle != nullptr || displayId == ADISPLAY_ID_NONE) {
         android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
                 handleInputChannelDisposed, im);
     }
@@ -1385,12 +1351,12 @@
 
     sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
             inputChannelObj);
-    if (inputChannel == NULL) {
+    if (inputChannel == nullptr) {
         throwInputChannelNotInitialized(env);
         return;
     }
 
-    android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
+    android_view_InputChannel_setDisposeCallback(env, inputChannelObj, nullptr, nullptr);
 
     status_t status = im->unregisterInputChannel(env, inputChannel);
     if (status && status != BAD_VALUE) { // ignore already unregistered channel
@@ -1454,10 +1420,17 @@
 }
 
 static void nativeSetFocusedApplication(JNIEnv* env, jclass /* clazz */,
-        jlong ptr, jobject applicationHandleObj) {
+        jlong ptr, jint displayId, jobject applicationHandleObj) {
     NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
 
-    im->setFocusedApplication(env, applicationHandleObj);
+    im->setFocusedApplication(env, displayId, applicationHandleObj);
+}
+
+static void nativeSetFocusedDisplay(JNIEnv* env, jclass /* clazz */,
+        jlong ptr, jint displayId) {
+    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+    im->setFocusedDisplay(env, displayId);
 }
 
 static void nativeSetPointerCapture(JNIEnv* env, jclass /* clazz */, jlong ptr,
@@ -1490,7 +1463,7 @@
     sp<InputChannel> toChannel =
             android_view_InputChannel_getInputChannel(env, toChannelObj);
 
-    if (fromChannel == NULL || toChannel == NULL) {
+    if (fromChannel == nullptr || toChannel == nullptr) {
         return JNI_FALSE;
     }
 
@@ -1543,7 +1516,7 @@
     }
 
     jlong* patternMillis = static_cast<jlong*>(env->GetPrimitiveArrayCritical(
-            patternObj, NULL));
+            patternObj, nullptr));
     nsecs_t pattern[patternSize];
     for (size_t i = 0; i < patternSize; i++) {
         pattern[i] = max(jlong(0), min(patternMillis[i],
@@ -1656,10 +1629,8 @@
             (void*) nativeInit },
     { "nativeStart", "(J)V",
             (void*) nativeStart },
-    { "nativeSetVirtualDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V",
-            (void*) nativeSetVirtualDisplayViewports },
-    { "nativeSetDisplayViewport", "(JIIIIIIIIIIIIILjava/lang/String;)V",
-            (void*) nativeSetDisplayViewport },
+    { "nativeSetDisplayViewports", "(J[Landroid/hardware/display/DisplayViewport;)V",
+            (void*) nativeSetDisplayViewports },
     { "nativeGetScanCodeState", "(JIII)I",
             (void*) nativeGetScanCodeState },
     { "nativeGetKeyCodeState", "(JIII)I",
@@ -1669,7 +1640,7 @@
     { "nativeHasKeys", "(JII[I[Z)Z",
             (void*) nativeHasKeys },
     { "nativeRegisterInputChannel",
-            "(JLandroid/view/InputChannel;Lcom/android/server/input/InputWindowHandle;Z)V",
+            "(JLandroid/view/InputChannel;Lcom/android/server/input/InputWindowHandle;I)V",
             (void*) nativeRegisterInputChannel },
     { "nativeUnregisterInputChannel", "(JLandroid/view/InputChannel;)V",
             (void*) nativeUnregisterInputChannel },
@@ -1681,8 +1652,10 @@
             (void*) nativeToggleCapsLock },
     { "nativeSetInputWindows", "(J[Lcom/android/server/input/InputWindowHandle;I)V",
             (void*) nativeSetInputWindows },
-    { "nativeSetFocusedApplication", "(JLcom/android/server/input/InputApplicationHandle;)V",
+    { "nativeSetFocusedApplication", "(JILcom/android/server/input/InputApplicationHandle;)V",
             (void*) nativeSetFocusedApplication },
+    { "nativeSetFocusedDisplay", "(JI)V",
+            (void*) nativeSetFocusedDisplay },
     { "nativeSetPointerCapture", "(JZ)V",
             (void*) nativeSetPointerCapture },
     { "nativeSetInputDispatchMode", "(JZZ)V",
diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
index 3302dea..649f1a5 100644
--- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp
+++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp
@@ -30,8 +30,8 @@
 #include <utils/Log.h>
 
 #include "android-base/unique_fd.h"
-#include "bpf/BpfNetworkStats.h"
 #include "bpf/BpfUtils.h"
+#include "netdbpf/BpfNetworkStats.h"
 
 using android::bpf::Stats;
 using android::bpf::hasBpfSupport;
diff --git a/services/devicepolicy/Android.bp b/services/devicepolicy/Android.bp
index 0505204..47790ce 100644
--- a/services/devicepolicy/Android.bp
+++ b/services/devicepolicy/Android.bp
@@ -3,7 +3,6 @@
     srcs: ["java/**/*.java"],
 
     libs: [
-        "conscrypt",
         "services.core",
     ],
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
index 84de6b4..2dbbf55 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/BaseIDevicePolicyManager.java
@@ -15,20 +15,12 @@
  */
 package com.android.server.devicepolicy;
 
-import android.annotation.UserIdInt;
+import android.app.admin.DevicePolicyManager;
 import android.app.admin.IDevicePolicyManager;
 import android.content.ComponentName;
-import android.os.PersistableBundle;
-import android.security.keymaster.KeymasterCertificateChain;
-import android.security.keystore.ParcelableKeyGenParameterSpec;
-import android.telephony.data.ApnSetting;
 
 import com.android.server.SystemService;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * Defines the required interface for IDevicePolicyManager implemenation.
  *
@@ -64,94 +56,10 @@
      */
     abstract void handleStopUser(int userId);
 
-    public void setSystemSetting(ComponentName who, String setting, String value){}
-
-    public void transferOwnership(ComponentName admin, ComponentName target, PersistableBundle bundle) {}
-
-    public PersistableBundle getTransferOwnershipBundle() {
-        return null;
-    }
-
-    public boolean generateKeyPair(ComponentName who, String callerPackage, String algorithm,
-            ParcelableKeyGenParameterSpec keySpec, int idAttestationFlags,
-            KeymasterCertificateChain attestationChain) {
-        return false;
-    }
-
-    public boolean isUsingUnifiedPassword(ComponentName who) {
-        return true;
-    }
-
-    public boolean setKeyPairCertificate(ComponentName who, String callerPackage, String alias,
-            byte[] cert, byte[] chain, boolean isUserSelectable) {
-        return false;
-    }
-
-    @Override
-    public void setStartUserSessionMessage(
-            ComponentName admin, CharSequence startUserSessionMessage) {}
-
-    @Override
-    public void setEndUserSessionMessage(ComponentName admin, CharSequence endUserSessionMessage) {}
-
-    @Override
-    public String getStartUserSessionMessage(ComponentName admin) {
-        return null;
-    }
-
-    @Override
-    public String getEndUserSessionMessage(ComponentName admin) {
-        return null;
-    }
-
-    @Override
-    public List<String> setMeteredDataDisabledPackages(ComponentName admin, List<String> packageNames) {
-        return packageNames;
-    }
-
-    @Override
-    public List<String> getMeteredDataDisabledPackages(ComponentName admin) {
-        return new ArrayList<>();
-    }
-
-    @Override
-    public int addOverrideApn(ComponentName admin, ApnSetting apnSetting) {
-        return -1;
-    }
-
-    @Override
-    public boolean updateOverrideApn(ComponentName admin, int apnId, ApnSetting apnSetting) {
-        return false;
-    }
-
-    @Override
-    public boolean removeOverrideApn(ComponentName admin, int apnId) {
-        return false;
-    }
-
-    @Override
-    public List<ApnSetting> getOverrideApns(ComponentName admin) {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public void setOverrideApnsEnabled(ComponentName admin, boolean enabled) {}
-
-    @Override
-    public boolean isOverrideApnEnabled(ComponentName admin) {
-        return false;
-    }
-
     public void clearSystemUpdatePolicyFreezePeriodRecord() {
     }
 
     @Override
-    public boolean isMeteredDataDisabledPackageForUser(ComponentName admin,
-            String packageName, int userId) {
-        return false;
-    }
-
-    @Override
     public long forceNetworkLogs() {
         return 0;
     }
@@ -162,6 +70,22 @@
     }
 
     @Override
-    public void setDefaultSmsApplication(ComponentName admin, String packageName) {
+    public boolean checkDeviceIdentifierAccess(String packageName, int userHandle, int pid,
+            int uid) {
+        return false;
+    }
+
+    @Override
+    public void setGlobalPrivateDns(ComponentName who, int mode, String privateDnsHost) {
+    }
+
+    @Override
+    public int getGlobalPrivateDnsMode(ComponentName who) {
+        return DevicePolicyManager.PRIVATE_DNS_MODE_UNKNOWN;
+    }
+
+    @Override
+    public String getGlobalPrivateDnsHost(ComponentName who) {
+        return null;
     }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
index a8b9b0c..85ca52e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DeviceAdminServiceController.java
@@ -66,7 +66,8 @@
             super(TAG, mContext, mHandler, userId, componentName,
                     mConstants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC,
                     mConstants.DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE,
-                    mConstants.DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC);
+                    mConstants.DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC,
+                    mConstants.DAS_DIED_SERVICE_STABLE_CONNECTION_THRESHOLD_SEC);
         }
 
         @Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyConstants.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyConstants.java
index 616c669..71fea02 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyConstants.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyConstants.java
@@ -30,14 +30,17 @@
 public class DevicePolicyConstants {
     private static final String TAG = DevicePolicyManagerService.LOG_TAG;
 
-    private static final String DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC_KEY
-            = "das_died_service_reconnect_backoff_sec";
+    private static final String DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC_KEY =
+            "das_died_service_reconnect_backoff_sec";
 
-    private static final String DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE_KEY
-            = "das_died_service_reconnect_backoff_increase";
+    private static final String DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE_KEY =
+            "das_died_service_reconnect_backoff_increase";
 
-    private static final String DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC_KEY
-            = "das_died_service_reconnect_max_backoff_sec";
+    private static final String DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC_KEY =
+            "das_died_service_reconnect_max_backoff_sec";
+
+    private static final String DAS_DIED_SERVICE_STABLE_CONNECTION_THRESHOLD_SEC_KEY =
+            "das_died_service_stable_connection_threshold_sec";
 
     /**
      * The back-off before re-connecting, when a service binding died, due to the owner
@@ -55,6 +58,11 @@
      */
     public final long DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC;
 
+    /**
+     * If a connection lasts more than this duration, we reset the re-connect back-off time.
+     */
+    public final long DAS_DIED_SERVICE_STABLE_CONNECTION_THRESHOLD_SEC;
+
     private DevicePolicyConstants(String settings) {
 
         final KeyValueListParser parser = new KeyValueListParser(',');
@@ -75,6 +83,10 @@
         long dasDiedServiceReconnectMaxBackoffSec = parser.getLong(
                 DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC_KEY, TimeUnit.DAYS.toSeconds(1));
 
+        long dasDiedServiceStableConnectionThresholdSec = parser.getLong(
+                DAS_DIED_SERVICE_STABLE_CONNECTION_THRESHOLD_SEC_KEY,
+                TimeUnit.MINUTES.toSeconds(2));
+
         // Set minimum: 5 seconds.
         dasDiedServiceReconnectBackoffSec = Math.max(5, dasDiedServiceReconnectBackoffSec);
 
@@ -89,7 +101,8 @@
         DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC = dasDiedServiceReconnectBackoffSec;
         DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE = dasDiedServiceReconnectBackoffIncrease;
         DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC = dasDiedServiceReconnectMaxBackoffSec;
-
+        DAS_DIED_SERVICE_STABLE_CONNECTION_THRESHOLD_SEC =
+                dasDiedServiceStableConnectionThresholdSec;
     }
 
     public static DevicePolicyConstants loadFromString(String settings) {
@@ -102,14 +115,18 @@
 
         pw.print(prefix);
         pw.print("  DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC: ");
-        pw.println( DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC);
+        pw.println(DAS_DIED_SERVICE_RECONNECT_BACKOFF_SEC);
 
         pw.print(prefix);
         pw.print("  DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE: ");
-        pw.println( DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE);
+        pw.println(DAS_DIED_SERVICE_RECONNECT_BACKOFF_INCREASE);
 
         pw.print(prefix);
         pw.print("  DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC: ");
-        pw.println( DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC);
+        pw.println(DAS_DIED_SERVICE_RECONNECT_MAX_BACKOFF_SEC);
+
+        pw.print(prefix);
+        pw.print("  DAS_DIED_SERVICE_STABLE_CONNECTION_THRESHOLD_SEC: ");
+        pw.println(DAS_DIED_SERVICE_STABLE_CONNECTION_THRESHOLD_SEC);
     }
 }
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index eeb4ad3..b88165e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -55,12 +55,18 @@
 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_UNKNOWN;
+import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OFF;
+import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
 import static android.app.admin.DevicePolicyManager.PROFILE_KEYGUARD_FEATURES_AFFECT_OWNER;
 import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
 import static android.app.admin.DevicePolicyManager.WIPE_EXTERNAL_STORAGE;
 import static android.app.admin.DevicePolicyManager.WIPE_RESET_PROTECTION_DATA;
 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
 
+import static android.provider.Settings.Global.PRIVATE_DNS_MODE;
+import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
 import static android.provider.Telephony.Carriers.DPC_URI;
 import static android.provider.Telephony.Carriers.ENFORCE_KEY;
 import static android.provider.Telephony.Carriers.ENFORCE_MANAGED_URI;
@@ -145,6 +151,7 @@
 import android.media.IAudioService;
 import android.net.ConnectivityManager;
 import android.net.IIpConnectivityMetrics;
+import android.net.NetworkUtils;
 import android.net.ProxyInfo;
 import android.net.Uri;
 import android.net.metrics.IpConnectivityLog;
@@ -199,6 +206,7 @@
 import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.StatsLog;
 import android.util.Xml;
 import android.view.IWindowManager;
 import android.view.accessibility.AccessibilityManager;
@@ -395,6 +403,8 @@
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_SLEEP_POLICY);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.STAY_ON_WHILE_PLUGGED_IN);
         GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN);
+        GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.PRIVATE_DNS_MODE);
+        GLOBAL_SETTINGS_WHITELIST.add(Settings.Global.PRIVATE_DNS_SPECIFIER);
 
         GLOBAL_SETTINGS_DEPRECATED = new ArraySet<>();
         GLOBAL_SETTINGS_DEPRECATED.add(Settings.Global.BLUETOOTH_ON);
@@ -7861,6 +7871,35 @@
         return getApplicationLabel(profileOwner.getPackageName(), userHandle);
     }
 
+    @Override
+    public boolean checkDeviceIdentifierAccess(String packageName, int userHandle, int pid,
+            int uid) {
+        // If the caller is not a system app then it should only be able to check its own device
+        // identifier access.
+        int callingAppId = UserHandle.getAppId(mInjector.binderGetCallingUid());
+        if (callingAppId >= Process.FIRST_APPLICATION_UID
+                && callingAppId != UserHandle.getAppId(uid)) {
+            return false;
+        }
+        // A device or profile owner must also have the READ_PHONE_STATE permission to access device
+        // identifiers. If the package being checked does not have this permission then deny access.
+        if (mContext.checkPermission(android.Manifest.permission.READ_PHONE_STATE, pid, uid)
+                != PackageManager.PERMISSION_GRANTED) {
+            return false;
+        }
+        // Allow access to the device owner.
+        ComponentName deviceOwner = getDeviceOwnerComponent(true);
+        if (deviceOwner != null && deviceOwner.getPackageName().equals(packageName)) {
+            return true;
+        }
+        // Allow access to the profile owner for the specified user.
+        ComponentName profileOwner = getProfileOwnerAsUser(userHandle);
+        if (profileOwner != null && profileOwner.getPackageName().equals(packageName)) {
+            return true;
+        }
+        return false;
+    }
+
     /**
      * Canonical name for a given package.
      */
@@ -9349,6 +9388,7 @@
             }
             saveUserRestrictionsLocked(userHandle);
         }
+        StatsLog.write(StatsLog.USER_RESTRICTION_CHANGED, key, enabledFromThisOwner);
         if (SecurityLog.isLoggingEnabled()) {
             final int eventTag = enabledFromThisOwner
                     ? SecurityLog.TAG_USER_RESTRICTION_ADDED
@@ -13099,4 +13139,78 @@
     private static String getManagedProvisioningPackage(Context context) {
         return context.getResources().getString(R.string.config_managed_provisioning_package);
     }
+
+    private void putPrivateDnsSettings(@Nullable String mode, @Nullable String host) {
+        // Set Private DNS settings using system permissions, as apps cannot write
+        // to global settings.
+        long origId = mInjector.binderClearCallingIdentity();
+        try {
+            mInjector.settingsGlobalPutString(PRIVATE_DNS_MODE, mode);
+            mInjector.settingsGlobalPutString(PRIVATE_DNS_SPECIFIER, host);
+        } finally {
+            mInjector.binderRestoreCallingIdentity(origId);
+        }
+    }
+
+    @Override
+    public void setGlobalPrivateDns(@NonNull ComponentName who, int mode, String privateDnsHost) {
+        if (!mHasFeature) {
+            return;
+        }
+
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        enforceDeviceOwner(who);
+
+        switch (mode) {
+            case PRIVATE_DNS_MODE_OPPORTUNISTIC:
+                if (!TextUtils.isEmpty(privateDnsHost)) {
+                    throw new IllegalArgumentException("A DNS host should not be provided when " +
+                            "setting opportunistic mode.");
+                }
+                putPrivateDnsSettings(ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC, null);
+                break;
+            case PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
+                if (!NetworkUtils.isWeaklyValidatedHostname(privateDnsHost)) {
+                    throw new IllegalArgumentException(
+                            String.format("Provided hostname is not valid: %s", privateDnsHost));
+                }
+                putPrivateDnsSettings(ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME,
+                        privateDnsHost);
+                break;
+            default:
+                throw new IllegalArgumentException(String.format("Unsupported mode: %d", mode));
+        }
+    }
+
+    @Override
+    public int getGlobalPrivateDnsMode(@NonNull ComponentName who) {
+        if (!mHasFeature) {
+            return PRIVATE_DNS_MODE_UNKNOWN;
+        }
+
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        enforceDeviceOwner(who);
+        switch (mInjector.settingsGlobalGetString(PRIVATE_DNS_MODE)) {
+            case ConnectivityManager.PRIVATE_DNS_MODE_OFF:
+                return PRIVATE_DNS_MODE_OFF;
+            case ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC:
+                return PRIVATE_DNS_MODE_OPPORTUNISTIC;
+            case ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME:
+                return PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+        }
+
+        return PRIVATE_DNS_MODE_UNKNOWN;
+    }
+
+    @Override
+    public String getGlobalPrivateDnsHost(@NonNull ComponentName who) {
+        if (!mHasFeature) {
+            return null;
+        }
+
+        Preconditions.checkNotNull(who, "ComponentName is null");
+        enforceDeviceOwner(who);
+
+        return mInjector.settingsGlobalGetString(PRIVATE_DNS_SPECIFIER);
+    }
 }
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index b8241d0..bbc4f44 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -359,7 +359,7 @@
             // The system server should never make non-oneway calls
             Binder.setWarnOnBlocking(true);
             // The system server should always load safe labels
-            PackageItemInfo.setForceSafeLabels(true);
+            PackageItemInfo.forceSafeLabels();
 
             // Default to FULL within the system server.
             SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL;
@@ -468,6 +468,12 @@
             }
         }
 
+        // Diagnostic to ensure that the system is in a base healthy state. Done here as a common
+        // non-zygote process.
+        if (!VMRuntime.hasBootImageSpaces()) {
+            Slog.wtf(TAG, "Runtime is not running with a boot image!");
+        }
+
         // Loop forever.
         Looper.loop();
         throw new RuntimeException("Main thread loop unexpectedly exited");
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index 77a3e21..6ba7d94 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -1,5 +1,8 @@
 package android.net.dhcp;
 
+import static android.net.util.NetworkConstants.IPV4_MAX_MTU;
+import static android.net.util.NetworkConstants.IPV4_MIN_MTU;
+
 import android.annotation.Nullable;
 import android.net.DhcpResults;
 import android.net.LinkAddress;
@@ -381,6 +384,26 @@
     }
 
     /**
+     * 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.
@@ -696,7 +719,11 @@
         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);
+        }
     }
 
     /**
@@ -1259,7 +1286,8 @@
         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, boolean metered) {
+        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);
@@ -1267,9 +1295,11 @@
         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;
         }
@@ -1283,7 +1313,8 @@
         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, boolean metered) {
+        Inet4Address dhcpServerIdentifier, String domainName, String hostname, boolean metered,
+        short mtu) {
         DhcpPacket pkt = new DhcpAckPacket(
                 transactionId, (short) 0, broadcast, serverIpAddr, relayIp, requestClientIp, yourIp,
                 mac);
@@ -1291,9 +1322,11 @@
         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;
         }
diff --git a/services/net/java/android/net/dhcp/DhcpServer.java b/services/net/java/android/net/dhcp/DhcpServer.java
index 2b3d577..cee6fa9 100644
--- a/services/net/java/android/net/dhcp/DhcpServer.java
+++ b/services/net/java/android/net/dhcp/DhcpServer.java
@@ -20,6 +20,7 @@
 import static android.net.NetworkUtils.getPrefixMaskAsInet4Address;
 import static android.net.TrafficStats.TAG_SYSTEM_DHCP_SERVER;
 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.DhcpPacket.INFINITE_LEASE;
@@ -46,6 +47,7 @@
 import android.os.SystemClock;
 import android.system.ErrnoException;
 import android.system.Os;
+import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.HexDump;
@@ -350,6 +352,19 @@
         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);
@@ -358,12 +373,14 @@
                 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 */, mServingParams.metered);
+                mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
+                mServingParams.metered, (short) mServingParams.linkMtu);
 
         return transmitOfferOrAckPacket(offerPacket, request, lease, clientMac, broadcastFlag);
     }
@@ -374,13 +391,15 @@
         // 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 */, mServingParams.metered);
+                mServingParams.getServerInet4Addr(), null /* domainName */, hostname,
+                mServingParams.metered, (short) mServingParams.linkMtu);
 
         return transmitOfferOrAckPacket(ackPacket, request, lease, clientMac, broadcastFlag);
     }
diff --git a/services/net/java/android/net/ip/IpNeighborMonitor.java b/services/net/java/android/net/ip/IpNeighborMonitor.java
index fc07aa1..9512f1b 100644
--- a/services/net/java/android/net/ip/IpNeighborMonitor.java
+++ b/services/net/java/android/net/ip/IpNeighborMonitor.java
@@ -40,7 +40,6 @@
 import com.android.internal.util.BitUtils;
 
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.FileDescriptor;
 import java.net.InetAddress;
diff --git a/services/net/java/android/net/ip/RouterAdvertisementDaemon.java b/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
index 9d686ef..d197d01 100644
--- a/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
+++ b/services/net/java/android/net/ip/RouterAdvertisementDaemon.java
@@ -28,7 +28,6 @@
 import android.net.util.InterfaceParams;
 import android.system.ErrnoException;
 import android.system.Os;
-import android.system.StructGroupReq;
 import android.system.StructTimeval;
 import android.util.Log;
 
diff --git a/services/net/java/android/net/netlink/NetlinkSocket.java b/services/net/java/android/net/netlink/NetlinkSocket.java
index cfcba3a..40098c1 100644
--- a/services/net/java/android/net/netlink/NetlinkSocket.java
+++ b/services/net/java/android/net/netlink/NetlinkSocket.java
@@ -32,7 +32,6 @@
 import android.system.StructTimeval;
 import android.util.Log;
 import libcore.io.IoUtils;
-import libcore.io.Libcore;
 
 import java.io.FileDescriptor;
 import java.io.InterruptedIOException;
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
index 78c0be4..e67f8d3 100644
--- a/services/robotests/Android.mk
+++ b/services/robotests/Android.mk
@@ -84,7 +84,7 @@
 
 LOCAL_JAVA_LIBRARIES := \
     junit \
-    platform-robolectric-3.6.1-prebuilt
+    platform-robolectric-3.6.2-prebuilt
 
 LOCAL_INSTRUMENTATION_FOR := FrameworksServicesLib
 LOCAL_MODULE := FrameworksServicesRoboTests
@@ -109,4 +109,4 @@
 
 LOCAL_INSTRUMENT_SOURCE_DIRS := $(dir $(LOCAL_PATH))backup/java
 
-include prebuilts/misc/common/robolectric/3.6.1/run_robotests.mk
+include prebuilts/misc/common/robolectric/3.6.2/run_robotests.mk
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java
new file mode 100644
index 0000000..c5f9b10
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/EncryptedChunkTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package 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.chunk.ChunkHash;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import com.google.common.primitives.Bytes;
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class EncryptedChunkTest {
+    private static final byte[] CHUNK_HASH_1_BYTES =
+            Arrays.copyOf(new byte[] {1}, ChunkHash.HASH_LENGTH_BYTES);
+    private static final byte[] NONCE_1 =
+            Arrays.copyOf(new byte[] {2}, EncryptedChunk.NONCE_LENGTH_BYTES);
+    private static final byte[] ENCRYPTED_BYTES_1 =
+            Arrays.copyOf(new byte[] {3}, EncryptedChunk.KEY_LENGTH_BYTES);
+
+    private static final byte[] CHUNK_HASH_2_BYTES =
+            Arrays.copyOf(new byte[] {4}, ChunkHash.HASH_LENGTH_BYTES);
+    private static final byte[] NONCE_2 =
+            Arrays.copyOf(new byte[] {5}, EncryptedChunk.NONCE_LENGTH_BYTES);
+    private static final byte[] ENCRYPTED_BYTES_2 =
+            Arrays.copyOf(new byte[] {6}, EncryptedChunk.KEY_LENGTH_BYTES);
+
+    @Test
+    public void testCreate_withIncorrectLength_throwsException() {
+        ChunkHash chunkHash = new ChunkHash(CHUNK_HASH_1_BYTES);
+        byte[] shortNonce = Arrays.copyOf(new byte[] {2}, EncryptedChunk.NONCE_LENGTH_BYTES - 1);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> EncryptedChunk.create(chunkHash, shortNonce, ENCRYPTED_BYTES_1));
+    }
+
+    @Test
+    public void testEncryptedBytes_forNewlyCreatedObject_returnsCorrectValue() {
+        ChunkHash chunkHash = new ChunkHash(CHUNK_HASH_1_BYTES);
+        EncryptedChunk encryptedChunk =
+                EncryptedChunk.create(chunkHash, NONCE_1, ENCRYPTED_BYTES_1);
+
+        byte[] returnedBytes = encryptedChunk.encryptedBytes();
+
+        assertThat(returnedBytes)
+                .asList()
+                .containsExactlyElementsIn(Bytes.asList(ENCRYPTED_BYTES_1))
+                .inOrder();
+    }
+
+    @Test
+    public void testKey_forNewlyCreatedObject_returnsCorrectValue() {
+        ChunkHash chunkHash = new ChunkHash(CHUNK_HASH_1_BYTES);
+        EncryptedChunk encryptedChunk =
+                EncryptedChunk.create(chunkHash, NONCE_1, ENCRYPTED_BYTES_1);
+
+        ChunkHash returnedKey = encryptedChunk.key();
+
+        assertThat(returnedKey).isEqualTo(chunkHash);
+    }
+
+    @Test
+    public void testNonce_forNewlycreatedObject_returnCorrectValue() {
+        ChunkHash chunkHash = new ChunkHash(CHUNK_HASH_1_BYTES);
+        EncryptedChunk encryptedChunk =
+                EncryptedChunk.create(chunkHash, NONCE_1, ENCRYPTED_BYTES_1);
+
+        byte[] returnedNonce = encryptedChunk.nonce();
+
+        assertThat(returnedNonce).asList().containsExactlyElementsIn(Bytes.asList(NONCE_1));
+    }
+
+    @Test
+    public void testEquals() {
+        ChunkHash chunkHash1 = new ChunkHash(CHUNK_HASH_1_BYTES);
+        ChunkHash equalChunkHash1 = new ChunkHash(CHUNK_HASH_1_BYTES);
+        ChunkHash chunkHash2 = new ChunkHash(CHUNK_HASH_2_BYTES);
+        EncryptedChunk encryptedChunk1 =
+                EncryptedChunk.create(chunkHash1, NONCE_1, ENCRYPTED_BYTES_1);
+        EncryptedChunk equalEncryptedChunk1 =
+                EncryptedChunk.create(equalChunkHash1, NONCE_1, ENCRYPTED_BYTES_1);
+        EncryptedChunk encryptedChunk2 =
+                EncryptedChunk.create(chunkHash2, NONCE_2, ENCRYPTED_BYTES_2);
+
+        assertThat(encryptedChunk1).isEqualTo(equalEncryptedChunk1);
+        assertThat(encryptedChunk1).isNotEqualTo(encryptedChunk2);
+    }
+
+    @Test
+    public void testHashCode() {
+        ChunkHash chunkHash1 = new ChunkHash(CHUNK_HASH_1_BYTES);
+        ChunkHash equalChunkHash1 = new ChunkHash(CHUNK_HASH_1_BYTES);
+        ChunkHash chunkHash2 = new ChunkHash(CHUNK_HASH_2_BYTES);
+        EncryptedChunk encryptedChunk1 =
+                EncryptedChunk.create(chunkHash1, NONCE_1, ENCRYPTED_BYTES_1);
+        EncryptedChunk equalEncryptedChunk1 =
+                EncryptedChunk.create(equalChunkHash1, NONCE_1, ENCRYPTED_BYTES_1);
+        EncryptedChunk encryptedChunk2 =
+                EncryptedChunk.create(chunkHash2, NONCE_2, ENCRYPTED_BYTES_2);
+
+        int hash1 = encryptedChunk1.hashCode();
+        int equalHash1 = equalEncryptedChunk1.hashCode();
+        int hash2 = encryptedChunk2.hashCode();
+
+        assertThat(hash1).isEqualTo(equalHash1);
+        assertThat(hash1).isNotEqualTo(hash2);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java
new file mode 100644
index 0000000..b162557
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/InlineLengthsEncryptedChunkEncoderTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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.backup.encryption.chunking;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+
+import android.platform.test.annotations.Presubmit;
+import com.android.server.backup.encryption.chunk.ChunkHash;
+import com.android.server.backup.encryption.chunk.ChunksMetadataProto;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class InlineLengthsEncryptedChunkEncoderTest {
+
+    private static final byte[] TEST_NONCE =
+            Arrays.copyOf(new byte[] {1}, EncryptedChunk.NONCE_LENGTH_BYTES);
+    private static final byte[] TEST_KEY_DATA =
+            Arrays.copyOf(new byte[] {2}, EncryptedChunk.KEY_LENGTH_BYTES);
+    private static final byte[] TEST_DATA = {5, 4, 5, 7, 10, 12, 1, 2, 9};
+
+    @Mock private BackupWriter mMockBackupWriter;
+    private ChunkHash mTestKey;
+    private EncryptedChunk mTestChunk;
+    private EncryptedChunkEncoder mEncoder;
+
+    @Before
+    public void setUp() throws Exception {
+        mMockBackupWriter = mock(BackupWriter.class);
+        mTestKey = new ChunkHash(TEST_KEY_DATA);
+        mTestChunk = EncryptedChunk.create(mTestKey, TEST_NONCE, TEST_DATA);
+        mEncoder = new InlineLengthsEncryptedChunkEncoder();
+    }
+
+    @Test
+    public void writeChunkToWriter_writesLengthThenNonceThenData() throws Exception {
+        mEncoder.writeChunkToWriter(mMockBackupWriter, mTestChunk);
+
+        InOrder inOrder = inOrder(mMockBackupWriter);
+        inOrder.verify(mMockBackupWriter)
+                .writeBytes(
+                        InlineLengthsEncryptedChunkEncoder.toByteArray(
+                                TEST_NONCE.length + TEST_DATA.length));
+        inOrder.verify(mMockBackupWriter).writeBytes(TEST_NONCE);
+        inOrder.verify(mMockBackupWriter).writeBytes(TEST_DATA);
+    }
+
+    @Test
+    public void getEncodedLengthOfChunk_returnsSumOfNonceAndDataLengths() {
+        int encodedLength = mEncoder.getEncodedLengthOfChunk(mTestChunk);
+
+        assertThat(encodedLength).isEqualTo(Integer.BYTES + TEST_NONCE.length + TEST_DATA.length);
+    }
+
+    @Test
+    public void getChunkOrderingType_returnsExplicitStartsType() {
+        assertThat(mEncoder.getChunkOrderingType()).isEqualTo(ChunksMetadataProto.INLINE_LENGTHS);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java b/services/robotests/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java
new file mode 100644
index 0000000..b61dbe9
--- /dev/null
+++ b/services/robotests/src/com/android/server/backup/encryption/chunking/LengthlessEncryptedChunkEncoderTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.backup.encryption.chunking;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+
+import android.platform.test.annotations.Presubmit;
+import com.android.server.backup.encryption.chunk.ChunkHash;
+import com.android.server.backup.encryption.chunk.ChunksMetadataProto;
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.robolectric.annotation.Config;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"com.android.server.backup"})
+@Presubmit
+public class LengthlessEncryptedChunkEncoderTest {
+    private static final byte[] TEST_NONCE =
+            Arrays.copyOf(new byte[] {1}, EncryptedChunk.NONCE_LENGTH_BYTES);
+    private static final byte[] TEST_KEY_DATA =
+            Arrays.copyOf(new byte[] {2}, EncryptedChunk.KEY_LENGTH_BYTES);
+    private static final byte[] TEST_DATA = {5, 4, 5, 7, 10, 12, 1, 2, 9};
+
+    @Mock private BackupWriter mMockBackupWriter;
+    private ChunkHash mTestKey;
+    private EncryptedChunk mTestChunk;
+    private EncryptedChunkEncoder mEncoder;
+
+    @Before
+    public void setUp() throws Exception {
+        mMockBackupWriter = mock(BackupWriter.class);
+        mTestKey = new ChunkHash(TEST_KEY_DATA);
+        mTestChunk = EncryptedChunk.create(mTestKey, TEST_NONCE, TEST_DATA);
+        mEncoder = new LengthlessEncryptedChunkEncoder();
+    }
+
+    @Test
+    public void writeChunkToWriter_writesNonceThenData() throws Exception {
+        mEncoder.writeChunkToWriter(mMockBackupWriter, mTestChunk);
+
+        InOrder inOrder = inOrder(mMockBackupWriter);
+        inOrder.verify(mMockBackupWriter).writeBytes(TEST_NONCE);
+        inOrder.verify(mMockBackupWriter).writeBytes(TEST_DATA);
+    }
+
+    @Test
+    public void getEncodedLengthOfChunk_returnsSumOfNonceAndDataLengths() {
+        int encodedLength = mEncoder.getEncodedLengthOfChunk(mTestChunk);
+
+        assertThat(encodedLength).isEqualTo(TEST_NONCE.length + TEST_DATA.length);
+    }
+
+    @Test
+    public void getChunkOrderingType_returnsExplicitStartsType() throws Exception {
+        assertThat(mEncoder.getChunkOrderingType()).isEqualTo(ChunksMetadataProto.EXPLICIT_STARTS);
+    }
+}
diff --git a/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java b/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
index 112e1e3..b771039 100644
--- a/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
+++ b/services/robotests/src/com/android/server/backup/fullbackup/AppMetadataBackupWriterTest.java
@@ -183,7 +183,6 @@
                                 new Signature[] {new Signature("1234"), new Signature("5678")},
                                 SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                                 null,
-                                null,
                                 null));
         File manifestFile = createFile(BACKUP_MANIFEST_FILENAME);
 
diff --git a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
index fb57d68..ba1d83e 100644
--- a/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/keyvalue/KeyValueBackupTaskTest.java
@@ -726,6 +726,39 @@
     }
 
     @Test
+    public void testRunTask_whenSecondAgentUnavailable_commitsFirstAgentState() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        AgentMock agentMock = setUpAgent(PACKAGE_1);
+        setUpAgent(PACKAGE_2.unavailable());
+        agentOnBackupDo(
+                agentMock,
+                (oldState, dataOutput, newState) -> {
+                    writeData(dataOutput, "key", "data".getBytes());
+                    writeState(newState, "newState".getBytes());
+                });
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, PACKAGE_1, PACKAGE_2);
+
+        runTask(task);
+
+        assertThat(Files.readAllBytes(getStateFile(mTransport, PACKAGE_1))).isEqualTo(
+                "newState".getBytes());
+    }
+
+    @Test
+    public void testRunTask_whenNonIncrementalAndAgentUnavailable() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1.unavailable());
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true, PACKAGE_1);
+
+        runTask(task);
+
+        verify(mBackupManagerService).setWorkSource(null);
+        verify(mObserver).onResult(PACKAGE_1.packageName, ERROR_AGENT_FAILURE);
+        verify(mObserver).backupFinished(BackupManager.SUCCESS);
+        assertBackupPendingFor(PACKAGE_1);
+    }
+
+    @Test
     public void testRunTask_whenBindToAgentThrowsSecurityException() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         setUpAgent(PACKAGE_1);
@@ -743,6 +776,23 @@
     }
 
     @Test
+    public void testRunTask_whenNonIncrementalAndBindToAgentThrowsSecurityException() throws Exception {
+        TransportMock transportMock = setUpInitializedTransport(mTransport);
+        setUpAgent(PACKAGE_1);
+        doThrow(SecurityException.class)
+                .when(mBackupManagerService)
+                .bindToAgentSynchronous(argThat(applicationInfo(PACKAGE_1)), anyInt());
+        KeyValueBackupTask task = createKeyValueBackupTask(transportMock, true, PACKAGE_1);
+
+        runTask(task);
+
+        verify(mBackupManagerService).setWorkSource(null);
+        verify(mObserver).onResult(PACKAGE_1.packageName, ERROR_AGENT_FAILURE);
+        verify(mObserver).backupFinished(BackupManager.SUCCESS);
+        assertBackupPendingFor(PACKAGE_1);
+    }
+
+    @Test
     public void testRunTask_whenTransportGetBackupQuotaThrows_notifiesCorrectly() throws Exception {
         TransportMock transportMock = setUpInitializedTransport(mTransport);
         when(transportMock.transport.getBackupQuota(PACKAGE_1.packageName, false))
@@ -2630,9 +2680,7 @@
         return Files.createTempFile(mContext.getCacheDir().toPath(), "backup", ".tmp");
     }
 
-    private static IterableSubject<
-                    ? extends IterableSubject<?, Path, Iterable<Path>>, Path, Iterable<Path>>
-            assertDirectory(Path directory) throws IOException {
+    private static IterableSubject assertDirectory(Path directory) throws IOException {
         return assertThat(oneTimeIterable(Files.newDirectoryStream(directory).iterator()))
                 .named("directory " + directory);
     }
diff --git a/services/tests/mockingservicestests/Android.mk b/services/tests/mockingservicestests/Android.mk
index 8c02833..b21b3e4 100644
--- a/services/tests/mockingservicestests/Android.mk
+++ b/services/tests/mockingservicestests/Android.mk
@@ -20,13 +20,11 @@
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    frameworks-base-testutils \
     services.core \
-    androidx-test \
+    services.net \
+    androidx.test.runner \
     mockito-target-extended-minus-junit4 \
     platform-test-annotations \
-    ShortcutManagerTestUtils \
-    truth-prebuilt \
 
 LOCAL_JAVA_LIBRARIES := android.test.mock android.test.base android.test.runner
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index de3d285..f85ffc8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -30,10 +30,20 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.timeout;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_LONG_TIME;
+import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_SHORT_TIME;
+import static com.android.server.AlarmManagerService.Constants
+        .KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
+import static com.android.server.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
+import static com.android.server.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
+import static com.android.server.AlarmManagerService.Constants.KEY_MIN_FUTURITY;
+import static com.android.server.AlarmManagerService.Constants.KEY_MIN_INTERVAL;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
@@ -45,6 +55,7 @@
 import android.app.IUidObserver;
 import android.app.PendingIntent;
 import android.app.usage.UsageStatsManagerInternal;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.os.Handler;
@@ -52,12 +63,16 @@
 import android.os.PowerManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Log;
+import android.util.SparseArray;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.internal.annotations.GuardedBy;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -66,8 +81,9 @@
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
 
-import javax.annotation.concurrent.GuardedBy;
+import java.util.ArrayList;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -80,6 +96,8 @@
 
     private AlarmManagerService mService;
     @Mock
+    private ContentResolver mMockResolver;
+    @Mock
     private IActivityManager mIActivityManager;
     @Mock
     private UsageStatsManagerInternal mUsageStatsManagerInternal;
@@ -186,9 +204,11 @@
     public final void setUp() throws Exception {
         mMockingSession = mockitoSession()
                 .initMocks(this)
-                .mockStatic(ActivityManager.class, Answers.CALLS_REAL_METHODS)
+                .spyStatic(ActivityManager.class)
                 .mockStatic(LocalServices.class)
-                .mockStatic(Looper.class, Answers.CALLS_REAL_METHODS)
+                .spyStatic(Looper.class)
+                .spyStatic(Settings.Global.class)
+                .strictness(Strictness.WARN)
                 .startMocking();
         doReturn(mIActivityManager).when(ActivityManager::getService);
         doReturn(mAppStateTracker).when(() -> LocalServices.getService(AppStateTracker.class));
@@ -201,15 +221,19 @@
                 .thenReturn(STANDBY_BUCKET_ACTIVE);
         doReturn(Looper.getMainLooper()).when(Looper::myLooper);
 
-        final Context context = InstrumentationRegistry.getTargetContext();
-        mInjector = spy(new Injector(context));
+        final Context context = spy(InstrumentationRegistry.getTargetContext());
+        when(context.getContentResolver()).thenReturn(mMockResolver);
+        doNothing().when(mMockResolver).registerContentObserver(any(), anyBoolean(), any());
+        doReturn("min_futurity=0").when(() ->
+                Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS));
+        mInjector = new Injector(context);
         mService = new AlarmManagerService(context, mInjector);
         spyOn(mService);
         doNothing().when(mService).publishBinderService(any(), any());
         mService.onStart();
         mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
-        mService.mConstants.MIN_FUTURITY = 0;
 
+        assertEquals(0, mService.mConstants.MIN_FUTURITY);
         assertEquals(mService.mSystemUiUid, SYSTEM_UI_UID);
         assertEquals(mService.mClockReceiver, mClockReceiver);
         assertEquals(mService.mWakeLock, mWakeLock);
@@ -235,7 +259,6 @@
         final long triggerTime = mNowElapsedTest + 5000;
         final PendingIntent alarmPi = getNewMockPendingIntent();
         setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, alarmPi);
-        verify(mInjector).setAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime);
         assertEquals(triggerTime, mTestTimer.getElapsed());
     }
 
@@ -257,12 +280,45 @@
     }
 
     @Test
+    public void testUpdateConstants() {
+        final StringBuilder constantsBuilder = new StringBuilder();
+        constantsBuilder.append(KEY_MIN_FUTURITY);
+        constantsBuilder.append("=5,");
+        constantsBuilder.append(KEY_MIN_INTERVAL);
+        constantsBuilder.append("=10,");
+        constantsBuilder.append(KEY_MAX_INTERVAL);
+        constantsBuilder.append("=15,");
+        constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_SHORT_TIME);
+        constantsBuilder.append("=20,");
+        constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_LONG_TIME);
+        constantsBuilder.append("=25,");
+        constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION);
+        constantsBuilder.append("=30,");
+        constantsBuilder.append(KEY_LISTENER_TIMEOUT);
+        constantsBuilder.append("=35,");
+
+        doReturn(constantsBuilder.toString()).when(() -> Settings.Global.getString(mMockResolver,
+                Settings.Global.ALARM_MANAGER_CONSTANTS));
+        mService.mConstants.onChange(false, null);
+        assertEquals(5, mService.mConstants.MIN_FUTURITY);
+        assertEquals(10, mService.mConstants.MIN_INTERVAL);
+        assertEquals(15, mService.mConstants.MAX_INTERVAL);
+        assertEquals(20, mService.mConstants.ALLOW_WHILE_IDLE_SHORT_TIME);
+        assertEquals(25, mService.mConstants.ALLOW_WHILE_IDLE_LONG_TIME);
+        assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION);
+        assertEquals(35, mService.mConstants.LISTENER_TIMEOUT);
+    }
+
+    @Test
     public void testMinFuturity() {
-        mService.mConstants.MIN_FUTURITY = 10;
+        doReturn("min_futurity=10").when(() ->
+                Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS));
+        mService.mConstants.onChange(false, null);
+        assertEquals(10, mService.mConstants.MIN_FUTURITY);
         final long triggerTime = mNowElapsedTest + 1;
         final long expectedTriggerTime = mNowElapsedTest + mService.mConstants.MIN_FUTURITY;
         setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, getNewMockPendingIntent());
-        verify(mInjector).setAlarm(ELAPSED_REALTIME_WAKEUP, expectedTriggerTime);
+        assertEquals(expectedTriggerTime, mTestTimer.getElapsed());
     }
 
     @Test
@@ -344,6 +400,31 @@
                 () -> (mTestTimer.getElapsed() == expectedNextTrigger)));
     }
 
+    @Test
+    public void testAlarmRestrictedInBatterSaver() throws PendingIntent.CanceledException {
+        final ArgumentCaptor<AppStateTracker.Listener> listenerArgumentCaptor =
+                ArgumentCaptor.forClass(AppStateTracker.Listener.class);
+        verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture());
+
+        final PendingIntent alarmPi = getNewMockPendingIntent();
+        when(mAppStateTracker.areAlarmsRestricted(TEST_CALLING_UID, TEST_CALLING_PACKAGE,
+                false)).thenReturn(true);
+        setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 2, alarmPi);
+        assertEquals(mNowElapsedTest + 2, mTestTimer.getElapsed());
+
+        final SparseArray<ArrayList<AlarmManagerService.Alarm>> restrictedAlarms =
+                mService.mPendingBackgroundAlarms;
+        assertNull(restrictedAlarms.get(TEST_CALLING_UID));
+
+        mNowElapsedTest = mTestTimer.expire();
+        pollingCheck(DEFAULT_TIMEOUT, () -> (restrictedAlarms.get(TEST_CALLING_UID) != null));
+
+        listenerArgumentCaptor.getValue().unblockAlarmsForUid(TEST_CALLING_UID);
+        verify(alarmPi).send(any(Context.class), eq(0), any(Intent.class), any(),
+                any(Handler.class), isNull(), any());
+        assertNull(restrictedAlarms.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
new file mode 100644
index 0000000..04a8408
--- /dev/null
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -0,0 +1,1557 @@
+/*
+ * 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 androidx.test.InstrumentationRegistry.getContext;
+
+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.mockitoSession;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static com.android.server.DeviceIdleController.LIGHT_STATE_ACTIVE;
+import static com.android.server.DeviceIdleController.LIGHT_STATE_IDLE;
+import static com.android.server.DeviceIdleController.LIGHT_STATE_IDLE_MAINTENANCE;
+import static com.android.server.DeviceIdleController.LIGHT_STATE_INACTIVE;
+import static com.android.server.DeviceIdleController.LIGHT_STATE_OVERRIDE;
+import static com.android.server.DeviceIdleController.LIGHT_STATE_PRE_IDLE;
+import static com.android.server.DeviceIdleController.LIGHT_STATE_WAITING_FOR_NETWORK;
+import static com.android.server.DeviceIdleController.STATE_ACTIVE;
+import static com.android.server.DeviceIdleController.STATE_IDLE;
+import static com.android.server.DeviceIdleController.STATE_IDLE_MAINTENANCE;
+import static com.android.server.DeviceIdleController.STATE_IDLE_PENDING;
+import static com.android.server.DeviceIdleController.STATE_INACTIVE;
+import static com.android.server.DeviceIdleController.STATE_LOCATING;
+import static com.android.server.DeviceIdleController.STATE_QUICK_DOZE_DELAY;
+import static com.android.server.DeviceIdleController.STATE_SENSING;
+import static com.android.server.DeviceIdleController.lightStateToString;
+import static com.android.server.DeviceIdleController.stateToString;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+
+import android.app.ActivityManagerInternal;
+import android.app.AlarmManager;
+import android.app.IActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.SensorManager;
+import android.location.LocationManager;
+import android.location.LocationProvider;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.PowerManagerInternal;
+import android.os.PowerSaveState;
+import android.os.SystemClock;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.net.NetworkPolicyManagerInternal;
+import com.android.server.wm.ActivityTaskManagerInternal;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.quality.Strictness;
+
+/**
+ * Tests for {@link com.android.server.DeviceIdleController}.
+ */
+@RunWith(AndroidJUnit4.class)
+public class DeviceIdleControllerTest {
+    private DeviceIdleController mDeviceIdleController;
+    private AnyMotionDetectorForTest mAnyMotionDetector;
+    private AppStateTrackerForTest mAppStateTracker;
+    private InjectorForTest mInjector;
+
+    private MockitoSession mMockingSession;
+    @Mock
+    private AlarmManager mAlarmManager;
+    @Mock
+    private ConnectivityService mConnectivityService;
+    @Mock
+    private DeviceIdleController.Constants mConstants;
+    @Mock
+    private IActivityManager mIActivityManager;
+    @Mock
+    private LocationManager mLocationManager;
+    @Mock
+    private PowerManager mPowerManager;
+    @Mock
+    private PowerManager.WakeLock mWakeLock;
+    @Mock
+    private PowerManagerInternal mPowerManagerInternal;
+
+    class InjectorForTest extends DeviceIdleController.Injector {
+        ConnectivityService connectivityService;
+        LocationManager locationManager;
+
+        InjectorForTest(Context ctx) {
+            super(ctx);
+        }
+
+        @Override
+        AlarmManager getAlarmManager() {
+            return mAlarmManager;
+        }
+
+        @Override
+        AnyMotionDetector getAnyMotionDetector(Handler handler, SensorManager sm,
+                AnyMotionDetector.DeviceIdleCallback callback, float angleThreshold) {
+            return mAnyMotionDetector;
+        }
+
+        @Override
+        AppStateTracker getAppStateTracker(Context ctx, Looper loop) {
+            return mAppStateTracker;
+        }
+
+        @Override
+        ConnectivityService getConnectivityService() {
+            return connectivityService;
+        }
+
+        @Override
+        DeviceIdleController.Constants getConstants(DeviceIdleController controller,
+                Handler handler,
+                ContentResolver resolver) {
+            return mConstants;
+        }
+
+        @Override
+        LocationManager getLocationManager() {
+            return locationManager;
+        }
+
+        @Override
+        DeviceIdleController.MyHandler getHandler(DeviceIdleController controller) {
+            return mock(DeviceIdleController.MyHandler.class);
+        }
+
+        @Override
+        PowerManager getPowerManager() {
+            return mPowerManager;
+        }
+    }
+
+    private class AnyMotionDetectorForTest extends AnyMotionDetector {
+        boolean isMonitoring = false;
+
+        AnyMotionDetectorForTest() {
+            super(mPowerManager, mock(Handler.class), mock(SensorManager.class),
+                    mock(DeviceIdleCallback.class), 0.5f);
+        }
+
+        @Override
+        public void checkForAnyMotion() {
+            isMonitoring = true;
+        }
+
+        @Override
+        public void stop() {
+            isMonitoring = false;
+        }
+    }
+
+    private class AppStateTrackerForTest extends AppStateTracker {
+        AppStateTrackerForTest(Context ctx, Looper looper) {
+            super(ctx, looper);
+        }
+
+        @Override
+        public void onSystemServicesReady() {
+            // Do nothing.
+        }
+
+        @Override
+        IActivityManager injectIActivityManager() {
+            return mIActivityManager;
+        }
+    }
+
+    @Before
+    public void setUp() {
+        mMockingSession = mockitoSession()
+                .initMocks(this)
+                .strictness(Strictness.LENIENT)
+                .mockStatic(LocalServices.class)
+                .startMocking();
+        doReturn(mock(ActivityManagerInternal.class))
+                .when(() -> LocalServices.getService(ActivityManagerInternal.class));
+        doReturn(mock(ActivityTaskManagerInternal.class))
+                .when(() -> LocalServices.getService(ActivityTaskManagerInternal.class));
+        doReturn(mPowerManagerInternal)
+                .when(() -> LocalServices.getService(PowerManagerInternal.class));
+        when(mPowerManagerInternal.getLowPowerState(anyInt())).thenReturn(
+                mock(PowerSaveState.class));
+        doReturn(mock(NetworkPolicyManagerInternal.class))
+                .when(() -> LocalServices.getService(NetworkPolicyManagerInternal.class));
+        when(mPowerManager.newWakeLock(anyInt(), anyString())).thenReturn(mWakeLock);
+        doNothing().when(mWakeLock).acquire();
+        doNothing().when(mAlarmManager).set(anyInt(), anyLong(), anyString(), any(), any());
+        mAppStateTracker = new AppStateTrackerForTest(getContext(), Looper.getMainLooper());
+        mAnyMotionDetector = new AnyMotionDetectorForTest();
+        mInjector = new InjectorForTest(getContext());
+        mDeviceIdleController = new DeviceIdleController(getContext(), mInjector);
+        spyOn(mDeviceIdleController);
+        doNothing().when(mDeviceIdleController).publishBinderService(any(), any());
+        mDeviceIdleController.onStart();
+        mDeviceIdleController.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+        mDeviceIdleController.setDeepEnabledForTest(true);
+        mDeviceIdleController.setLightEnabledForTest(true);
+    }
+
+    @After
+    public void tearDown() {
+        if (mMockingSession != null) {
+            mMockingSession.finishMocking();
+        }
+        // DeviceIdleController adds this to LocalServices in the constructor, so we have to remove
+        // it after each test, otherwise, subsequent tests will fail.
+        LocalServices.removeServiceForTest(AppStateTracker.class);
+    }
+
+    @Test
+    public void testUpdateInteractivityLocked() {
+        doReturn(false).when(mPowerManager).isInteractive();
+        mDeviceIdleController.updateInteractivityLocked();
+        assertFalse(mDeviceIdleController.isScreenOn());
+
+        // Make sure setting false when screen is already off doesn't change anything.
+        doReturn(false).when(mPowerManager).isInteractive();
+        mDeviceIdleController.updateInteractivityLocked();
+        assertFalse(mDeviceIdleController.isScreenOn());
+
+        // Test changing from screen off to screen on.
+        doReturn(true).when(mPowerManager).isInteractive();
+        mDeviceIdleController.updateInteractivityLocked();
+        assertTrue(mDeviceIdleController.isScreenOn());
+
+        // Make sure setting true when screen is already on doesn't change anything.
+        doReturn(true).when(mPowerManager).isInteractive();
+        mDeviceIdleController.updateInteractivityLocked();
+        assertTrue(mDeviceIdleController.isScreenOn());
+
+        // Test changing from screen on to screen off.
+        doReturn(false).when(mPowerManager).isInteractive();
+        mDeviceIdleController.updateInteractivityLocked();
+        assertFalse(mDeviceIdleController.isScreenOn());
+    }
+
+    @Test
+    public void testUpdateChargingLocked() {
+        mDeviceIdleController.updateChargingLocked(false);
+        assertFalse(mDeviceIdleController.isCharging());
+
+        // Make sure setting false when charging is already off doesn't change anything.
+        mDeviceIdleController.updateChargingLocked(false);
+        assertFalse(mDeviceIdleController.isCharging());
+
+        // Test changing from charging off to charging on.
+        mDeviceIdleController.updateChargingLocked(true);
+        assertTrue(mDeviceIdleController.isCharging());
+
+        // Make sure setting true when charging is already on doesn't change anything.
+        mDeviceIdleController.updateChargingLocked(true);
+        assertTrue(mDeviceIdleController.isCharging());
+
+        // Test changing from charging on to charging off.
+        mDeviceIdleController.updateChargingLocked(false);
+        assertFalse(mDeviceIdleController.isCharging());
+    }
+
+    @Test
+    public void testUpdateConnectivityState() {
+        // No connectivity service
+        final boolean isConnected = mDeviceIdleController.isNetworkConnected();
+        mInjector.connectivityService = null;
+        mDeviceIdleController.updateConnectivityState(null);
+        assertEquals(isConnected, mDeviceIdleController.isNetworkConnected());
+
+        // No active network info
+        mInjector.connectivityService = mConnectivityService;
+        doReturn(null).when(mConnectivityService).getActiveNetworkInfo();
+        mDeviceIdleController.updateConnectivityState(null);
+        assertFalse(mDeviceIdleController.isNetworkConnected());
+
+        // Active network info says connected.
+        final NetworkInfo ani = mock(NetworkInfo.class);
+        doReturn(ani).when(mConnectivityService).getActiveNetworkInfo();
+        doReturn(true).when(ani).isConnected();
+        mDeviceIdleController.updateConnectivityState(null);
+        assertTrue(mDeviceIdleController.isNetworkConnected());
+
+        // Active network info says not connected.
+        doReturn(false).when(ani).isConnected();
+        mDeviceIdleController.updateConnectivityState(null);
+        assertFalse(mDeviceIdleController.isNetworkConnected());
+
+        // Wrong intent passed (false).
+        Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
+        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 3);
+        doReturn(true).when(ani).isConnected();
+        doReturn(1).when(ani).getType();
+        mDeviceIdleController.updateConnectivityState(intent);
+        // Wrong intent means we shouldn't update the connected state.
+        assertFalse(mDeviceIdleController.isNetworkConnected());
+
+        // Intent says connected.
+        doReturn(1).when(ani).getType();
+        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 1);
+        intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
+        mDeviceIdleController.updateConnectivityState(intent);
+        assertTrue(mDeviceIdleController.isNetworkConnected());
+
+        // Wrong intent passed (true).
+        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 3);
+        // Wrong intent means we shouldn't update the connected state.
+        assertTrue(mDeviceIdleController.isNetworkConnected());
+
+        // Intent says not connected.
+        intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, 1);
+        intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
+        mDeviceIdleController.updateConnectivityState(intent);
+        assertFalse(mDeviceIdleController.isNetworkConnected());
+    }
+
+    @Test
+    public void testUpdateQuickDozeFlagLocked() {
+        mDeviceIdleController.updateQuickDozeFlagLocked(false);
+        assertFalse(mDeviceIdleController.isQuickDozeEnabled());
+
+        // Make sure setting false when quick doze is already off doesn't change anything.
+        mDeviceIdleController.updateQuickDozeFlagLocked(false);
+        assertFalse(mDeviceIdleController.isQuickDozeEnabled());
+
+        // Test changing from quick doze off to quick doze on.
+        mDeviceIdleController.updateQuickDozeFlagLocked(true);
+        assertTrue(mDeviceIdleController.isQuickDozeEnabled());
+
+        // Make sure setting true when quick doze is already on doesn't change anything.
+        mDeviceIdleController.updateQuickDozeFlagLocked(true);
+        assertTrue(mDeviceIdleController.isQuickDozeEnabled());
+
+        // Test changing from quick doze on to quick doze off.
+        mDeviceIdleController.updateQuickDozeFlagLocked(false);
+        assertFalse(mDeviceIdleController.isQuickDozeEnabled());
+    }
+
+    @Test
+    public void testStateActiveToStateInactive_ConditionsNotMet() {
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        verifyStateConditions(STATE_ACTIVE);
+
+        // State should stay ACTIVE with screen on and charging.
+        setChargingOn(true);
+        setScreenOn(true);
+
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyStateConditions(STATE_ACTIVE);
+
+        // State should stay ACTIVE with charging on.
+        setChargingOn(true);
+        setScreenOn(false);
+
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyStateConditions(STATE_ACTIVE);
+
+        // State should stay ACTIVE with screen on.
+        // Note the different operation order here makes sure the state doesn't change before test.
+        setScreenOn(true);
+        setChargingOn(false);
+
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyStateConditions(STATE_ACTIVE);
+    }
+
+    @Test
+    public void testLightStateActiveToLightStateInactive_ConditionsNotMet() {
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        // State should stay ACTIVE with screen on and charging.
+        setChargingOn(true);
+        setScreenOn(true);
+
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        // State should stay ACTIVE with charging on.
+        setChargingOn(true);
+        setScreenOn(false);
+
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        // State should stay ACTIVE with screen on.
+        // Note the different operation order here makes sure the state doesn't change before test.
+        setScreenOn(true);
+        setChargingOn(false);
+
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+    }
+
+    @Test
+    public void testStateActiveToStateInactive_ConditionsMet() {
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        verifyStateConditions(STATE_ACTIVE);
+
+        setChargingOn(false);
+        setScreenOn(false);
+
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyStateConditions(STATE_INACTIVE);
+    }
+
+    @Test
+    public void testLightStateActiveToLightStateInactive_ConditionsMet() {
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        setChargingOn(false);
+        setScreenOn(false);
+
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+    }
+
+    @Test
+    public void testTransitionFromAnyStateToStateQuickDozeDelay() {
+        enterDeepState(STATE_ACTIVE);
+        setQuickDozeEnabled(true);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_INACTIVE);
+        setQuickDozeEnabled(true);
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        setQuickDozeEnabled(true);
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_SENSING);
+        setQuickDozeEnabled(true);
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_LOCATING);
+        setQuickDozeEnabled(true);
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        // IDLE should stay as IDLE.
+        enterDeepState(STATE_IDLE);
+        setQuickDozeEnabled(true);
+        verifyStateConditions(STATE_IDLE);
+
+        // IDLE_MAINTENANCE should stay as IDLE_MAINTENANCE.
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        setQuickDozeEnabled(true);
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+    }
+
+    @Test
+    public void testStepIdleStateLocked_InvalidStates() {
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        // mDeviceIdleController.stepIdleStateLocked doesn't handle the ACTIVE case, so the state
+        // should stay as ACTIVE.
+        verifyStateConditions(STATE_ACTIVE);
+    }
+
+    @Test
+    public void testStepIdleStateLocked_ValidStates_QuickDoze() {
+        setAlarmSoon(false);
+
+        // Quick doze should go directly into IDLE.
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE);
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
+    public void testStepIdleStateLocked_ValidStates_WithWakeFromIdleAlarmSoon() {
+        enterDeepState(STATE_ACTIVE);
+        // Return that there's an alarm coming soon.
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_ACTIVE);
+
+        // Everything besides ACTIVE should end up as INACTIVE since the screen would be off.
+
+        enterDeepState(STATE_INACTIVE);
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_SENSING);
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_LOCATING);
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_INACTIVE);
+
+        // With quick doze enabled, we should end up in QUICK_DOZE_DELAY instead of INACTIVE.
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        setQuickDozeEnabled(true);
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        // With quick doze disabled, we should end up in INACTIVE instead of QUICK_DOZE_DELAY.
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        setQuickDozeEnabled(false);
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE);
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        setAlarmSoon(true);
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_INACTIVE);
+    }
+
+    @Test
+    public void testStepIdleStateLocked_ValidStates_NoLocationManager() {
+        mInjector.locationManager = null;
+        // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
+        setAlarmSoon(false);
+        // Set state to INACTIVE.
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyStateConditions(STATE_INACTIVE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_SENSING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        // No location manager, so SENSING should go straight to IDLE.
+        verifyStateConditions(STATE_IDLE);
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
+    public void testStepIdleStateLocked_ValidStates_WithLocationManager_NoProviders() {
+        // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
+        setAlarmSoon(false);
+        // Set state to INACTIVE.
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyStateConditions(STATE_INACTIVE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_SENSING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        // Location manager exists but there isn't a network or GPS provider,
+        // so SENSING should go straight to IDLE.
+        verifyStateConditions(STATE_IDLE);
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
+    public void testStepIdleStateLocked_ValidStates_WithLocationManager_WithProviders() {
+        mInjector.locationManager = mLocationManager;
+        doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(anyString());
+        // Make sure the controller doesn't think there's a wake-from-idle alarm coming soon.
+        setAlarmSoon(false);
+        // Set state to INACTIVE.
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyStateConditions(STATE_INACTIVE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_SENSING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        // Location manager exists with a provider, so SENSING should go to LOCATING.
+        verifyStateConditions(STATE_LOCATING);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE);
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE);
+
+        mDeviceIdleController.stepIdleStateLocked("testing");
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
+    public void testLightStepIdleStateLocked_InvalidStates() {
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        // stepLightIdleStateLocked doesn't handle the ACTIVE case, so the state
+        // should stay as ACTIVE.
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+    }
+
+    /**
+     * Make sure stepLightIdleStateLocked doesn't change state when the state is
+     * LIGHT_STATE_OVERRIDE.
+     */
+    @Test
+    public void testLightStepIdleStateLocked_Overriden() {
+        enterLightState(LIGHT_STATE_OVERRIDE);
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
+    }
+
+    @Test
+    public void testLightStepIdleStateLocked_ValidStates_NoActiveOps_NetworkConnected() {
+        setNetworkConnected(true);
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+        // 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);
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
+    public void testLightStepIdleStateLocked_ValidStates_ActiveOps_NetworkConnected() {
+        setNetworkConnected(true);
+        // Set state to INACTIVE.
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+        // Active ops means INACTIVE should go to PRE_IDLE to wait.
+        mDeviceIdleController.setJobsActive(true);
+        mDeviceIdleController.setAlarmsActive(true);
+        mDeviceIdleController.setActiveIdleOpsForTest(1);
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_PRE_IDLE);
+
+        // Even with active ops, PRE_IDLE should go to IDLE.
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        // Should just alternate between IDLE and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
+    public void testLightStepIdleStateLocked_ValidStates_NoActiveOps_NoNetworkConnected() {
+        setNetworkConnected(false);
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+        // 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);
+
+        // Should cycle between IDLE, WAITING_FOR_NETWORK, and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+    }
+
+    @Test
+    public void testLightStepIdleStateLocked_ValidStates_ActiveOps_NoNetworkConnected() {
+        setNetworkConnected(false);
+        // Set state to INACTIVE.
+        mDeviceIdleController.becomeActiveLocked("testing", 0);
+        setChargingOn(false);
+        setScreenOn(false);
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+        // Active ops means INACTIVE should go to PRE_IDLE to wait.
+        mDeviceIdleController.setJobsActive(true);
+        mDeviceIdleController.setAlarmsActive(true);
+        mDeviceIdleController.setActiveIdleOpsForTest(1);
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_PRE_IDLE);
+
+        // Even with active ops, PRE_IDLE should go to IDLE.
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        // Should cycle between IDLE, WAITING_FOR_NETWORK, and IDLE_MAINTENANCE now.
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        mDeviceIdleController.stepLightIdleStateLocked("testing");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+    }
+
+    ///////////////// EXIT conditions ///////////////////
+
+    @Test
+    public void testExitMaintenanceEarlyIfNeededLocked_deep_noActiveOps() {
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+        // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
+
+        enterDeepState(STATE_ACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_INACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        enterDeepState(STATE_SENSING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_SENSING);
+
+        enterDeepState(STATE_LOCATING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_LOCATING);
+
+        enterDeepState(STATE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        // Going into IDLE_MAINTENANCE increments the active idle op count.
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE);
+
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+    }
+
+    @Test
+    public void testExitMaintenanceEarlyIfNeededLocked_deep_activeJobs() {
+        mDeviceIdleController.setJobsActive(true);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+        // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
+
+        enterDeepState(STATE_ACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_INACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        enterDeepState(STATE_SENSING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_SENSING);
+
+        enterDeepState(STATE_LOCATING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_LOCATING);
+
+        enterDeepState(STATE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+    }
+
+    @Test
+    public void testExitMaintenanceEarlyIfNeededLocked_deep_activeAlarms() {
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(true);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+        // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
+
+        enterDeepState(STATE_ACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_INACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        enterDeepState(STATE_SENSING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_SENSING);
+
+        enterDeepState(STATE_LOCATING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_LOCATING);
+
+        enterDeepState(STATE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+    }
+
+    @Test
+    public void testExitMaintenanceEarlyIfNeededLocked_deep_activeOps() {
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(1);
+
+        // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
+
+        enterDeepState(STATE_ACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_INACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE_PENDING);
+
+        enterDeepState(STATE_SENSING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_SENSING);
+
+        enterDeepState(STATE_LOCATING);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_LOCATING);
+
+        enterDeepState(STATE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_IDLE_MAINTENANCE);
+
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+    }
+
+    @Test
+    public void testExitMaintenanceEarlyIfNeededLocked_light_noActiveOps() {
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+        // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
+
+        enterLightState(LIGHT_STATE_ACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_INACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+        enterLightState(LIGHT_STATE_PRE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        enterLightState(LIGHT_STATE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
+        // Going into IDLE_MAINTENANCE increments the active idle op count.
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        enterLightState(LIGHT_STATE_OVERRIDE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
+    }
+
+    @Test
+    public void testExitMaintenanceEarlyIfNeededLocked_light_activeJobs() {
+        mDeviceIdleController.setJobsActive(true);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+        // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
+
+        enterLightState(LIGHT_STATE_ACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_INACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+        enterLightState(LIGHT_STATE_PRE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_PRE_IDLE);
+
+        enterLightState(LIGHT_STATE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+        enterLightState(LIGHT_STATE_OVERRIDE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
+    }
+
+    @Test
+    public void testExitMaintenanceEarlyIfNeededLocked_light_activeAlarms() {
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(true);
+        mDeviceIdleController.setActiveIdleOpsForTest(0);
+
+        // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
+
+        enterLightState(LIGHT_STATE_ACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_INACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+        enterLightState(LIGHT_STATE_PRE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_PRE_IDLE);
+
+        enterLightState(LIGHT_STATE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+        enterLightState(LIGHT_STATE_OVERRIDE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
+    }
+
+    @Test
+    public void testExitMaintenanceEarlyIfNeededLocked_light_activeOps() {
+        mDeviceIdleController.setJobsActive(false);
+        mDeviceIdleController.setAlarmsActive(false);
+        mDeviceIdleController.setActiveIdleOpsForTest(1);
+
+        // This method should only change things if in IDLE_MAINTENANCE or PRE_IDLE states.
+
+        enterLightState(LIGHT_STATE_ACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_INACTIVE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+        enterLightState(LIGHT_STATE_PRE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_PRE_IDLE);
+
+        enterLightState(LIGHT_STATE_IDLE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+        enterLightState(LIGHT_STATE_OVERRIDE);
+        mDeviceIdleController.exitMaintenanceEarlyIfNeededLocked();
+        verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
+    }
+
+    @Test
+    public void testHandleMotionDetectedLocked_deep_quickDoze_off() {
+        enterDeepState(STATE_ACTIVE);
+        setQuickDozeEnabled(false);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_ACTIVE);
+
+        // Anything that wasn't ACTIVE before motion detection should end up in the INACTIVE state.
+
+        enterDeepState(STATE_INACTIVE);
+        setQuickDozeEnabled(false);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        setQuickDozeEnabled(false);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_SENSING);
+        setQuickDozeEnabled(false);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_LOCATING);
+        setQuickDozeEnabled(false);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE);
+        setQuickDozeEnabled(false);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        setQuickDozeEnabled(false);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        setQuickDozeEnabled(false);
+        // Disabling quick doze doesn't immediately change the state as coming out is harder than
+        // going in.
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_INACTIVE);
+    }
+
+    @Test
+    public void testHandleMotionDetectedLocked_deep_quickDoze_on() {
+        enterDeepState(STATE_ACTIVE);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_ACTIVE);
+
+        // Anything that wasn't ACTIVE before motion detection should end up in the
+        // QUICK_DOZE_DELAY state since quick doze is enabled.
+
+        enterDeepState(STATE_INACTIVE);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_SENSING);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_LOCATING);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_IDLE);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        setQuickDozeEnabled(true);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyStateConditions(STATE_QUICK_DOZE_DELAY);
+    }
+
+    @Test
+    public void testHandleMotionDetectedLocked_light() {
+        enterLightState(LIGHT_STATE_ACTIVE);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        // Motion shouldn't affect light idle, so LIGHT states should stay as they were except for
+        // OVERRIDE. OVERRIDE means deep was active, so if motion was detected,
+        // LIGHT_STATE_OVERRIDE should end up as LIGHT_STATE_INACTIVE.
+
+        enterLightState(LIGHT_STATE_INACTIVE);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+
+        enterLightState(LIGHT_STATE_PRE_IDLE);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyLightStateConditions(LIGHT_STATE_PRE_IDLE);
+
+        enterLightState(LIGHT_STATE_IDLE);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyLightStateConditions(LIGHT_STATE_IDLE);
+
+        enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyLightStateConditions(LIGHT_STATE_WAITING_FOR_NETWORK);
+
+        enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyLightStateConditions(LIGHT_STATE_IDLE_MAINTENANCE);
+
+        enterLightState(LIGHT_STATE_OVERRIDE);
+        mDeviceIdleController.handleMotionDetectedLocked(50, "test");
+        verifyLightStateConditions(LIGHT_STATE_INACTIVE);
+    }
+
+    @Test
+    public void testbecomeActiveLocked_deep() {
+        // becomeActiveLocked should put everything into ACTIVE.
+
+        enterDeepState(STATE_ACTIVE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_INACTIVE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_IDLE_PENDING);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_SENSING);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_LOCATING);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_IDLE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyStateConditions(STATE_ACTIVE);
+
+        enterDeepState(STATE_QUICK_DOZE_DELAY);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyStateConditions(STATE_ACTIVE);
+    }
+
+    @Test
+    public void testbecomeActiveLocked_light() {
+        // becomeActiveLocked should put everything into ACTIVE.
+
+        enterLightState(LIGHT_STATE_ACTIVE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_INACTIVE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_PRE_IDLE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_IDLE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_WAITING_FOR_NETWORK);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_IDLE_MAINTENANCE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+
+        enterLightState(LIGHT_STATE_OVERRIDE);
+        mDeviceIdleController.becomeActiveLocked("test", 1000);
+        verifyLightStateConditions(LIGHT_STATE_ACTIVE);
+    }
+
+    private void enterDeepState(int state) {
+        switch (state) {
+            case STATE_ACTIVE:
+                setScreenOn(true);
+                mDeviceIdleController.becomeActiveLocked("testing", 0);
+                break;
+            case STATE_QUICK_DOZE_DELAY:
+                // Start off from ACTIVE in case we're already past the desired state.
+                enterDeepState(STATE_ACTIVE);
+                setQuickDozeEnabled(true);
+                setScreenOn(false);
+                setChargingOn(false);
+                mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+                break;
+            case STATE_LOCATING:
+                mInjector.locationManager = mLocationManager;
+                doReturn(mock(LocationProvider.class)).when(mLocationManager).getProvider(
+                        anyString());
+                // Fallthrough to step loop.
+            case STATE_IDLE_PENDING:
+            case STATE_SENSING:
+            case STATE_IDLE:
+            case STATE_IDLE_MAINTENANCE:
+                // Make sure the controller doesn't think there's a wake-from-idle alarm coming
+                // soon.
+                setAlarmSoon(false);
+            case STATE_INACTIVE:
+                // Start off from ACTIVE in case we're already past the desired state.
+                enterDeepState(STATE_ACTIVE);
+                setQuickDozeEnabled(false);
+                setScreenOn(false);
+                setChargingOn(false);
+                mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+                int count = 0;
+                while (mDeviceIdleController.getState() != state) {
+                    // Stepping through each state ensures that the proper features are turned
+                    // on/off.
+                    mDeviceIdleController.stepIdleStateLocked("testing");
+                    count++;
+                    if (count > 10) {
+                        fail("Infinite loop. Check test configuration. Currently at " +
+                                stateToString(mDeviceIdleController.getState()));
+                    }
+                }
+                break;
+            default:
+                fail("Unknown deep state " + stateToString(state));
+        }
+    }
+
+    private void enterLightState(int lightState) {
+        switch (lightState) {
+            case LIGHT_STATE_ACTIVE:
+                setScreenOn(true);
+                mDeviceIdleController.becomeActiveLocked("testing", 0);
+                break;
+            case LIGHT_STATE_INACTIVE:
+            case LIGHT_STATE_IDLE:
+            case LIGHT_STATE_IDLE_MAINTENANCE:
+                // Start off from ACTIVE in case we're already past the desired state.
+                enterLightState(LIGHT_STATE_ACTIVE);
+                setScreenOn(false);
+                setChargingOn(false);
+                int count = 0;
+                mDeviceIdleController.becomeInactiveIfAppropriateLocked();
+                while (mDeviceIdleController.getLightState() != lightState) {
+                    // Stepping through each state ensures that the proper features are turned
+                    // on/off.
+                    mDeviceIdleController.stepLightIdleStateLocked("testing");
+
+                    count++;
+                    if (count > 10) {
+                        fail("Infinite loop. Check test configuration. Currently at " +
+                                lightStateToString(mDeviceIdleController.getLightState()));
+                    }
+                }
+                break;
+            case LIGHT_STATE_PRE_IDLE:
+            case LIGHT_STATE_WAITING_FOR_NETWORK:
+            case LIGHT_STATE_OVERRIDE:
+                setScreenOn(false);
+                setChargingOn(false);
+                mDeviceIdleController.setLightStateForTest(lightState);
+                break;
+            default:
+                fail("Unknown light state " + lightStateToString(lightState));
+        }
+    }
+
+    private void setChargingOn(boolean on) {
+        mDeviceIdleController.updateChargingLocked(on);
+    }
+
+    private void setScreenOn(boolean on) {
+        doReturn(on).when(mPowerManager).isInteractive();
+        mDeviceIdleController.updateInteractivityLocked();
+    }
+
+    private void setNetworkConnected(boolean connected) {
+        mInjector.connectivityService = mConnectivityService;
+        final NetworkInfo ani = mock(NetworkInfo.class);
+        doReturn(connected).when(ani).isConnected();
+        doReturn(ani).when(mConnectivityService).getActiveNetworkInfo();
+        mDeviceIdleController.updateConnectivityState(null);
+    }
+
+    private void setQuickDozeEnabled(boolean on) {
+        mDeviceIdleController.updateQuickDozeFlagLocked(on);
+    }
+
+    private void setAlarmSoon(boolean isSoon) {
+        if (isSoon) {
+            doReturn(SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM / 2).when(
+                    mAlarmManager).getNextWakeFromIdleTime();
+        } else {
+            doReturn(Long.MAX_VALUE).when(mAlarmManager).getNextWakeFromIdleTime();
+        }
+    }
+
+    private void verifyStateConditions(int expectedState) {
+        int curState = mDeviceIdleController.getState();
+        assertEquals(
+                "Expected " + stateToString(expectedState) + " but was " + stateToString(curState),
+                expectedState, curState);
+
+        switch (expectedState) {
+            case STATE_ACTIVE:
+                assertFalse(mDeviceIdleController.mMotionListener.isActive());
+                assertFalse(mAnyMotionDetector.isMonitoring);
+                break;
+            case STATE_INACTIVE:
+                assertFalse(mDeviceIdleController.mMotionListener.isActive());
+                assertFalse(mAnyMotionDetector.isMonitoring);
+                assertFalse(mDeviceIdleController.isCharging());
+                assertFalse(mDeviceIdleController.isScreenOn());
+                break;
+            case STATE_IDLE_PENDING:
+                assertTrue(mDeviceIdleController.mMotionListener.isActive());
+                assertFalse(mAnyMotionDetector.isMonitoring);
+                assertFalse(mDeviceIdleController.isCharging());
+                assertFalse(mDeviceIdleController.isScreenOn());
+                break;
+            case STATE_SENSING:
+                assertTrue(mDeviceIdleController.mMotionListener.isActive());
+                assertTrue(mAnyMotionDetector.isMonitoring);
+                assertFalse(mDeviceIdleController.isCharging());
+                assertFalse(mDeviceIdleController.isScreenOn());
+                break;
+            case STATE_LOCATING:
+                assertTrue(mDeviceIdleController.mMotionListener.isActive());
+                assertTrue(mAnyMotionDetector.isMonitoring);
+                assertFalse(mDeviceIdleController.isCharging());
+                assertFalse(mDeviceIdleController.isScreenOn());
+                break;
+            case STATE_IDLE:
+                assertTrue(mDeviceIdleController.mMotionListener.isActive()
+                        // If quick doze is enabled, the motion listener should NOT be active.
+                        || mDeviceIdleController.isQuickDozeEnabled());
+                assertFalse(mAnyMotionDetector.isMonitoring);
+                assertFalse(mDeviceIdleController.isCharging());
+                assertFalse(mDeviceIdleController.isScreenOn());
+                // Light state should be OVERRIDE at this point.
+                verifyLightStateConditions(LIGHT_STATE_OVERRIDE);
+                break;
+            case STATE_IDLE_MAINTENANCE:
+                assertTrue(mDeviceIdleController.mMotionListener.isActive()
+                        // If quick doze is enabled, the motion listener should NOT be active.
+                        || mDeviceIdleController.isQuickDozeEnabled());
+                assertFalse(mAnyMotionDetector.isMonitoring);
+                assertFalse(mDeviceIdleController.isCharging());
+                assertFalse(mDeviceIdleController.isScreenOn());
+                break;
+            case STATE_QUICK_DOZE_DELAY:
+                // If quick doze is enabled, the motion listener should NOT be active.
+                assertFalse(mDeviceIdleController.mMotionListener.isActive());
+                assertFalse(mAnyMotionDetector.isMonitoring);
+                assertFalse(mDeviceIdleController.isCharging());
+                assertFalse(mDeviceIdleController.isScreenOn());
+                break;
+            default:
+                fail("Conditions for " + stateToString(expectedState) + " unknown.");
+        }
+    }
+
+    private void verifyLightStateConditions(int expectedLightState) {
+        int curLightState = mDeviceIdleController.getLightState();
+        assertEquals(
+                "Expected " + lightStateToString(expectedLightState)
+                        + " but was " + lightStateToString(curLightState),
+                expectedLightState, curLightState);
+
+        switch (expectedLightState) {
+            case LIGHT_STATE_ACTIVE:
+                assertTrue(
+                        mDeviceIdleController.isCharging() || mDeviceIdleController.isScreenOn()
+                                // Or there's an alarm coming up soon.
+                                || SystemClock.elapsedRealtime() + mConstants.MIN_TIME_TO_ALARM
+                                > mAlarmManager.getNextWakeFromIdleTime());
+                break;
+            case LIGHT_STATE_INACTIVE:
+            case LIGHT_STATE_PRE_IDLE:
+            case LIGHT_STATE_IDLE:
+            case LIGHT_STATE_WAITING_FOR_NETWORK:
+            case LIGHT_STATE_IDLE_MAINTENANCE:
+            case LIGHT_STATE_OVERRIDE:
+                assertFalse(mDeviceIdleController.isCharging());
+                assertFalse(mDeviceIdleController.isScreenOn());
+                break;
+            default:
+                fail("Conditions for " + lightStateToString(expectedLightState) + " unknown.");
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java
similarity index 79%
rename from services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
rename to services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java
index 39cab8d..8f39b4a 100644
--- a/services/tests/servicestests/src/com/android/server/am/PersistentConnectionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/PersistentConnectionTest.java
@@ -32,9 +32,10 @@
 import android.os.Looper;
 import android.os.UserHandle;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Pair;
 
+import androidx.test.filters.SmallTest;
+
 import org.mockito.ArgumentMatchers;
 
 import java.util.ArrayList;
@@ -43,6 +44,8 @@
 
 @SmallTest
 public class PersistentConnectionTest extends AndroidTestCase {
+    private static final String TAG = "PersistentConnectionTest";
+
     private static class MyConnection extends PersistentConnection<IDeviceAdminService> {
         public long uptimeMillis = 12345;
 
@@ -50,9 +53,11 @@
 
         public MyConnection(String tag, Context context, Handler handler, int userId,
                 ComponentName componentName, long rebindBackoffSeconds,
-                double rebindBackoffIncrease, long rebindMaxBackoffSeconds) {
+                double rebindBackoffIncrease, long rebindMaxBackoffSeconds,
+                long resetBackoffDelay) {
             super(tag, context, handler, userId, componentName,
-                    rebindBackoffSeconds, rebindBackoffIncrease, rebindMaxBackoffSeconds);
+                    rebindBackoffSeconds, rebindBackoffIncrease, rebindMaxBackoffSeconds,
+                    resetBackoffDelay);
         }
 
         @Override
@@ -113,10 +118,11 @@
         final ComponentName cn = ComponentName.unflattenFromString("a.b.c/def");
         final Handler handler = new Handler(Looper.getMainLooper());
 
-        final MyConnection conn = new MyConnection("tag", context, handler, userId, cn,
+        final MyConnection conn = new MyConnection(TAG, context, handler, userId, cn,
                 /* rebindBackoffSeconds= */ 5,
                 /* rebindBackoffIncrease= */ 1.5,
-                /* rebindMaxBackoffSeconds= */ 11);
+                /* rebindMaxBackoffSeconds= */ 11,
+                /* resetBackoffDelay= */ 999);
 
         assertFalse(conn.isBound());
         assertFalse(conn.isConnected());
@@ -315,10 +321,11 @@
         final ComponentName cn = ComponentName.unflattenFromString("a.b.c/def");
         final Handler handler = new Handler(Looper.getMainLooper());
 
-        final MyConnection conn = new MyConnection("tag", context, handler, userId, cn,
+        final MyConnection conn = new MyConnection(TAG, context, handler, userId, cn,
                 /* rebindBackoffSeconds= */ 5,
                 /* rebindBackoffIncrease= */ 1.5,
-                /* rebindMaxBackoffSeconds= */ 11);
+                /* rebindMaxBackoffSeconds= */ 11,
+                /* resetBackoffDelay= */ 999);
 
         when(context.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class), anyInt(),
                 any(Handler.class), any(UserHandle.class)))
@@ -356,4 +363,78 @@
         assertFalse(conn.isBound());
         assertFalse(conn.shouldBeBoundForTest());
     }
+
+    public void testResetBackoff() {
+        final Context context = mock(Context.class);
+        final int userId = 11;
+        final ComponentName cn = ComponentName.unflattenFromString("a.b.c/def");
+        final Handler handler = new Handler(Looper.getMainLooper());
+
+        final MyConnection conn = new MyConnection(TAG, context, handler, userId, cn,
+                /* rebindBackoffSeconds= */ 5,
+                /* rebindBackoffIncrease= */ 1.5,
+                /* rebindMaxBackoffSeconds= */ 11,
+                /* resetBackoffDelay= */ 20);
+
+        when(context.bindServiceAsUser(any(Intent.class), any(ServiceConnection.class), anyInt(),
+                any(Handler.class), any(UserHandle.class)))
+                .thenReturn(true);
+
+        // Bind.
+        conn.bind();
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isRebindScheduled());
+
+        conn.elapse(1000);
+
+        // Then the binding is "died"...
+        conn.getServiceConnectionForTest().onBindingDied(cn);
+
+        assertFalse(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertTrue(conn.isRebindScheduled());
+
+        assertEquals(7500, conn.getNextBackoffMsForTest());
+
+        assertEquals(
+                Arrays.asList(Pair.create(conn.getBindForBackoffRunnableForTest(),
+                        conn.uptimeMillis + 5000)),
+                conn.scheduledRunnables);
+
+        // 5000 ms later...
+        conn.elapse(5000);
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertFalse(conn.isConnected());
+        assertNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(7500, conn.getNextBackoffMsForTest());
+
+        // Connected.
+        conn.getServiceConnectionForTest().onServiceConnected(cn,
+                new IDeviceAdminService.Stub() {});
+
+        assertTrue(conn.isBound());
+        assertTrue(conn.shouldBeBoundForTest());
+        assertTrue(conn.isConnected());
+        assertNotNull(conn.getServiceBinder());
+        assertFalse(conn.isRebindScheduled());
+
+        assertEquals(7500, conn.getNextBackoffMsForTest());
+
+        assertEquals(
+                Arrays.asList(Pair.create(conn.getStableCheckRunnableForTest(),
+                        conn.uptimeMillis + 20000)),
+                conn.scheduledRunnables);
+
+        conn.elapse(20000);
+
+        assertEquals(5000, conn.getNextBackoffMsForTest());
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
similarity index 78%
rename from services/tests/servicestests/src/com/android/server/job/controllers/JobStatusTest.java
rename to services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
index 1752479..b63138e 100644
--- a/services/tests/servicestests/src/com/android/server/job/controllers/JobStatusTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
@@ -16,19 +16,27 @@
 
 package com.android.server.job.controllers;
 
+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.mockitoSession;
+
 import static org.junit.Assert.assertEquals;
 
 import android.app.job.JobInfo;
 import android.content.ComponentName;
+import android.content.pm.PackageManagerInternal;
 import android.os.SystemClock;
 
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerService;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.MockitoSession;
 
 import java.time.Clock;
 import java.time.ZoneOffset;
@@ -37,8 +45,17 @@
 public class JobStatusTest {
     private static final double DELTA = 0.00001;
 
+    private MockitoSession mMockingSession;
+
     @Before
     public void setUp() throws Exception {
+        mMockingSession = mockitoSession()
+                .initMocks(this)
+                .mockStatic(LocalServices.class)
+                .startMocking();
+        doReturn(mock(PackageManagerInternal.class))
+                .when(() -> LocalServices.getService(PackageManagerInternal.class));
+
         // Freeze the clocks at this moment in time
         JobSchedulerService.sSystemClock =
                 Clock.fixed(Clock.systemUTC().instant(), ZoneOffset.UTC);
@@ -48,6 +65,13 @@
                 Clock.fixed(SystemClock.elapsedRealtimeClock().instant(), ZoneOffset.UTC);
     }
 
+    @After
+    public void tearDown() {
+        if (mMockingSession != null) {
+            mMockingSession.finishMocking();
+        }
+    }
+
     @Test
     public void testFraction() throws Exception {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
diff --git a/services/tests/runtests.py b/services/tests/runtests.py
index 7980dc2..f19cc5d 100755
--- a/services/tests/runtests.py
+++ b/services/tests/runtests.py
@@ -22,8 +22,7 @@
                                'android.support.test.runner.AndroidJUnitRunner')
 
 PACKAGE_WHITELIST = (
-    'android.net',
-    'com.android.server.connectivity',
+    "com.android.server",
 )
 
 COLOR_RED = '\033[0;31m'
@@ -37,14 +36,27 @@
                 COLOR_NONE)
     return subprocess.check_call(shell_command, shell=True)
 
-
+# usage:
+#   ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/runtests.py : run tests in com.android.server
+#   ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/runtests.py -e package [package name, e.g. com.android.server]
+#   ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/runtests.py -e class [class name, e.g. com.android.server.MountServiceTests]
+#
+#   The available INSTRUMENTED_PACKAGE_RUNNER may differ in different environments.
+#   In this case, use "adb shell pm list instrumentation" to query available runners
+#   and use the environment variable INSTRUMENTED_PACKAGE_RUNNER to overwrite
+#   the default one, e.g.,
+#   INSTRUMENTED_PACKAGE_RUNNER=com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner \
+#       ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/runtests.py
+#
 def main():
     build_top = os.environ.get('ANDROID_BUILD_TOP', None)
     out_dir = os.environ.get('OUT', None)
+    runner = os.environ.get('INSTRUMENTED_PACKAGE_RUNNER', None)
     if build_top is None or out_dir is None:
         print 'You need to source and lunch before you can use this script'
         return 1
-
+    if runner is None:
+        runner = INSTRUMENTED_PACKAGE_RUNNER
     print 'Building tests...'
     run('make -j32 -C %s -f build/core/main.mk '
         'MODULES-IN-frameworks-base-services-tests-servicestests' % build_top,
@@ -57,19 +69,19 @@
     apk_path = (
             '%s/data/app/FrameworksServicesTests/FrameworksServicesTests.apk' %
             out_dir)
-    run('adb install -r -g "%s"' % apk_path)
+    run('adb install -t -r -g "%s"' % apk_path)
 
     print 'Running tests...'
     if len(sys.argv) != 1:
         run('adb shell am instrument -w %s "%s"' %
-            (' '.join(sys.argv[1:]), INSTRUMENTED_PACKAGE_RUNNER))
+            (' '.join(sys.argv[1:]), runner))
         return 0
 
     # It would be nice if the activity manager accepted a list of packages, but
     # in lieu of that...
     for package in PACKAGE_WHITELIST:
         run('adb shell am instrument -w -e package %s %s' %
-            (package, INSTRUMENTED_PACKAGE_RUNNER))
+            (package, runner))
 
     return 0
 
diff --git a/services/tests/servicestests/Android.mk b/services/tests/servicestests/Android.mk
index 80307ee..878179b 100644
--- a/services/tests/servicestests/Android.mk
+++ b/services/tests/servicestests/Android.mk
@@ -24,7 +24,8 @@
     services.net \
     services.usage \
     guava \
-    androidx-test \
+    androidx.test.runner \
+    androidx.test.rules \
     mockito-target-minus-junit4 \
     platform-test-annotations \
     ShortcutManagerTestUtils \
@@ -58,6 +59,7 @@
     libbacktrace \
     libbase \
     libbinder \
+    libbinderthreadstate \
     libc++ \
     libcutils \
     liblog \
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers
new file mode 100644
index 0000000..509ea3b
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-2-signers
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers
new file mode 100644
index 0000000..bee71c0
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256-lineage-3-signers
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8 b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8
new file mode 100644
index 0000000..f781c30
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der
new file mode 100644
index 0000000..e611e3d
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8 b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8
new file mode 100644
index 0000000..5e73f27
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der
new file mode 100644
index 0000000..7723bea
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_2.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8 b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8
new file mode 100644
index 0000000..d7309dd
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.pk8
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der
new file mode 100644
index 0000000..cc82af9
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/certs/ec-p256_3.x509.der
Binary files differ
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/README b/services/tests/servicestests/assets/PackageSignaturesTest/xml/README
new file mode 100644
index 0000000..43d5bb8
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/README
@@ -0,0 +1,58 @@
+The XML files in this directory are taken from the packages tag of a test APK signed with the
+certificates and keys under the certs/ directory. To recreate the XML files run the following:
+
+1. Build the test APK:
+mmm -j cts/hostsidetests/appsecurity/test-apps/tinyapp/
+
+2. Sign the APK with the first signer:
+apksigner sign --in ${OUT}/data/app/CtsPkgInstallTinyApp/CtsPkgInstallTinyApp.apk --out test.apk \
+ --cert certs/ec-p256.x509.der --key certs/ec-p256.pk8
+
+3. Install the APK on a device:
+adb install test.apk
+
+4. Pull the packages.xml file containing the new entry for the APK from the device:
+adb pull /data/system/packages.xml
+
+5. Search the packages.xml file for the package name 'android.appsecurity.cts.tinyapp'. Following is
+   the full entry when the APK is signed as above:
+
+    <package name="android.appsecurity.cts.tinyapp" codePath="/data/app/android.appsecurity.cts.tiny
+    app-4ix3umoWct_iD26jQ03Z_g==" nativeLibraryPath="/data/app/android.appsecurity.cts.tinyapp-4ix3u
+    moWct_iD26jQ03Z_g==/lib" publicFlags="805879364" privateFlags="0" ft="1663710dd00" it="1663710de
+    41" ut="1663710de41" version="10" userId="10051">
+        <sigs count="1" schemeVersion="3">
+            <cert index="16" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d
+            04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433
+            303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d0201
+            06082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2
+            b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d
+            0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b
+            30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d04030203490030
+            46022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea48297
+            99c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+        <proper-signing-keyset identifier="480" />
+    </package>
+
+The PackageSignatures#readXml and writeXml methods read and write everything within the sigs tag.
+The tags and attributes within the sigs tag can be modified and used to verify various good and
+error paths for the PackageSignaturesTest.
+
+Step 2 can be modified to sign with multiple signers by running one of the following commands:
+
+- To sign with two signers in the lineage (after the signing key has been rotated once):
+apksigner sign --in ${OUT}/data/app/CtsPkgInstallTinyApp/CtsPkgInstallTinyApp.apk --out test.apk \
+  --cert certs/ec-p256.x509.der --key certs/ec-p256.pk8 --next-signer --cert \
+  certs/ec-p256_2.x509.der --key certs/ec-p256_2.pk8 --lineage certs/ec-p256-lineage-2-signers
+
+- To sign with three signers in the lineage (after the second key rotation):
+apksigner sign --in ${OUT}/data/app/CtsPkgInstallTinyApp/CtsPkgInstallTinyApp.apk --out test.apk \
+  --cert certs/ec-p256.x509.der --key certs/ec-p256.pk8 --next-signer --cert \
+  certs/ec-p256_3.x509.der --key certs/ec-p256_3.pk8 --lineage certs/ec-p256-lineage-3-signers
+
+- To sign with two distinct signers (NOTE: The V3 signature scheme only supports a single signer,
+  so this method can only be used with signature schemes V1 and V2):
+apksigner sign --in ${OUT}/data/app/CtsPkgInstallTinyApp/CtsPkgInstallTinyApp.apk --out test.apk \
+  --cert certs/ec-p256.x509.der --key certs/ec-p256.pk8 --next-signer --cert \
+  certs/ec-p256_3.x509.der --key certs/ec-p256_3.pk8 --v3-signing-enabled false
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml
new file mode 100644
index 0000000..4d55bad
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-extra-cert-tag.xml
@@ -0,0 +1,5 @@
+        <sigs count="1" schemeVersion="3">
+          <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml
new file mode 100644
index 0000000..f7882b1
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-index.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="x" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml
new file mode 100644
index 0000000..af2c293
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-cert-key.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml
new file mode 100644
index 0000000..893402d
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-public-key-cert-key.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="1">
+            <cert index="0" key="4082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml
new file mode 100644
index 0000000..1f81dac
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-invalid-tag.xml
@@ -0,0 +1,5 @@
+        <sigs count="1" schemeVersion="3">
+          <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+          <invalid />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml
new file mode 100644
index 0000000..c38e4d9
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-index.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="3">
+            <cert key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml
new file mode 100644
index 0000000..8e8cbcf
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-key.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="3">
+          <cert index="0" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml
new file mode 100644
index 0000000..57e96a8
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-cert-tag.xml
@@ -0,0 +1,3 @@
+        <sigs count="1" schemeVersion="3">
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml
new file mode 100644
index 0000000..d9f7a5f
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-scheme-version.xml
@@ -0,0 +1,4 @@
+        <sigs count="1">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml
new file mode 100644
index 0000000..4eefdd9
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-missing-sigs-count.xml
@@ -0,0 +1,4 @@
+        <sigs schemeVersion="3">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml
new file mode 100644
index 0000000..2aeeb71
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer-previous-cert.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="2">
+          <cert index="0" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml
new file mode 100644
index 0000000..14471f8
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/one-signer.xml
@@ -0,0 +1,4 @@
+        <sigs count="1" schemeVersion="1">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml
new file mode 100644
index 0000000..2b2e383
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-invalid-pastSigs-count.xml
@@ -0,0 +1,9 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs count="x">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="2" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" flags="7" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml
new file mode 100644
index 0000000..f992104
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs count="3">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml
new file mode 100644
index 0000000..6ef0fe5
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-pastSigs-count.xml
@@ -0,0 +1,9 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs>
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="2" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" flags="7" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml
new file mode 100644
index 0000000..d98573d
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage-missing-scheme-version.xml
@@ -0,0 +1,9 @@
+        <sigs count="1">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs count="3">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="2" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" flags="7" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml
new file mode 100644
index 0000000..2ccf5060
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/three-signers-in-lineage.xml
@@ -0,0 +1,9 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d020106082a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e" />
+            <pastSigs count="3">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="3" />
+                <cert index="2" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" flags="7" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml
new file mode 100644
index 0000000..6d567e9
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-certs-flags.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="x" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml
new file mode 100644
index 0000000..a2146b7
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="x" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="7" />
+                <cert index="0" flags="0" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml
new file mode 100644
index 0000000..90a4a84
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-certs-flags.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+                <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml
new file mode 100644
index 0000000..6525e48
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="7" />
+                <cert flags="0" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml
new file mode 100644
index 0000000..e06892c
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-multiple-pastSigs-tags.xml
@@ -0,0 +1,12 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="23" />
+                <cert index="0" flags="23" />
+                <pastSigs count="2">
+                    <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="23" />
+                    <cert index="0" flags="23" />
+                </pastSigs>
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml
new file mode 100644
index 0000000..8081d2e
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-no-caps.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="0" />
+                <cert index="0" flags="7" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml
new file mode 100644
index 0000000..127000a
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage-undefined-pastSigs-index.xml
@@ -0,0 +1,8 @@
+        <sigs count="2" schemeVersion="3">
+          <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+            <pastSigs count="2">
+              <cert index="1" flags="23" />
+              <cert index="0" flags="23" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml
new file mode 100644
index 0000000..6097ea6
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-in-lineage.xml
@@ -0,0 +1,8 @@
+        <sigs count="1" schemeVersion="3">
+            <cert index="0" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+            <pastSigs count="2">
+                <cert index="1" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" flags="7" />
+                <cert index="0" flags="3" />
+            </pastSigs>
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml
new file mode 100644
index 0000000..6ed3be8
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2-missing-cert-tag.xml
@@ -0,0 +1,4 @@
+        <sigs count="2" schemeVersion="1">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+        </sigs>
+
diff --git a/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml
new file mode 100644
index 0000000..ee4c4eb
--- /dev/null
+++ b/services/tests/servicestests/assets/PackageSignaturesTest/xml/two-signers-v1v2.xml
@@ -0,0 +1,5 @@
+        <sigs count="2" schemeVersion="2">
+            <cert index="0" key="3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3136303333313134353830365a170d3433303831373134353830365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd" />
+            <cert index="1" key="3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06035504030c0765632d70323536301e170d3138303731333137343135315a170d3238303731303137343135315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a8648ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e" />
+        </sigs>
+
diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
index 2ec6830..4fbc587 100644
--- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java
@@ -73,6 +73,9 @@
     private static final int IGNORED_ACTION = 13;
     private static final int IGNORED_CODE = 1999;
     private static final int IGNORED_REPEAT = 42;
+    private static final int IGNORED_META_STATE = 0;
+    private static final int IGNORED_DEVICE_ID = 0;
+    private static final int IGNORED_SCANCODE = 0;
 
     private @Mock Context mContext;
     private @Mock Resources mResources;
@@ -369,6 +372,50 @@
     }
 
     @Test
+    public void testInterceptPowerKeyDown_longpress() {
+        withCameraDoubleTapPowerEnableConfigValue(true);
+        withCameraDoubleTapPowerDisableSettingValue(0);
+        mGestureLauncherService.updateCameraDoubleTapPowerEnabled();
+        withUserSetupCompleteValue(true);
+
+        long eventTime = INITIAL_EVENT_TIME_MILLIS;
+        KeyEvent keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT);
+        boolean interactive = true;
+        MutableBoolean outLaunched = new MutableBoolean(true);
+        boolean intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        final long interval = GestureLauncherService.CAMERA_POWER_DOUBLE_TAP_MAX_TIME_MS - 1;
+        eventTime += interval;
+        keyEvent = new KeyEvent(IGNORED_DOWN_TIME, eventTime, IGNORED_ACTION, IGNORED_CODE,
+                IGNORED_REPEAT, IGNORED_META_STATE, IGNORED_DEVICE_ID, IGNORED_SCANCODE,
+                KeyEvent.FLAG_LONG_PRESS);
+        outLaunched.value = false;
+        intercepted = mGestureLauncherService.interceptPowerKeyDown(keyEvent, interactive,
+                outLaunched);
+        assertFalse(intercepted);
+        assertFalse(outLaunched.value);
+
+        verify(mMetricsLogger, never())
+                .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt());
+
+        final ArgumentCaptor<Integer> intervalCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(1)).histogram(
+                eq("power_double_tap_interval"), intervalCaptor.capture());
+        List<Integer> intervals = intervalCaptor.getAllValues();
+        assertEquals((int) INITIAL_EVENT_TIME_MILLIS, intervals.get(0).intValue());
+
+        final ArgumentCaptor<Integer> tapCountCaptor = ArgumentCaptor.forClass(Integer.class);
+        verify(mMetricsLogger, times(1)).histogram(
+                eq("power_consecutive_short_tap_count"), tapCountCaptor.capture());
+        List<Integer> tapCounts = tapCountCaptor.getAllValues();
+        assertEquals(1, tapCounts.get(0).intValue());
+    }
+
+    @Test
     public void
     testInterceptPowerKeyDown_intervalInBoundsCameraPowerGestureOnInteractiveSetupIncomplete() {
         withCameraDoubleTapPowerEnableConfigValue(true);
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 1eb88ba..113ee2d 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -26,13 +26,21 @@
 import static android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND;
 import static android.net.NetworkPolicyManager.POLICY_NONE;
 import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
+import static android.net.NetworkPolicyManager.RULE_NONE;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
 import static android.net.NetworkPolicyManager.uidPoliciesToString;
+import static android.net.NetworkPolicyManager.uidRulesToString;
 import static android.net.NetworkStats.IFACE_ALL;
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.NetworkTemplate.buildTemplateWifi;
 import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.os.Process.SYSTEM_UID;
 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
@@ -124,6 +132,7 @@
 import android.text.format.Time;
 import android.util.DataUnit;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Range;
 import android.util.RecurrenceRule;
 
@@ -171,6 +180,7 @@
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Iterator;
@@ -1644,6 +1654,76 @@
                 true);
     }
 
+    /**
+     * Exhaustively test isUidNetworkingBlocked to output the expected results based on external
+     * conditions.
+     */
+    @Test
+    public void testIsUidNetworkingBlocked() {
+        final ArrayList<Pair<Boolean, Integer>> expectedBlockedStates = new ArrayList<>();
+
+        // Metered network. Data saver on.
+        expectedBlockedStates.add(new Pair<>(true, RULE_NONE));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_METERED));
+        expectedBlockedStates.add(new Pair<>(true, RULE_ALLOW_ALL));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+        verifyNetworkBlockedState(
+                true /* metered */, true /* backgroundRestricted */, expectedBlockedStates);
+        expectedBlockedStates.clear();
+
+        // Metered network. Data saver off.
+        expectedBlockedStates.add(new Pair<>(false, RULE_NONE));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_ALL));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+        verifyNetworkBlockedState(
+                true /* metered */, false /* backgroundRestricted */, expectedBlockedStates);
+        expectedBlockedStates.clear();
+
+        // Non-metered network. Data saver on.
+        expectedBlockedStates.add(new Pair<>(false, RULE_NONE));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_TEMPORARY_ALLOW_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_REJECT_METERED));
+        expectedBlockedStates.add(new Pair<>(false, RULE_ALLOW_ALL));
+        expectedBlockedStates.add(new Pair<>(true, RULE_REJECT_ALL));
+        verifyNetworkBlockedState(
+                false /* metered */, true /* backgroundRestricted */, expectedBlockedStates);
+
+        // Non-metered network. Data saver off. The result is the same as previous case since
+        // the network is blocked only for RULE_REJECT_ALL regardless of data saver.
+        verifyNetworkBlockedState(
+                false /* metered */, false /* backgroundRestricted */, expectedBlockedStates);
+        expectedBlockedStates.clear();
+    }
+
+    private void verifyNetworkBlockedState(boolean metered, boolean backgroundRestricted,
+            ArrayList<Pair<Boolean, Integer>> expectedBlockedStateForRules) {
+        final NetworkPolicyManagerInternal npmi = LocalServices
+                .getService(NetworkPolicyManagerInternal.class);
+
+        for (Pair<Boolean, Integer> pair : expectedBlockedStateForRules) {
+            final boolean expectedResult = pair.first;
+            final int rule = pair.second;
+            assertEquals(formatBlockedStateError(UID_A, rule, metered, backgroundRestricted),
+                    expectedResult,
+                    npmi.isUidNetworkingBlocked(UID_A, rule, metered, backgroundRestricted));
+            assertFalse(formatBlockedStateError(SYSTEM_UID, rule, metered, backgroundRestricted),
+                    npmi.isUidNetworkingBlocked(SYSTEM_UID, rule, metered, backgroundRestricted));
+        }
+    }
+
+    private String formatBlockedStateError(int uid, int rule, boolean metered,
+            boolean backgroundRestricted) {
+        return String.format(
+                "Unexpected BlockedState: (uid=%d, rule=%s, metered=%b, backgroundRestricted=%b)",
+                uid, uidRulesToString(rule), metered, backgroundRestricted);
+    }
+
     private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) {
         return SubscriptionPlan.Builder
                 .createRecurringMonthly(start)
diff --git a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
index 43438b9..8022532 100644
--- a/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/StorageManagerServiceTest.java
@@ -124,7 +124,7 @@
                 "/storage/emulated/0/Android/sandbox/com.grey/foo.jpg",
                 "/storage/emulated/0/foo.jpg", PKG_GREY);
         assertTranslation(
-                "/storage/emulated/0/Android/sandbox/shared/colors/foo.jpg",
+                "/storage/emulated/0/Android/sandbox/shared:colors/foo.jpg",
                 "/storage/emulated/0/foo.jpg", PKG_RED);
     }
 
@@ -134,7 +134,7 @@
                 "/storage/0000-0000/Android/sandbox/com.grey/foo/bar.jpg",
                 "/storage/0000-0000/foo/bar.jpg", PKG_GREY);
         assertTranslation(
-                "/storage/0000-0000/Android/sandbox/shared/colors/foo/bar.jpg",
+                "/storage/0000-0000/Android/sandbox/shared:colors/foo/bar.jpg",
                 "/storage/0000-0000/foo/bar.jpg", PKG_RED);
     }
 
@@ -147,7 +147,7 @@
 
         // Accessing other package paths goes into sandbox
         assertTranslation(
-                "/storage/emulated/0/Android/sandbox/shared/colors/"
+                "/storage/emulated/0/Android/sandbox/shared:colors/"
                         + "Android/data/com.grey/foo.jpg",
                 "/storage/emulated/0/Android/data/com.grey/foo.jpg", PKG_RED);
     }
@@ -192,7 +192,7 @@
         // Sandboxes can't see paths in other sandboxes
         try {
             mService.translateSystemToApp(
-                    "/storage/emulated/0/Android/sandbox/shared/colors/foo.jpg",
+                    "/storage/emulated/0/Android/sandbox/shared:colors/foo.jpg",
                     PKG_GREY, UserHandle.USER_SYSTEM);
             fail();
         } catch (SecurityException expected) {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
index c88b873..feffeef 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
@@ -86,12 +86,8 @@
     final AccessibilityManagerService mMockAms = mock(AccessibilityManagerService.class);
     final WindowManagerInternal mMockWindowManager = mock(WindowManagerInternal.class);
     final MessageCapturingHandler mMessageCapturingHandler =
-            new MessageCapturingHandler(new Handler.Callback() {
-        @Override
-        public boolean handleMessage(Message msg) {
-            return mMagnificationController.handleMessage(msg);
-        }
-    });
+            new MessageCapturingHandler(null);
+
     final ValueAnimator mMockValueAnimator = mock(ValueAnimator.class);
     MagnificationController.SettingsBridge mMockSettingsBridge;
 
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
index 79e4d70..032074a 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationGestureHandlerTest.java
@@ -29,9 +29,11 @@
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.animation.ValueAnimator;
 import android.annotation.NonNull;
 import android.content.Context;
 import android.os.Message;
@@ -44,7 +46,9 @@
 
 import com.android.server.testutils.OffsettableClock;
 import com.android.server.testutils.TestHandler;
+import com.android.server.wm.WindowManagerInternal;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -101,8 +105,15 @@
     public static final float DEFAULT_Y = 299;
 
     private Context mContext;
-    private AccessibilityManagerService mAms;
-    private MagnificationController mMagnificationController;
+    final AccessibilityManagerService mMockAms = mock(AccessibilityManagerService.class);
+    final WindowManagerInternal mMockWindowManager = mock(WindowManagerInternal.class);
+    final MessageCapturingHandler mMessageCapturingHandler =
+            new MessageCapturingHandler(null);
+    final ValueAnimator mMockValueAnimator = mock(ValueAnimator.class);
+    MagnificationController.SettingsBridge mMockSettingsBridge =
+            mock(MagnificationController.SettingsBridge.class);
+    MagnificationController mMagnificationController;
+
     private OffsettableClock mClock;
     private MagnificationGestureHandler mMgh;
     private TestHandler mHandler;
@@ -112,9 +123,9 @@
     @Before
     public void setUp() {
         mContext = InstrumentationRegistry.getContext();
-        mAms = new AccessibilityManagerService(mContext);
-        mMagnificationController = new MagnificationController(
-                mContext, mAms, /* lock */ new Object()) {
+        mMagnificationController = new MagnificationController(mContext, mMockAms, new Object(),
+                mMessageCapturingHandler, mMockWindowManager, mMockValueAnimator,
+                mMockSettingsBridge) {
             @Override
             public boolean magnificationRegionContains(float x, float y) {
                 return true;
@@ -123,7 +134,7 @@
             @Override
             void setForceShowMagnifiableBounds(boolean show) {}
         };
-        mMagnificationController.mRegistered = true;
+        mMagnificationController.register();
         mClock = new OffsettableClock.Stopped();
 
         boolean detectTripleTap = true;
@@ -131,6 +142,11 @@
         mMgh = newInstance(detectTripleTap, detectShortcutTrigger);
     }
 
+    @After
+    public void tearDown() {
+        mMagnificationController.unregister();
+    }
+
     @NonNull
     private MagnificationGestureHandler newInstance(boolean detectTripleTap,
             boolean detectShortcutTrigger) {
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 8e09d60..9ac3987 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/UiAutomationManagerTest.java
@@ -49,7 +49,7 @@
 public class UiAutomationManagerTest {
     static final int SERVICE_ID = 42;
 
-    final UiAutomationManager mUiAutomationManager = new UiAutomationManager();
+    final UiAutomationManager mUiAutomationManager = new UiAutomationManager(new Object());
 
     MessageCapturingHandler mMessageCapturingHandler;
 
@@ -158,13 +158,13 @@
         verify(mMockOwner).linkToDeath(captor.capture(), anyInt());
         captor.getValue().binderDied();
         mMessageCapturingHandler.sendAllMessages();
-        verify(mMockSystemSupport).onClientChange(false);
+        verify(mMockSystemSupport).onClientChangeLocked(false);
     }
 
     private void register(int flags) {
         mUiAutomationManager.registerUiTestAutomationServiceLocked(mMockOwner,
                 mMockAccessibilityServiceClient, mMockContext, mMockServiceInfo, SERVICE_ID,
-                mMessageCapturingHandler, new Object(), mMockSecurityPolicy, mMockSystemSupport,
+                mMessageCapturingHandler, mMockSecurityPolicy, mMockSystemSupport,
                 mMockWindowManagerInternal, mMockGlobalActionPerformer, flags);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
new file mode 100644
index 0000000..0da5742
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityDisplayTests.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
+
+import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the {@link ActivityDisplay} class.
+ *
+ * Build/Install/Run:
+ *  atest WmTests:ActivityDisplayTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ActivityDisplayTests extends ActivityTestsBase {
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        setupActivityTaskManagerService();
+    }
+
+    @Test
+    public void testLastFocusedStackIsUpdatedWhenMovingStack() {
+        // Create a stack at bottom.
+        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+        final ActivityStack stack = display.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, !ON_TOP);
+        final ActivityStack prevFocusedStack = display.getFocusedStack();
+
+        stack.moveToFront("moveStackToFront");
+        // After moving the stack to front, the previous focused should be the last focused.
+        assertTrue(stack.isFocusedStackOnDisplay());
+        assertEquals(prevFocusedStack, display.getLastFocusedStack());
+
+        stack.moveToBack("moveStackToBack", null /* task */);
+        // After moving the stack to back, the stack should be the last focused.
+        assertEquals(stack, display.getLastFocusedStack());
+    }
+
+    /**
+     * This test simulates the picture-in-picture menu activity launches an activity to fullscreen
+     * stack. The fullscreen stack should be the top focused for resuming correctly.
+     */
+    @Test
+    public void testFullscreenStackCanBeFocusedWhenFocusablePinnedStackExists() {
+        // Create a pinned stack and move to front.
+        final ActivityStack pinnedStack = mSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, ON_TOP);
+        final TaskRecord pinnedTask = new TaskBuilder(mService.mStackSupervisor)
+                .setStack(pinnedStack).build();
+        new ActivityBuilder(mService).setActivityFlags(FLAG_ALWAYS_FOCUSABLE)
+                .setTask(pinnedTask).build();
+        pinnedStack.moveToFront("movePinnedStackToFront");
+
+        // The focused stack should be the pinned stack.
+        assertTrue(pinnedStack.isFocusedStackOnDisplay());
+
+        // Create a fullscreen stack and move to front.
+        final ActivityStack fullscreenStack = createFullscreenStackWithSimpleActivityAt(
+                mSupervisor.getDefaultDisplay());
+        fullscreenStack.moveToFront("moveFullscreenStackToFront");
+
+        // The focused stack should be the fullscreen stack.
+        assertTrue(fullscreenStack.isFocusedStackOnDisplay());
+    }
+
+    /**
+     * Test {@link ActivityDisplay#mPreferredTopFocusableStack} will be cleared when the stack is
+     * removed or moved to back, and the focused stack will be according to z-order.
+     */
+    @Test
+    public void testStackShouldNotBeFocusedAfterMovingToBackOrRemoving() {
+        // Create a display which only contains 2 stacks.
+        final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
+        final ActivityStack stack1 = createFullscreenStackWithSimpleActivityAt(display);
+        final ActivityStack stack2 = createFullscreenStackWithSimpleActivityAt(display);
+
+        // Put stack1 and stack2 on top.
+        stack1.moveToFront("moveStack1ToFront");
+        stack2.moveToFront("moveStack2ToFront");
+        assertTrue(stack2.isFocusedStackOnDisplay());
+
+        // Stack1 should be focused after moving stack2 to back.
+        stack2.moveToBack("moveStack2ToBack", null /* task */);
+        assertTrue(stack1.isFocusedStackOnDisplay());
+
+        // Stack2 should be focused after removing stack1.
+        display.removeChild(stack1);
+        assertTrue(stack2.isFocusedStackOnDisplay());
+    }
+
+    private ActivityStack createFullscreenStackWithSimpleActivityAt(ActivityDisplay display) {
+        final ActivityStack fullscreenStack = display.createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, ON_TOP);
+        final TaskRecord fullscreenTask = new TaskBuilder(mService.mStackSupervisor)
+                .setStack(fullscreenStack).build();
+        new ActivityBuilder(mService).setTask(fullscreenTask).build();
+        return fullscreenStack;
+    }
+
+    /**
+     * Verifies the correct activity is returned when querying the top running activity.
+     */
+    @Test
+    public void testTopRunningActivity() {
+        // Create stack to hold focus.
+        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+        final ActivityStack emptyStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        final KeyguardController keyguard = mSupervisor.getKeyguardController();
+        final ActivityStack stack = mSupervisor.getDefaultDisplay().createStack(
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
+                .setStack(stack).build();
+
+        // Make sure the top running activity is not affected when keyguard is not locked.
+        assertTopRunningActivity(activity, display);
+
+        // Check to make sure activity not reported when it cannot show on lock and lock is on.
+        doReturn(true).when(keyguard).isKeyguardLocked();
+        assertEquals(activity, display.topRunningActivity());
+        assertNull(display.topRunningActivity(true /* considerKeyguardState */));
+
+        // Change focus to stack with activity.
+        stack.moveToFront("focusChangeToTestStack");
+        assertEquals(stack, display.getFocusedStack());
+        assertEquals(activity, display.topRunningActivity());
+        assertNull(display.topRunningActivity(true /* considerKeyguardState */));
+
+        // Add activity that should be shown on the keyguard.
+        final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
+                .setCreateTask(true)
+                .setStack(stack)
+                .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
+                .build();
+
+        // Ensure the show when locked activity is returned.
+        assertTopRunningActivity(showWhenLockedActivity, display);
+
+        // Change focus back to empty stack.
+        emptyStack.moveToFront("focusChangeToEmptyStack");
+        assertEquals(emptyStack, display.getFocusedStack());
+        // If there is no running activity in focused stack, the running activity in next focusable
+        // stack should be returned.
+        assertTopRunningActivity(showWhenLockedActivity, display);
+    }
+
+    private static void assertTopRunningActivity(ActivityRecord top, ActivityDisplay display) {
+        assertEquals(top, display.topRunningActivity());
+        assertEquals(top, display.topRunningActivity(true /* considerKeyguardState */));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
deleted file mode 100644
index 9de64f2..0000000
--- a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java
+++ /dev/null
@@ -1,144 +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.am;
-
-import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
-
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
-import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.app.ActivityOptions;
-import android.content.pm.ActivityInfo;
-import android.graphics.Rect;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.server.am.LaunchParamsController.LaunchParams;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Tests for exercising resizing bounds due to activity options.
- *
- * Build/Install/Run:
- *  atest FrameworksServicesTests:ActivityLaunchParamsModifierTests
- */
-@MediumTest
-@Presubmit
-@RunWith(AndroidJUnit4.class)
-public class ActivityLaunchParamsModifierTests extends ActivityTestsBase {
-    private ActivityLaunchParamsModifier mModifier;
-    private ActivityTaskManagerService mService;
-    private ActivityStack mStack;
-    private TaskRecord mTask;
-    private ActivityRecord mActivity;
-
-    private LaunchParams mCurrent;
-    private LaunchParams mResult;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mService = createActivityTaskManagerService();
-        mModifier = new ActivityLaunchParamsModifier(mService.mStackSupervisor);
-        mCurrent = new LaunchParams();
-        mResult = new LaunchParams();
-
-
-        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        mTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
-        mActivity = new ActivityBuilder(mService).setTask(mTask).build();
-    }
-
-
-    @Test
-    public void testSkippedInvocations() throws Exception {
-        // No specified activity should be ignored
-        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                null /*activity*/, null /*source*/, null /*options*/, mCurrent, mResult));
-
-        // No specified activity options should be ignored
-        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, null /*options*/, mCurrent, mResult));
-
-        // launch bounds specified should be ignored.
-        final ActivityOptions options = ActivityOptions.makeBasic();
-        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
-
-        // Non-resizeable records should be ignored
-        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
-        assertFalse(mActivity.isResizeable());
-        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
-
-        // make record resizeable
-        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
-        assertTrue(mActivity.isResizeable());
-
-        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
-
-        // Does not support freeform
-        mService.mSupportsFreeformWindowManagement = false;
-        assertFalse(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options));
-        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
-
-        mService.mSupportsFreeformWindowManagement = true;
-        options.setLaunchBounds(new Rect());
-        assertTrue(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options));
-
-        // Invalid bounds
-        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
-        options.setLaunchBounds(new Rect(0, 0, -1, -1));
-        assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
-
-        // Valid bounds should cause the positioner to be applied.
-        options.setLaunchBounds(new Rect(0, 0, 100, 100));
-        assertEquals(RESULT_DONE, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
-    }
-
-    @Test
-    public void testBoundsExtraction() throws Exception {
-        // Make activity resizeable and enable freeform mode.
-        mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
-        mService.mSupportsFreeformWindowManagement = true;
-
-        ActivityOptions options = ActivityOptions.makeBasic();
-        final Rect proposedBounds = new Rect(20, 30, 45, 40);
-        options.setLaunchBounds(proposedBounds);
-
-        assertEquals(RESULT_DONE, mModifier.onCalculate(null /*task*/, null /*layout*/,
-                mActivity, null /*source*/, options /*options*/, mCurrent, mResult));
-        assertEquals(mResult.mBounds, proposedBounds);
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
index 9a7488e..8c27e25 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
@@ -133,7 +133,7 @@
 
     private UidRecord addActiveUidRecord(int uid, long curProcStateSeq,
             long lastNetworkUpdatedProcStateSeq) {
-        final UidRecord record = new UidRecord(uid);
+        final UidRecord record = new UidRecord(uid, null /* atmInternal */);
         record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
         record.curProcStateSeq = curProcStateSeq;
         record.waitingForNetwork = true;
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index c44e492..349c0a37 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -64,6 +64,7 @@
 import android.os.RemoteException;
 import android.os.SystemClock;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -102,6 +103,7 @@
  *     com.android.frameworks.servicestests/androidx.test.runner.AndroidJUnitRunner
  */
 @SmallTest
+@FlakyTest(bugId = 113616538)
 @RunWith(AndroidJUnit4.class)
 public class ActivityManagerServiceTest {
     private static final String TAG = ActivityManagerServiceTest.class.getSimpleName();
@@ -173,7 +175,7 @@
                 true); // expectNotify
 
         // Explicitly setting the seq counter for more verification.
-        mAms.mProcStateSeqCounter = 42;
+        mAms.mProcessList.mProcStateSeqCounter = 42;
 
         // Uid state is not moving from background to foreground or vice versa.
         verifySeqCounterAndInteractions(uidRec,
@@ -253,14 +255,14 @@
     }
 
     private UidRecord addUidRecord(int uid) {
-        final UidRecord uidRec = new UidRecord(uid);
+        final UidRecord uidRec = new UidRecord(uid, null /* atmInternal */);
         uidRec.waitingForNetwork = true;
         uidRec.hasInternetPermission = true;
         mAms.mActiveUids.put(uid, uidRec);
 
         final ProcessRecord appRec = new ProcessRecord(mAms, new ApplicationInfo(), TAG, uid, null);
         appRec.thread = Mockito.mock(IApplicationThread.class);
-        mAms.mLruProcesses.add(appRec);
+        mAms.mProcessList.mLruProcesses.add(appRec);
 
         return uidRec;
     }
@@ -272,14 +274,14 @@
         thread.startAndWait("Unexpected state for " + uidRec);
 
         uidRec.setProcState = prevState;
-        uidRec.curProcState = curState;
+        uidRec.setCurProcState(curState);
         mAms.incrementProcStateSeqAndNotifyAppsLocked();
 
-        assertEquals(expectedGlobalCounter, mAms.mProcStateSeqCounter);
+        assertEquals(expectedGlobalCounter, mAms.mProcessList.mProcStateSeqCounter);
         assertEquals(expectedCurProcStateSeq, uidRec.curProcStateSeq);
 
-        for (int i = mAms.mLruProcesses.size() - 1; i >= 0; --i) {
-            final ProcessRecord app = mAms.mLruProcesses.get(i);
+        for (int i = mAms.mProcessList.getLruSizeLocked() - 1; i >= 0; --i) {
+            final ProcessRecord app = mAms.mProcessList.mLruProcesses.get(i);
             // AMS should notify apps only for block states other than NETWORK_STATE_NO_CHANGE.
             if (app.uid == uidRec.uid && expectedBlockState == NETWORK_STATE_BLOCK) {
                 verify(app.thread).setNetworkBlockSeq(uidRec.curProcStateSeq);
@@ -299,7 +301,7 @@
 
     @Test
     public void testBlockStateForUid() {
-        final UidRecord uidRec = new UidRecord(TEST_UID);
+        final UidRecord uidRec = new UidRecord(TEST_UID, null /* atmInternal */);
         int expectedBlockState;
 
         final String errorTemplate = "Block state should be %s, prevState: %s, curState: %s";
@@ -307,47 +309,48 @@
             return String.format(errorTemplate,
                     valueToString(ActivityManagerService.class, "NETWORK_STATE_", blockState),
                     valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.setProcState),
-                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.curProcState));
+                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.getCurProcState())
+            );
         };
 
         // No change in uid state
         uidRec.setProcState = PROCESS_STATE_RECEIVER;
-        uidRec.curProcState = PROCESS_STATE_RECEIVER;
+        uidRec.setCurProcState(PROCESS_STATE_RECEIVER);
         expectedBlockState = NETWORK_STATE_NO_CHANGE;
         assertEquals(errorMsg.apply(expectedBlockState),
                 expectedBlockState, mAms.getBlockStateForUid(uidRec));
 
         // Foreground to foreground
         uidRec.setProcState = PROCESS_STATE_FOREGROUND_SERVICE;
-        uidRec.curProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+        uidRec.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
         expectedBlockState = NETWORK_STATE_NO_CHANGE;
         assertEquals(errorMsg.apply(expectedBlockState),
                 expectedBlockState, mAms.getBlockStateForUid(uidRec));
 
         // Background to background
         uidRec.setProcState = PROCESS_STATE_CACHED_ACTIVITY;
-        uidRec.curProcState = PROCESS_STATE_CACHED_EMPTY;
+        uidRec.setCurProcState(PROCESS_STATE_CACHED_EMPTY);
         expectedBlockState = NETWORK_STATE_NO_CHANGE;
         assertEquals(errorMsg.apply(expectedBlockState),
                 expectedBlockState, mAms.getBlockStateForUid(uidRec));
 
         // Background to background
         uidRec.setProcState = PROCESS_STATE_NONEXISTENT;
-        uidRec.curProcState = PROCESS_STATE_CACHED_ACTIVITY;
+        uidRec.setCurProcState(PROCESS_STATE_CACHED_ACTIVITY);
         expectedBlockState = NETWORK_STATE_NO_CHANGE;
         assertEquals(errorMsg.apply(expectedBlockState),
                 expectedBlockState, mAms.getBlockStateForUid(uidRec));
 
         // Background to foreground
         uidRec.setProcState = PROCESS_STATE_SERVICE;
-        uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+        uidRec.setCurProcState(PROCESS_STATE_FOREGROUND_SERVICE);
         expectedBlockState = NETWORK_STATE_BLOCK;
         assertEquals(errorMsg.apply(expectedBlockState),
                 expectedBlockState, mAms.getBlockStateForUid(uidRec));
 
         // Foreground to background
         uidRec.setProcState = PROCESS_STATE_TOP;
-        uidRec.curProcState = PROCESS_STATE_LAST_ACTIVITY;
+        uidRec.setCurProcState(PROCESS_STATE_LAST_ACTIVITY);
         expectedBlockState = NETWORK_STATE_UNBLOCK;
         assertEquals(errorMsg.apply(expectedBlockState),
                 expectedBlockState, mAms.getBlockStateForUid(uidRec));
@@ -591,10 +594,10 @@
                 assertNotNull("validateUidRecord should not be null since the change is neither "
                         + "CHANGE_GONE nor CHANGE_GONE_IDLE", validateUidRecord);
                 assertEquals("processState: " + item.processState + " curProcState: "
-                        + validateUidRecord.curProcState + " should have been equal",
-                        item.processState, validateUidRecord.curProcState);
+                        + validateUidRecord.getCurProcState() + " should have been equal",
+                        item.processState, validateUidRecord.getCurProcState());
                 assertEquals("processState: " + item.processState + " setProcState: "
-                        + validateUidRecord.curProcState + " should have been equal",
+                        + validateUidRecord.getCurProcState() + " should have been equal",
                         item.processState, validateUidRecord.setProcState);
                 if (item.change == UidRecord.CHANGE_IDLE) {
                     assertTrue("UidRecord.idle should be updated to true for CHANGE_IDLE",
@@ -624,7 +627,7 @@
 
     @Test
     public void testEnqueueUidChangeLocked_procStateSeqUpdated() {
-        final UidRecord uidRecord = new UidRecord(TEST_UID);
+        final UidRecord uidRecord = new UidRecord(TEST_UID, null /* atmInternal */);
         uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
 
         // Verify with no pending changes for TEST_UID.
@@ -670,7 +673,7 @@
     @MediumTest
     @Test
     public void testEnqueueUidChangeLocked_dispatchUidsChanged() {
-        final UidRecord uidRecord = new UidRecord(TEST_UID);
+        final UidRecord uidRecord = new UidRecord(TEST_UID, null /* atmInternal */);
         final int expectedProcState = PROCESS_STATE_SERVICE;
         uidRecord.setProcState = expectedProcState;
         uidRecord.curProcStateSeq = TEST_PROC_STATE_SEQ1;
@@ -742,7 +745,7 @@
     private void verifyWaitingForNetworkStateUpdate(long curProcStateSeq,
             long lastDispatchedProcStateSeq, long lastNetworkUpdatedProcStateSeq,
             final long procStateSeqToWait, boolean expectWait) throws Exception {
-        final UidRecord record = new UidRecord(Process.myUid());
+        final UidRecord record = new UidRecord(Process.myUid(), null /* atmInternal */);
         record.curProcStateSeq = curProcStateSeq;
         record.lastDispatchedProcStateSeq = lastDispatchedProcStateSeq;
         record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
@@ -829,4 +832,4 @@
             mRestricted = restricted;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
index ba25b16..2dfb375 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerTest.java
@@ -16,38 +16,59 @@
 
 package com.android.server.am;
 
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+
 import android.app.ActivityManager;
+import android.app.ActivityManager.RecentTaskInfo;
 import android.app.IActivityManager;
-import android.os.ServiceManager;
-import android.os.UserHandle;
 import android.os.RemoteException;
-import android.test.AndroidTestCase;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Before;
+import org.junit.Test;
 
 import java.util.List;
 
-public class ActivityManagerTest extends AndroidTestCase {
+import androidx.test.filters.FlakyTest;
 
-    IActivityManager service;
-    @Override
+/**
+ * Tests for {@link ActivityManager}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.am.ActivityManagerTest
+ */
+@Presubmit
+@FlakyTest(detail = "Promote to presubmit if stable")
+public class ActivityManagerTest {
+
+    private IActivityManager service;
+
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         service = ActivityManager.getService();
     }
 
+    @Test
     public void testTaskIdsForRunningUsers() throws RemoteException {
-        for(int userId : service.getRunningUserIds()) {
+        int[] runningUserIds = service.getRunningUserIds();
+        assertThat(runningUserIds).isNotEmpty();
+        for (int userId : runningUserIds) {
             testTaskIdsForUser(userId);
         }
     }
 
     private void testTaskIdsForUser(int userId) throws RemoteException {
-        List<ActivityManager.RecentTaskInfo> recentTasks = service.getRecentTasks(
-                100, 0, userId).getList();
-        if(recentTasks != null) {
-            for(ActivityManager.RecentTaskInfo recentTask : recentTasks) {
-                int taskId = recentTask.persistentId;
+        List<?> recentTasks = service.getRecentTasks(100, 0, userId).getList();
+        if (recentTasks != null) {
+            for (Object elem : recentTasks) {
+                assertThat(elem).isInstanceOf(RecentTaskInfo.class);
+                RecentTaskInfo recentTask = (RecentTaskInfo) elem;
+                int taskId = recentTask.taskId;
                 assertEquals("The task id " + taskId + " should not belong to user " + userId,
-                        taskId / UserHandle.PER_USER_RANGE, userId);
+                             taskId / UserHandle.PER_USER_RANGE, userId);
             }
         }
     }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index 0345a81..2c993d3 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -18,13 +18,13 @@
 
 import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
 import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
-import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
 
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
 import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
@@ -33,10 +33,14 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.contains;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -232,6 +236,7 @@
         doReturn(displaySleeping).when(display).isSleeping();
         doReturn(keyguardShowing).when(keyguard).isKeyguardOrAodShowing(anyInt());
 
+        doReturn(isFocusedStack).when(stack).isFocusedStackOnDisplay();
         doReturn(isFocusedStack ? stack : null).when(display).getFocusedStack();
         mSupervisor.applySleepTokensLocked(true);
         verify(stack, times(expectWakeFromSleep ? 1 : 0)).awakeFromSleepingLocked();
@@ -301,62 +306,6 @@
     }
 
     /**
-     * Verifies the correct activity is returned when querying the top running activity.
-     */
-    @Test
-    public void testTopRunningActivity() throws Exception {
-        // Create stack to hold focus
-        final ActivityDisplay display = mService.mStackSupervisor.getDefaultDisplay();
-        final ActivityStack emptyStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_STANDARD, true /* onTop */);
-
-        final KeyguardController keyguard = mSupervisor.getKeyguardController();
-        final ActivityStack stack = mService.mStackSupervisor.getDefaultDisplay().createStack(
-                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
-                .setStack(stack).build();
-
-        // Make sure the top running activity is not affected when keyguard is not locked
-        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
-        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked(
-                true /* considerKeyguardState */));
-
-        // Check to make sure activity not reported when it cannot show on lock and lock is on.
-        doReturn(true).when(keyguard).isKeyguardLocked();
-        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
-        assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
-                true /* considerKeyguardState */));
-
-        // Change focus to stack with activity.
-        stack.moveToFront("focusChangeToTestStack");
-        assertEquals(stack, display.getFocusedStack());
-        assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
-        assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
-                true /* considerKeyguardState */));
-
-        // Add activity that should be shown on the keyguard.
-        final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
-                .setCreateTask(true)
-                .setStack(stack)
-                .setActivityFlags(FLAG_SHOW_WHEN_LOCKED)
-                .build();
-
-        // Ensure the show when locked activity is returned.
-        assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked());
-        assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
-                true /* considerKeyguardState */));
-
-        // Change focus back to empty stack
-        emptyStack.moveToFront("focusChangeToEmptyStack");
-        assertEquals(emptyStack, display.getFocusedStack());
-        // Looking for running activity only in top and focused stack, so nothing should be returned
-        // from empty stack.
-        assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked());
-        assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
-                true /* considerKeyguardState */));
-    }
-
-    /**
      * Verify that split-screen primary stack will be chosen if activity is launched that targets
      * split-screen secondary, but a matching existing instance is found on top of split-screen
      * primary stack.
@@ -402,4 +351,83 @@
         assertEquals(primaryStack.getBounds(), STACK_SIZE);
         assertEquals(task.getBounds(), TASK_SIZE);
     }
+
+    /**
+     * Verify that home stack would be moved to front when the top activity is Recents.
+     */
+    @Test
+    public void testFindTaskToMoveToFrontWhenRecentsOnTop() throws Exception {
+        // Create stack/task on default display.
+        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+        final ActivityStack targetStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final TaskRecord targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+
+        // Create Recents on top of the display.
+        final ActivityStack stack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+        new ActivityBuilder(mService).setTask(task).build();
+
+        final String reason = "findTaskToMoveToFront";
+        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
+                false);
+
+        verify(display).moveHomeStackToFront(contains(reason));
+    }
+
+    /**
+     * Verify that home stack won't be moved to front if the top activity on other display is
+     * Recents.
+     */
+    @Test
+    public void testFindTaskToMoveToFrontWhenRecentsOnOtherDisplay() throws Exception {
+        // Create stack/task on default display.
+        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+        final ActivityStack targetStack = display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */);
+        final TaskRecord targetTask = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+
+        // Create Recents on secondary display.
+        final TestActivityDisplay secondDisplay = addNewActivityDisplayAt(
+                ActivityDisplay.POSITION_TOP);
+        final ActivityStack stack = secondDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_RECENTS, true /* onTop */);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+        new ActivityBuilder(mService).setTask(task).build();
+
+        final String reason = "findTaskToMoveToFront";
+        mSupervisor.findTaskToMoveToFront(targetTask, 0, ActivityOptions.makeBasic(), reason,
+                false);
+
+        verify(display, never()).moveHomeStackToFront(contains(reason));
+    }
+
+    /**
+     * Verify if a stack is not at the topmost position, it should be able to resume its activity if
+     * the stack is the top focused.
+     */
+    @Test
+    public void testResumeActivityWhenNonTopmostStackIsTopFocused() throws Exception {
+        // Create a stack at bottom.
+        final ActivityDisplay display = mSupervisor.getDefaultDisplay();
+        final ActivityStack targetStack = spy(display.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, false /* onTop */));
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(targetStack).build();
+        final ActivityRecord activity = new ActivityBuilder(mService).setTask(task).build();
+        display.positionChildAtBottom(targetStack);
+
+        // Assume the stack is not at the topmost position (e.g. behind always-on-top stacks) but it
+        // is the current top focused stack.
+        assertFalse(targetStack.isTopStackOnDisplay());
+        doReturn(targetStack).when(mSupervisor).getTopDisplayFocusedStack();
+
+        // Use the stack as target to resume.
+        mSupervisor.resumeFocusedStacksTopActivitiesLocked(
+                targetStack, activity, null /* targetOptions */);
+
+        // Verify the target stack should resume its activity.
+        verify(targetStack, times(1)).resumeTopActivityUncheckedLocked(
+                eq(activity), eq(null /* targetOptions */));
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
index ab814ee..53f67af 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackTests.java
@@ -26,6 +26,9 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 
+import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
+import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
+import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
 import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
@@ -35,9 +38,14 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 
 import android.content.pm.ActivityInfo;
 import android.os.UserHandle;
@@ -71,8 +79,8 @@
 
         setupActivityTaskManagerService();
         mDefaultDisplay = mSupervisor.getDefaultDisplay();
-        mStack = mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
-                true /* onTop */);
+        mStack = spy(mDefaultDisplay.createStack(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD,
+                true /* onTop */));
         mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
     }
 
@@ -654,6 +662,39 @@
     }
 
     @Test
+    public void testFinishCurrentActivity() {
+        // Create 2 activities on a new display.
+        final ActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
+        final ActivityStack stack1 = createStackForShouldBeVisibleTest(display,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final ActivityStack stack2 = createStackForShouldBeVisibleTest(display,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+
+        // There is still an activity1 in stack1 so the activity2 should be added to finishing list
+        // that will be destroyed until idle.
+        final ActivityRecord activity2 = finishCurrentActivity(stack2);
+        assertEquals(FINISHING, activity2.getState());
+        assertTrue(mSupervisor.mFinishingActivities.contains(activity2));
+
+        // The display becomes empty. Since there is no next activity to be idle, the activity
+        // should be destroyed immediately with updating configuration to restore original state.
+        final ActivityRecord activity1 = finishCurrentActivity(stack1);
+        assertEquals(DESTROYING, activity1.getState());
+        verify(mSupervisor).ensureVisibilityAndConfig(eq(null) /* starting */,
+                eq(display.mDisplayId), anyBoolean(), anyBoolean());
+    }
+
+    private ActivityRecord finishCurrentActivity(ActivityStack stack) {
+        final ActivityRecord activity = stack.topRunningActivityLocked();
+        assertNotNull(activity);
+        activity.setState(PAUSED, "finishCurrentActivity");
+        activity.makeFinishingLocked();
+        stack.finishCurrentActivityLocked(activity, ActivityStack.FINISH_AFTER_VISIBLE,
+                false /* oomAdj */, "finishCurrentActivity");
+        return activity;
+    }
+
+    @Test
     public void testShouldSleepActivities() throws Exception {
         // When focused activity and keyguard is going away, we should not sleep regardless
         // of the display state
@@ -720,7 +761,7 @@
         doReturn(display).when(mSupervisor).getActivityDisplay(anyInt());
         doReturn(keyguardGoingAway).when(keyguardController).isKeyguardGoingAway();
         doReturn(displaySleeping).when(display).isSleeping();
-        doReturn(focusedStack ? mStack : null).when(mSupervisor).getTopDisplayFocusedStack();
+        doReturn(focusedStack).when(mStack).isFocusedStackOnDisplay();
 
         assertEquals(expected, mStack.shouldSleepActivities());
     }
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
index 86541b9..270d394 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartInterceptorTest.java
@@ -35,6 +35,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.os.UserHandle;
 import android.os.UserManager;
@@ -108,7 +109,6 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mService.mAm = mAm;
         mService.mAmInternal = mAmInternal;
         mInterceptor = new ActivityStartInterceptor(mService, mSupervisor, mContext);
         mInterceptor.setStates(TEST_USER_ID, TEST_REAL_CALLING_PID, TEST_REAL_CALLING_UID,
@@ -165,17 +165,20 @@
     public void testSuspendedPackage() {
         mAInfo.applicationInfo.flags = FLAG_SUSPENDED;
         final String suspendingPackage = "com.test.suspending.package";
-        final String dialogMessage = "Test Message";
+        final SuspendDialogInfo dialogInfo = new SuspendDialogInfo.Builder()
+                .setMessage("Test Message")
+                .setIcon(0x11110001)
+                .build();
         when(mPackageManagerInternal.getSuspendingPackage(TEST_PACKAGE_NAME, TEST_USER_ID))
                 .thenReturn(suspendingPackage);
-        when(mPackageManagerInternal.getSuspendedDialogMessage(TEST_PACKAGE_NAME, TEST_USER_ID))
-                .thenReturn(dialogMessage);
+        when(mPackageManagerInternal.getSuspendedDialogInfo(TEST_PACKAGE_NAME, TEST_USER_ID))
+                .thenReturn(dialogInfo);
         // THEN calling intercept returns true
         assertTrue(mInterceptor.intercept(null, null, mAInfo, null, null, 0, 0, null));
 
         // Check intent parameters
-        assertEquals(dialogMessage,
-                mInterceptor.mIntent.getStringExtra(SuspendedAppActivity.EXTRA_DIALOG_MESSAGE));
+        assertEquals(dialogInfo,
+                mInterceptor.mIntent.getParcelableExtra(SuspendedAppActivity.EXTRA_DIALOG_INFO));
         assertEquals(suspendingPackage,
                 mInterceptor.mIntent.getStringExtra(SuspendedAppActivity.EXTRA_SUSPENDING_PACKAGE));
         assertEquals(TEST_PACKAGE_NAME,
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
index bac4a52..ba64b51 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java
@@ -37,7 +37,8 @@
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 
 import static com.android.server.am.ActivityDisplay.POSITION_BOTTOM;
-import static com.android.server.am.ActivityManagerService.ANIMATE;
+import static com.android.server.am.ActivityDisplay.POSITION_TOP;
+import static com.android.server.am.ActivityTaskManagerService.ANIMATE;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -48,6 +49,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -206,11 +208,11 @@
         prepareStarter(launchFlags);
         final IApplicationThread caller = mock(IApplicationThread.class);
 
-        // If no caller app, return {@code null} {@link ProcessRecord}.
-        final ProcessRecord record = containsConditions(preconditions, PRECONDITION_NO_CALLER_APP)
-                ? null : new ProcessRecord(service.mAm, mock(ApplicationInfo.class), null, 0, null);
-
-        doReturn(record).when(service.mAm).getRecordForAppLocked(anyObject());
+        final WindowProcessController wpc =
+                containsConditions(preconditions, PRECONDITION_NO_CALLER_APP)
+                ? null : new WindowProcessController(
+                        service, mock(ApplicationInfo.class),null, 0, -1, null, null, null);
+        doReturn(wpc).when(service).getProcessController(anyObject());
 
         final Intent intent = new Intent();
         intent.setFlags(launchFlags);
@@ -354,10 +356,12 @@
                 invocation -> {
                     throw new RuntimeException("Not stubbed");
                 });
-        doReturn(mockPackageManager).when(mService.mAm).getPackageManagerInternalLocked();
+        doReturn(mockPackageManager).when(mService).getPackageManagerInternalLocked();
 
         // Never review permissions
         doReturn(false).when(mockPackageManager).isPermissionsReviewRequired(any(), anyInt());
+        doNothing().when(mockPackageManager).grantEphemeralAccess(
+                anyInt(), any(), anyInt(), anyInt());
 
         final Intent intent = new Intent();
         intent.addFlags(launchFlags);
@@ -408,8 +412,9 @@
                 .setActivityOptions(new SafeActivityOptions(options))
                 .execute();
 
-        // verify that values are passed to the modifier.
-        verify(modifier, times(1)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options),
+        // verify that values are passed to the modifier. Values are passed twice -- once for
+        // setting initial state, another when task is created.
+        verify(modifier, times(2)).onCalculate(any(), eq(windowLayout), any(), any(), eq(options),
                 any(), any());
     }
 
@@ -510,7 +515,7 @@
      */
     @Test
     public void testActivityStartsLogging_noLoggingWhenDisabled() {
-        doReturn(false).when(mService.mAm).isActivityStartsLoggingEnabled();
+        doReturn(false).when(mService).isActivityStartsLoggingEnabled();
         doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger();
 
         ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK);
@@ -528,7 +533,7 @@
     @Test
     public void testActivityStartsLogging_logsWhenEnabled() {
         // note: conveniently this package doesn't have any activity visible
-        doReturn(true).when(mService.mAm).isActivityStartsLoggingEnabled();
+        doReturn(true).when(mService).isActivityStartsLoggingEnabled();
         doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger();
 
         ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
@@ -558,23 +563,13 @@
                 false /* mockGetLaunchStack */);
 
         // Create a secondary display at bottom.
-        final TestActivityDisplay secondaryDisplay = spy(addNewActivityDisplayAt(POSITION_BOTTOM));
+        final TestActivityDisplay secondaryDisplay = spy(createNewActivityDisplay());
+        mSupervisor.addChild(secondaryDisplay, POSITION_BOTTOM);
         final ActivityStack stack = secondaryDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
                 ACTIVITY_TYPE_STANDARD, true /* onTop */);
 
         // Create an activity record on the top of secondary display.
-        final ComponentName componentName = ComponentName.createRelative(
-                DEFAULT_COMPONENT_PACKAGE_NAME,
-                DEFAULT_COMPONENT_PACKAGE_NAME + ".ReusableActivity");
-        final TaskRecord taskRecord = new TaskBuilder(mSupervisor)
-                .setComponent(componentName)
-                .setStack(stack)
-                .build();
-        final ActivityRecord topActivityOnSecondaryDisplay = new ActivityBuilder(mService)
-                .setComponent(componentName)
-                .setLaunchMode(LAUNCH_SINGLE_TASK)
-                .setTask(taskRecord)
-                .build();
+        final ActivityRecord topActivityOnSecondaryDisplay = createSingleTaskActivityOn(stack);
 
         // Put an activity on default display as the top focused activity.
         new ActivityBuilder(mService).setCreateTask(true).build();
@@ -596,6 +591,59 @@
     }
 
     /**
+     * This test ensures that when starting an existing non-top single task activity on secondary
+     * display which is the top focused display, it should bring the task to front without creating
+     * unused stack.
+     */
+    @Test
+    public void testBringTaskToFrontOnSecondaryDisplay() {
+        final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK,
+                false /* mockGetLaunchStack */);
+
+        // Create a secondary display with an activity.
+        final TestActivityDisplay secondaryDisplay = spy(createNewActivityDisplay());
+        mSupervisor.addChild(secondaryDisplay, POSITION_TOP);
+        final ActivityRecord singleTaskActivity = createSingleTaskActivityOn(
+                secondaryDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
+                        ACTIVITY_TYPE_STANDARD, false /* onTop */));
+
+        // Create another activity on top of the secondary display.
+        final ActivityStack topStack = secondaryDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
+                ACTIVITY_TYPE_STANDARD, true /* onTop */);
+        final TaskRecord topTask = new TaskBuilder(mSupervisor).setStack(topStack).build();
+        new ActivityBuilder(mService).setTask(topTask).build();
+
+        // Start activity with the same intent as {@code singleTaskActivity} on secondary display.
+        final ActivityOptions options = ActivityOptions.makeBasic()
+                .setLaunchDisplayId(secondaryDisplay.mDisplayId);
+        final int result = starter.setReason("testBringTaskToFrontOnSecondaryDisplay")
+                .setIntent(singleTaskActivity.intent)
+                .setActivityOptions(options.toBundle())
+                .execute();
+
+        // Ensure result is moving existing task to front.
+        assertEquals(START_TASK_TO_FRONT, result);
+
+        // Ensure secondary display only creates two stacks.
+        verify(secondaryDisplay, times(2)).createStack(anyInt(), anyInt(), anyBoolean());
+    }
+
+    private ActivityRecord createSingleTaskActivityOn(ActivityStack stack) {
+        final ComponentName componentName = ComponentName.createRelative(
+                DEFAULT_COMPONENT_PACKAGE_NAME,
+                DEFAULT_COMPONENT_PACKAGE_NAME + ".SingleTaskActivity");
+        final TaskRecord taskRecord = new TaskBuilder(mSupervisor)
+                .setComponent(componentName)
+                .setStack(stack)
+                .build();
+        return new ActivityBuilder(mService)
+                .setComponent(componentName)
+                .setLaunchMode(LAUNCH_SINGLE_TASK)
+                .setTask(taskRecord)
+                .build();
+    }
+
+    /**
      * This test ensures that a reused top activity in the top focused stack is able to be
      * reparented to another display.
      */
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 22add01..01d51e4 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -58,8 +58,9 @@
 import android.graphics.Rect;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerGlobal;
-import android.os.HandlerThread;
+import android.os.Handler;
 import android.os.Looper;
+import android.os.Process;
 import android.os.UserHandle;
 import android.service.voice.IVoiceInteractionSession;
 import android.testing.DexmakerShareClassLoaderRule;
@@ -69,7 +70,9 @@
 import androidx.test.InstrumentationRegistry;
 
 import com.android.internal.app.IVoiceInteractor;
+import com.android.server.AppOpsService;
 import com.android.server.AttributeCache;
+import com.android.server.ServiceThread;
 import com.android.server.wm.AppWindowContainerController;
 import com.android.server.wm.PinnedStackWindowController;
 import com.android.server.wm.RootWindowContainerController;
@@ -82,6 +85,7 @@
 import org.junit.Before;
 import org.mockito.MockitoAnnotations;
 
+import java.io.File;
 import java.util.List;
 
 /**
@@ -97,7 +101,7 @@
             new DexmakerShareClassLoaderRule();
 
     private final Context mContext = InstrumentationRegistry.getContext();
-    private HandlerThread mHandlerThread;
+    final TestInjector mTestInjector = new TestInjector();
 
     ActivityTaskManagerService mService;
     ActivityStackSupervisor mSupervisor;
@@ -115,13 +119,12 @@
             MockitoAnnotations.initMocks(this);
             AttributeCache.init(mContext);
         }
-        mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
-        mHandlerThread.start();
+        mTestInjector.setUp();
     }
 
     @After
     public void tearDown() {
-        mHandlerThread.quitSafely();
+        mTestInjector.tearDown();
     }
 
     protected ActivityTaskManagerService createActivityTaskManagerService() {
@@ -143,7 +146,7 @@
     }
 
     ActivityManagerService setupActivityManagerService(TestActivityTaskManagerService atm) {
-        final TestActivityManagerService am = spy(new TestActivityManagerService(mContext, atm));
+        final TestActivityManagerService am = spy(new TestActivityManagerService(mTestInjector));
         setupActivityManagerService(am, atm);
         return am;
     }
@@ -162,23 +165,27 @@
 
     void setupActivityManagerService(
             TestActivityManagerService am, TestActivityTaskManagerService atm) {
-        atm.setActivityManagerService(am);
+        atm.setActivityManagerService(am, am.mHandlerThread.getLooper(), am.mIntentFirewall,
+                am.mPendingIntentController);
         atm.mAmInternal = am.getLocalService();
         am.mAtmInternal = atm.getLocalService();
         // Makes sure the supervisor is using with the spy object.
         atm.mStackSupervisor.setService(atm);
         doReturn(mock(IPackageManager.class)).when(am).getPackageManager();
+        PackageManagerInternal mockPackageManager = mock(PackageManagerInternal.class);
+        doReturn(mockPackageManager).when(am).getPackageManagerInternalLocked();
+        doReturn(null).when(mockPackageManager).getDefaultHomeActivity(anyInt());
         doNothing().when(am).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt());
+        am.mActivityTaskManager = atm;
         am.mWindowManager = prepareMockWindowManager();
         atm.setWindowManager(am.mWindowManager);
 
         // Put a home stack on the default display, so that we'll always have something focusable.
         final TestActivityStackSupervisor supervisor =
                 (TestActivityStackSupervisor) atm.mStackSupervisor;
-        supervisor.mHomeStack = supervisor.mDisplay.createStack(WINDOWING_MODE_FULLSCREEN,
-                ACTIVITY_TYPE_HOME, ON_TOP);
+        supervisor.mDisplay.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP);
         final TaskRecord task = new TaskBuilder(atm.mStackSupervisor)
-                .setStack(supervisor.mHomeStack).build();
+                .setStack(supervisor.getDefaultDisplay().getHomeStack()).build();
         new ActivityBuilder(atm).setTask(task).build();
     }
 
@@ -189,8 +196,6 @@
         // An id appended to the end of the component name to make it unique
         private static int sCurrentActivityId = 0;
 
-
-
         private final ActivityTaskManagerService mService;
 
         private ComponentName mComponent;
@@ -447,9 +452,6 @@
             final ActivityStackSupervisor supervisor = spy(createTestSupervisor());
             final KeyguardController keyguardController = mock(KeyguardController.class);
 
-            // No home stack is set.
-            doNothing().when(supervisor).moveHomeStackToFront(any());
-            doReturn(true).when(supervisor).moveHomeStackTaskToTop(any());
             // Invoked during {@link ActivityStack} creation.
             doNothing().when(supervisor).updateUIDsPresentOnDisplay();
             // Always keep things awake.
@@ -487,6 +489,40 @@
         }
     }
 
+    private static class TestInjector extends ActivityManagerService.Injector {
+        private ServiceThread mHandlerThread;
+
+        @Override
+        public Context getContext() {
+            return InstrumentationRegistry.getContext();
+        }
+
+        @Override
+        public AppOpsService getAppOpsService(File file, Handler handler) {
+            return null;
+        }
+
+        @Override
+        public Handler getUiHandler(ActivityManagerService service) {
+            return mHandlerThread.getThreadHandler();
+        }
+
+        @Override
+        public boolean isNetworkRestrictedForUid(int uid) {
+            return false;
+        }
+
+        void setUp() {
+            mHandlerThread = new ServiceThread("ActivityTestsThread",
+                    Process.THREAD_PRIORITY_DEFAULT, true /* allowIo */);
+            mHandlerThread.start();
+        }
+
+        void tearDown() {
+            mHandlerThread.quitSafely();
+        }
+    }
+
     /**
      * An {@link ActivityManagerService} subclass which provides a test
      * {@link ActivityStackSupervisor}.
@@ -495,8 +531,8 @@
 
         private ActivityManagerInternal mInternal;
 
-        TestActivityManagerService(Context context, TestActivityTaskManagerService atm) {
-            super(context, atm);
+        TestActivityManagerService(TestInjector testInjector) {
+            super(testInjector, testInjector.mHandlerThread);
             mUgmInternal = mock(UriGrantsManagerInternal.class);
         }
 
@@ -546,6 +582,11 @@
         ActivityDisplay getDefaultDisplay() {
             return mDisplay;
         }
+
+        @Override
+        void setWindowManager(WindowManagerService wm) {
+            mWindowManager = wm;
+        }
     }
 
     protected static class TestActivityDisplay extends ActivityDisplay {
diff --git a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
index 3819e21..06d41f1 100644
--- a/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AppErrorDialogTest.java
@@ -21,6 +21,7 @@
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.annotation.UiThreadTest;
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -37,6 +38,7 @@
  */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
+@FlakyTest(bugId = 113616538)
 public class AppErrorDialogTest {
 
     private Context mContext;
diff --git a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
index a030210..1b823ff 100644
--- a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
@@ -46,6 +46,7 @@
 import android.view.IWindowManager;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.MediumTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -67,6 +68,7 @@
  * runtest --path frameworks/base/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java
  */
 @MediumTest
+@FlakyTest(bugId = 113616538)
 @RunWith(AndroidJUnit4.class)
 public class AssistDataRequesterTest extends ActivityTestsBase {
 
diff --git a/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java b/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java
index 62c5734..75f7c4c 100644
--- a/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/BroadcastRecordTest.java
@@ -45,7 +45,7 @@
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-public class BroadcastRecordTest extends ActivityTestsBase {
+public class BroadcastRecordTest {
 
     @Test
     public void testCleanupDisabledPackageReceivers() {
diff --git a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
index fe8256e..719e0ed 100644
--- a/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/CoreSettingsObserverTest.java
@@ -132,15 +132,36 @@
                 settingsBundle.containsKey(TEST_SETTING_SYSTEM_STRING));
     }
 
+    @Test
+    public void testPopulateSettings_settingDeleted() {
+        Settings.Secure.putInt(mContentResolver, TEST_SETTING_SECURE_INT, TEST_INT);
+        Settings.Global.putFloat(mContentResolver, TEST_SETTING_GLOBAL_FLOAT, TEST_FLOAT);
+        Settings.System.putString(mContentResolver, TEST_SETTING_SYSTEM_STRING, TEST_STRING);
+
+        Bundle settingsBundle = getPopulatedBundle();
+
+        assertEquals("Unexpected value of " + TEST_SETTING_SECURE_INT,
+                TEST_INT, settingsBundle.getInt(TEST_SETTING_SECURE_INT));
+        assertEquals("Unexpected value of " + TEST_SETTING_GLOBAL_FLOAT,
+                TEST_FLOAT, settingsBundle.getFloat(TEST_SETTING_GLOBAL_FLOAT), 0);
+        assertEquals("Unexpected value of " + TEST_SETTING_SYSTEM_STRING,
+                TEST_STRING, settingsBundle.getString(TEST_SETTING_SYSTEM_STRING));
+
+        Settings.Global.putString(mContentResolver, TEST_SETTING_GLOBAL_FLOAT, null);
+        settingsBundle = getPopulatedBundle();
+
+        assertFalse("Bundle should not contain " + TEST_SETTING_GLOBAL_FLOAT,
+                settingsBundle.containsKey(TEST_SETTING_GLOBAL_FLOAT));
+        assertEquals("Unexpected value of " + TEST_SETTING_SECURE_INT,
+                TEST_INT, settingsBundle.getInt(TEST_SETTING_SECURE_INT));
+        assertEquals("Unexpected value of " + TEST_SETTING_SYSTEM_STRING,
+                TEST_STRING, settingsBundle.getString(TEST_SETTING_SYSTEM_STRING));
+
+    }
+
     private Bundle getPopulatedBundle() {
-        final Bundle settingsBundle = new Bundle();
-        mCoreSettingsObserver.populateSettings(settingsBundle,
-                CoreSettingsObserver.sGlobalSettingToTypeMap);
-        mCoreSettingsObserver.populateSettings(settingsBundle,
-                CoreSettingsObserver.sSecureSettingToTypeMap);
-        mCoreSettingsObserver.populateSettings(settingsBundle,
-                CoreSettingsObserver.sSystemSettingToTypeMap);
-        return settingsBundle;
+        mCoreSettingsObserver.onChange(false);
+        return mCoreSettingsObserver.getCoreSettingsLocked();
     }
 
     private class TestInjector extends Injector {
diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
index d4bab2e..2fb10e1 100644
--- a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java
@@ -17,6 +17,8 @@
 package com.android.server.am;
 
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
 
 import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
 import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_DONE;
@@ -189,6 +191,35 @@
     }
 
     /**
+     * Tests preferred display id calculation for VR.
+     */
+    @Test
+    public void testVrPreferredDisplay() {
+        final int vr2dDisplayId = 1;
+        mService.mVr2dDisplayId = vr2dDisplayId;
+
+        final LaunchParams result = new LaunchParams();
+        final ActivityRecord vrActivity = new ActivityBuilder(mService).build();
+        vrActivity.requestedVrComponent = vrActivity.realActivity;
+
+        // VR activities should always land on default display.
+        mController.calculate(null /*task*/, null /*layout*/, vrActivity /*activity*/,
+                null /*source*/, null /*options*/, result);
+        assertEquals(DEFAULT_DISPLAY, result.mPreferredDisplayId);
+
+        // Otherwise, always lands on VR 2D display.
+        final ActivityRecord vr2dActivity = new ActivityBuilder(mService).build();
+        mController.calculate(null /*task*/, null /*layout*/, vr2dActivity /*activity*/,
+                null /*source*/, null /*options*/, result);
+        assertEquals(vr2dDisplayId, result.mPreferredDisplayId);
+        mController.calculate(null /*task*/, null /*layout*/, null /*activity*/, null /*source*/,
+                null /*options*/, result);
+        assertEquals(vr2dDisplayId, result.mPreferredDisplayId);
+
+        mService.mVr2dDisplayId = INVALID_DISPLAY;
+    }
+
+    /**
      * Ensures that {@link LaunchParamsModifier} requests specifying display id during
      * layout are honored.
      */
diff --git a/services/tests/servicestests/src/com/android/server/am/PersisterQueueTests.java b/services/tests/servicestests/src/com/android/server/am/PersisterQueueTests.java
new file mode 100644
index 0000000..d7794b0
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/PersisterQueueTests.java
@@ -0,0 +1,300 @@
+/*
+ * 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.am;
+
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertSame;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+
+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 java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Predicate;
+
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+/**
+ * atest PersisterQueueTests
+ */
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+@Presubmit
+@FlakyTest(detail = "Confirm stable in post-submit before removing")
+public class PersisterQueueTests implements PersisterQueue.Listener {
+    private static final long INTER_WRITE_DELAY_MS = 50;
+    private static final long PRE_TASK_DELAY_MS = 300;
+    // We allow at most 1s more than the expected timeout.
+    private static final long TIMEOUT_ALLOWANCE = 100;
+
+    private static final Predicate<MatchingTestItem> TEST_ITEM_PREDICATE = item -> item.mMatching;
+
+    private AtomicInteger mItemCount;
+    private CountDownLatch mSetUpLatch;
+    private volatile CountDownLatch mLatch;
+    private List<Boolean> mProbablyDoneResults;
+
+    private PersisterQueue mTarget;
+
+    @Before
+    public void setUp() throws Exception {
+        mItemCount = new AtomicInteger(0);
+        mProbablyDoneResults = new ArrayList<>();
+        mSetUpLatch = new CountDownLatch(1);
+
+        mTarget = new PersisterQueue(INTER_WRITE_DELAY_MS, PRE_TASK_DELAY_MS);
+        mTarget.addListener(this);
+        mTarget.startPersisting();
+
+        assertTrue("Target didn't call callback on start up.",
+                mSetUpLatch.await(TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mTarget.stopPersisting();
+    }
+
+    @Test
+    public void testCallCallbackOnStartUp() throws Exception {
+        // The onPreProcessItem() must be called on start up.
+        assertEquals(1, mProbablyDoneResults.size());
+        // The last one must be called with probably done being true.
+        assertTrue("The last probablyDone must be true.", mProbablyDoneResults.get(0));
+    }
+
+    @Test
+    public void testProcessOneItem() throws Exception {
+        mLatch = new CountDownLatch(1);
+
+        final long dispatchTime = SystemClock.uptimeMillis();
+        mTarget.addItem(new TestItem(), false);
+        assertTrue("Target didn't call callback enough times.",
+                mLatch.await(PRE_TASK_DELAY_MS + TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+        assertEquals("Target didn't process item.", 1, mItemCount.get());
+        final long processDuration = SystemClock.uptimeMillis() - dispatchTime;
+        assertTrue("Target didn't wait enough time before processing item. duration: "
+                        + processDuration + "ms pretask delay: " + PRE_TASK_DELAY_MS + "ms",
+                processDuration >= PRE_TASK_DELAY_MS);
+
+        // Once before processing this item, once after that.
+        assertEquals(2, mProbablyDoneResults.size());
+        // The last one must be called with probably done being true.
+        assertTrue("The last probablyDone must be true.", mProbablyDoneResults.get(1));
+    }
+
+    @Test
+    public void testProcessOneItem_Flush() throws Exception {
+        mLatch = new CountDownLatch(1);
+
+        final long dispatchTime = SystemClock.uptimeMillis();
+        mTarget.addItem(new TestItem(), true);
+        assertTrue("Target didn't call callback enough times.",
+                mLatch.await(TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+        assertEquals("Target didn't process item.", 1, mItemCount.get());
+        final long processDuration = SystemClock.uptimeMillis() - dispatchTime;
+        assertTrue("Target didn't process item immediately when flushing. duration: "
+                        + processDuration + "ms pretask delay: "
+                        + PRE_TASK_DELAY_MS + "ms",
+                processDuration < PRE_TASK_DELAY_MS);
+
+        // Once before processing this item, once after that.
+        assertEquals(2, mProbablyDoneResults.size());
+        // The last one must be called with probably done being true.
+        assertTrue("The last probablyDone must be true.", mProbablyDoneResults.get(1));
+    }
+
+    @Test
+    public void testProcessTwoItems() throws Exception {
+        mLatch = new CountDownLatch(2);
+
+        final long dispatchTime = SystemClock.uptimeMillis();
+        mTarget.addItem(new TestItem(), false);
+        mTarget.addItem(new TestItem(), false);
+        assertTrue("Target didn't call callback enough times.",
+                mLatch.await(PRE_TASK_DELAY_MS + INTER_WRITE_DELAY_MS + TIMEOUT_ALLOWANCE,
+                        TimeUnit.MILLISECONDS));
+        assertEquals("Target didn't process all items.", 2, mItemCount.get());
+        final long processDuration = SystemClock.uptimeMillis() - dispatchTime;
+        assertTrue("Target didn't wait enough time before processing item. duration: "
+                        + processDuration + "ms pretask delay: " + PRE_TASK_DELAY_MS
+                        + "ms inter write delay: " + INTER_WRITE_DELAY_MS + "ms",
+                processDuration >= PRE_TASK_DELAY_MS + INTER_WRITE_DELAY_MS);
+
+        // Once before processing this item, once after that.
+        assertEquals(3, mProbablyDoneResults.size());
+        // The first one must be called with probably done being false.
+        assertFalse("The first probablyDone must be false.", mProbablyDoneResults.get(1));
+        // The last one must be called with probably done being true.
+        assertTrue("The last probablyDone must be true.", mProbablyDoneResults.get(2));
+    }
+
+    @Test
+    public void testProcessTwoItems_OneAfterAnother() throws Exception {
+        // First item
+        mLatch = new CountDownLatch(1);
+        long dispatchTime = SystemClock.uptimeMillis();
+        mTarget.addItem(new TestItem(), false);
+        assertTrue("Target didn't call callback enough times.",
+                mLatch.await(PRE_TASK_DELAY_MS + TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+        long processDuration = SystemClock.uptimeMillis() - dispatchTime;
+        assertTrue("Target didn't wait enough time before processing item."
+                        + processDuration + "ms pretask delay: "
+                        + PRE_TASK_DELAY_MS + "ms",
+                processDuration >= PRE_TASK_DELAY_MS);
+        assertEquals("Target didn't process item.", 1, mItemCount.get());
+
+        // Second item
+        mLatch = new CountDownLatch(1);
+        dispatchTime = SystemClock.uptimeMillis();
+        // Synchronize on the instance to make sure we schedule the item after it starts to wait for
+        // task indefinitely.
+        synchronized (mTarget) {
+            mTarget.addItem(new TestItem(), false);
+        }
+        assertTrue("Target didn't call callback enough times.",
+                mLatch.await(PRE_TASK_DELAY_MS + TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+        assertEquals("Target didn't process all items.", 2, mItemCount.get());
+        processDuration = SystemClock.uptimeMillis() - dispatchTime;
+        assertTrue("Target didn't wait enough time before processing item."
+                        + processDuration + "ms pre task delay: "
+                        + PRE_TASK_DELAY_MS + "ms",
+                processDuration >= PRE_TASK_DELAY_MS);
+
+        // Once before processing this item, once after that.
+        assertEquals(3, mProbablyDoneResults.size());
+        // The last one must be called with probably done being true.
+        assertTrue("The last probablyDone must be true.", mProbablyDoneResults.get(2));
+    }
+
+    @Test
+    public void testFindLastItemNotReturnDifferentType() throws Exception {
+        synchronized (mTarget) {
+            mTarget.addItem(new TestItem(), false);
+            assertNull(mTarget.findLastItem(TEST_ITEM_PREDICATE, MatchingTestItem.class));
+        }
+    }
+
+    @Test
+    public void testFindLastItemNotReturnMismatchItem() throws Exception {
+        synchronized (mTarget) {
+            mTarget.addItem(new MatchingTestItem(false), false);
+            assertNull(mTarget.findLastItem(TEST_ITEM_PREDICATE, MatchingTestItem.class));
+        }
+    }
+
+    @Test
+    public void testFindLastItemReturnMatchedItem() throws Exception {
+        synchronized (mTarget) {
+            final MatchingTestItem item = new MatchingTestItem(true);
+            mTarget.addItem(item, false);
+            assertSame(item, mTarget.findLastItem(TEST_ITEM_PREDICATE, MatchingTestItem.class));
+        }
+    }
+
+    @Test
+    public void testRemoveItemsNotRemoveDifferentType() throws Exception {
+        mLatch = new CountDownLatch(1);
+        synchronized (mTarget) {
+            mTarget.addItem(new TestItem(), false);
+            mTarget.removeItems(TEST_ITEM_PREDICATE, MatchingTestItem.class);
+        }
+        assertTrue("Target didn't call callback enough times.",
+                mLatch.await(PRE_TASK_DELAY_MS + TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+        assertEquals("Target didn't process item.", 1, mItemCount.get());
+    }
+
+    @Test
+    public void testRemoveItemsNotRemoveMismatchedItem() throws Exception {
+        mLatch = new CountDownLatch(1);
+        synchronized (mTarget) {
+            mTarget.addItem(new MatchingTestItem(false), false);
+            mTarget.removeItems(TEST_ITEM_PREDICATE, MatchingTestItem.class);
+        }
+        assertTrue("Target didn't call callback enough times.",
+                mLatch.await(PRE_TASK_DELAY_MS + TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+        assertEquals("Target didn't process item.", 1, mItemCount.get());
+    }
+
+    @Test
+    public void testRemoveItemsRemoveMatchedItem() throws Exception {
+        mLatch = new CountDownLatch(1);
+        synchronized (mTarget) {
+            mTarget.addItem(new TestItem(), false);
+            mTarget.addItem(new MatchingTestItem(true), false);
+            mTarget.removeItems(TEST_ITEM_PREDICATE, MatchingTestItem.class);
+        }
+        assertTrue("Target didn't call callback enough times.",
+                mLatch.await(PRE_TASK_DELAY_MS + TIMEOUT_ALLOWANCE, TimeUnit.MILLISECONDS));
+        assertEquals("Target didn't process item.", 1, mItemCount.get());
+    }
+
+    @Test
+    public void testFlushWaitSynchronously() {
+        final long dispatchTime = SystemClock.uptimeMillis();
+        mTarget.addItem(new TestItem(), false);
+        mTarget.addItem(new TestItem(), false);
+        mTarget.flush();
+        assertEquals("Flush should wait until all items are processed before return.",
+                2, mItemCount.get());
+        final long processTime = SystemClock.uptimeMillis() - dispatchTime;
+        assertTrue("Flush should trigger immediate flush without delays. processTime: "
+                + processTime, processTime < TIMEOUT_ALLOWANCE);
+    }
+
+    @Override
+    public void onPreProcessItem(boolean queueEmpty) {
+        mProbablyDoneResults.add(queueEmpty);
+
+        final CountDownLatch latch = mLatch;
+        if (latch != null) {
+            latch.countDown();
+        }
+
+        mSetUpLatch.countDown();
+    }
+
+    private class TestItem implements PersisterQueue.WriteQueueItem {
+        @Override
+        public void process() {
+            mItemCount.getAndIncrement();
+        }
+    }
+
+    private class MatchingTestItem extends TestItem {
+        private boolean mMatching;
+
+        private MatchingTestItem(boolean matching) {
+            mMatching = matching;
+        }
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index 70cfad1..27e8c63 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -116,8 +116,7 @@
 
         mTaskPersister = new TestTaskPersister(mContext.getFilesDir());
         mService = spy(new MyTestActivityTaskManagerService(mContext));
-        final TestActivityManagerService am =
-                spy(new MyTestActivityManagerService(mContext, mService));
+        final TestActivityManagerService am = spy(new MyTestActivityManagerService());
         setupActivityManagerService(am, mService);
         mRecentTasks = (TestRecentTasks) mService.getRecentTasks();
         mRecentTasks.loadParametersFromResources(mContext.getResources());
@@ -125,7 +124,6 @@
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
         mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
                 WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        ((MyTestActivityStackSupervisor) mService.mStackSupervisor).setHomeStack(mHomeStack);
         mCallbacksRecorder = new CallbacksRecorder();
         mRecentTasks.registerCallback(mCallbacksRecorder);
         QUIET_USER_INFO.flags = UserInfo.FLAG_MANAGED_PROFILE | UserInfo.FLAG_QUIET_MODE;
@@ -558,9 +556,8 @@
 
         final MyTestActivityStackSupervisor supervisor =
                 (MyTestActivityStackSupervisor) mService.mStackSupervisor;
-        final ActivityStack homeStack = new MyTestActivityStack(mDisplay, supervisor);
+        final ActivityStack homeStack = mDisplay.getHomeStack();
         final ActivityStack aboveHomeStack = new MyTestActivityStack(mDisplay, supervisor);
-        supervisor.setHomeStack(homeStack);
 
         // Add a number of tasks (beyond the max) but ensure that nothing is trimmed because all
         // the tasks belong in stacks above the home stack
@@ -579,9 +576,8 @@
         final MyTestActivityStackSupervisor supervisor =
                 (MyTestActivityStackSupervisor) mService.mStackSupervisor;
         final ActivityStack behindHomeStack = new MyTestActivityStack(mDisplay, supervisor);
-        final ActivityStack homeStack = new MyTestActivityStack(mDisplay, supervisor);
+        final ActivityStack homeStack = mDisplay.getHomeStack();
         final ActivityStack aboveHomeStack = new MyTestActivityStack(mDisplay, supervisor);
-        supervisor.setHomeStack(homeStack);
 
         // Add a number of tasks (beyond the max) but ensure that only the task in the stack behind
         // the home stack is trimmed once a new task is added
@@ -601,9 +597,8 @@
 
         final MyTestActivityStackSupervisor supervisor =
                 (MyTestActivityStackSupervisor) mService.mStackSupervisor;
-        final ActivityStack homeStack = new MyTestActivityStack(mDisplay, supervisor);
+        final ActivityStack homeStack = mDisplay.getHomeStack();
         final ActivityStack otherDisplayStack = new MyTestActivityStack(mOtherDisplay, supervisor);
-        supervisor.setHomeStack(homeStack);
 
         // Add a number of tasks (beyond the max) on each display, ensure that the tasks are not
         // removed
@@ -852,8 +847,8 @@
     }
 
     private class MyTestActivityManagerService extends TestActivityManagerService {
-        MyTestActivityManagerService(Context context, TestActivityTaskManagerService atm) {
-            super(context, atm);
+        MyTestActivityManagerService() {
+            super(mTestInjector);
         }
 
         @Override
@@ -870,7 +865,7 @@
         @Override
         public void initialize() {
             super.initialize();
-            mDisplay = TestActivityDisplay.create(this, DEFAULT_DISPLAY);
+            mDisplay = getActivityDisplay(DEFAULT_DISPLAY);
             mOtherDisplay = TestActivityDisplay.create(this, DEFAULT_DISPLAY + 1);
             addChild(mOtherDisplay, ActivityDisplay.POSITION_TOP);
             addChild(mDisplay, ActivityDisplay.POSITION_TOP);
@@ -881,10 +876,6 @@
             mRunningTasks = new TestRunningTasks();
             return mRunningTasks;
         }
-
-        void setHomeStack(ActivityStack stack) {
-            mHomeStack = stack;
-        }
     }
 
     private class MyTestActivityStack extends TestActivityStack {
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
index f5b8f78..169204f 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskLaunchParamsModifierTests.java
@@ -11,239 +11,1091 @@
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
  */
 
 package com.android.server.am;
 
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+import static android.util.DisplayMetrics.DENSITY_DEFAULT;
+import static android.view.Display.DEFAULT_DISPLAY;
 
 import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
+import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_SKIP;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.when;
 
-import android.content.pm.ActivityInfo.WindowLayout;
+import android.app.ActivityOptions;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.os.Build;
 import android.platform.test.annotations.Presubmit;
 import android.view.Gravity;
 
-import androidx.test.filters.MediumTest;
+import androidx.test.filters.SmallTest;
+import androidx.test.filters.FlakyTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.am.LaunchParamsController.LaunchParams;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.Locale;
+
 /**
- * Tests for exercising resizing task bounds.
+ * Tests for default task bounds.
  *
  * Build/Install/Run:
  *  atest FrameworksServicesTests:TaskLaunchParamsModifierTests
  */
-@MediumTest
+@SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
+@FlakyTest(detail = "Confirm stable in post-submit before removing")
 public class TaskLaunchParamsModifierTests extends ActivityTestsBase {
-    private final static int STACK_WIDTH = 100;
-    private final static int STACK_HEIGHT = 200;
 
-    private final static Rect STACK_BOUNDS = new Rect(0, 0, STACK_WIDTH, STACK_HEIGHT);
+    private ActivityRecord mActivity;
 
-    private ActivityTaskManagerService mService;
-    private ActivityStack mStack;
-    private TaskRecord mTask;
+    private TaskLaunchParamsModifier mTarget;
 
-    private TaskLaunchParamsModifier mPositioner;
-
-    private LaunchParamsController.LaunchParams mCurrent;
-    private LaunchParamsController.LaunchParams mResult;
+    private LaunchParams mCurrent;
+    private LaunchParams mResult;
 
     @Before
     @Override
     public void setUp() throws Exception {
         super.setUp();
 
-        mService = createActivityTaskManagerService();
-        mStack = mService.mStackSupervisor.getDefaultDisplay().createStack(
-                WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD, true /* onTop */);
-        mStack.requestResize(STACK_BOUNDS);
+        setupActivityTaskManagerService();
+        mService.mSupportsFreeformWindowManagement = true;
+        when(mSupervisor.canUseActivityOptionsLaunchBounds(any())).thenCallRealMethod();
 
-        // We must create the task after resizing to make sure it does not inherit the stack
-        // dimensions on resize.
-        mTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
+        mActivity = new ActivityBuilder(mService).build();
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+        mActivity.info.applicationInfo.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
 
-        mPositioner = new TaskLaunchParamsModifier();
+        mTarget = new TaskLaunchParamsModifier(mSupervisor);
 
-        mResult = new LaunchParamsController.LaunchParams();
-        mCurrent = new LaunchParamsController.LaunchParams();
+        mCurrent = new LaunchParams();
+        mCurrent.reset();
+        mResult = new LaunchParams();
+        mResult.reset();
     }
 
-    /**
-     * Ensures that the setup bounds are set as expected with the stack bounds set and the task
-     * bounds still {@code null}.
-     * @throws Exception
-     */
     @Test
-    public void testInitialBounds() throws Exception {
-        assertEquals(mStack.getOverrideBounds(), STACK_BOUNDS);
-        assertEquals(mTask.getOverrideBounds(), new Rect());
+    public void testReturnsSkipWithEmptyActivity() {
+        final TaskRecord task = new TaskBuilder(mSupervisor).build();
+        assertEquals(RESULT_SKIP, mTarget.onCalculate(task, /* layout */ null,
+                /* activity */ null, /* source */ null, /* options */ null, mCurrent, mResult));
     }
 
-    /**
-     * Ensures that a task positioned with no {@link WindowLayout} receives the default launch
-     * position.
-     * @throws Exception
-     */
+    // =============================
+    // Display ID Related Tests
+    // =============================
     @Test
-    public void testLaunchNoWindowLayout() throws Exception {
-        assertEquals(RESULT_CONTINUE, mPositioner.onCalculate(mTask, null /*layout*/,
-                null /*record*/, null /*source*/, null /*options*/, mCurrent, mResult));
-        assertEquals(getDefaultBounds(Gravity.NO_GRAVITY), mResult.mBounds);
+    public void testDefaultToPrimaryDisplay() {
+        createNewActivityDisplay(WINDOWING_MODE_FREEFORM);
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(DEFAULT_DISPLAY, mResult.mPreferredDisplayId);
     }
 
-    /**
-     * Ensures that a task positioned with an empty {@link WindowLayout} receives the default launch
-     * position.
-     * @throws Exception
-     */
     @Test
-    public void testlaunchEmptyWindowLayout() throws Exception {
-        assertEquals(RESULT_CONTINUE, mPositioner.onCalculate(mTask,
-                new WindowLayout(0, 0, 0, 0, Gravity.NO_GRAVITY, 0, 0), null /*activity*/,
-                null /*source*/, null /*options*/, mCurrent, mResult));
-        assertEquals(mResult.mBounds, getDefaultBounds(Gravity.NO_GRAVITY));
+    public void testUsesPreviousDisplayIdIfSet() {
+        createNewActivityDisplay(WINDOWING_MODE_FREEFORM);
+        final TestActivityDisplay display = createNewActivityDisplay(WINDOWING_MODE_FULLSCREEN);
+
+        mCurrent.mPreferredDisplayId = display.mDisplayId;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(display.mDisplayId, mResult.mPreferredDisplayId);
     }
 
-    /**
-     * Ensures that a task positioned with a {@link WindowLayout} gravity specified is positioned
-     * according to specification.
-     * @throws Exception
-     */
     @Test
-    public void testlaunchWindowLayoutGravity() throws Exception {
-        // Unspecified gravity should be ignored
-        testGravity(Gravity.NO_GRAVITY);
+    public void testUsesSourcesDisplayIdIfSet() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+        final TestActivityDisplay fullscreenDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FULLSCREEN);
 
-        // Unsupported gravity should be ignored
-        testGravity(Gravity.LEFT);
-        testGravity(Gravity.RIGHT);
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
 
-        // Test defaults for vertical gravities
-        testGravity(Gravity.TOP);
-        testGravity(Gravity.BOTTOM);
+        ActivityRecord source = createSourceActivity(fullscreenDisplay);
 
-        // Test corners
-        testGravity(Gravity.TOP | Gravity.LEFT);
-        testGravity(Gravity.TOP | Gravity.RIGHT);
-        testGravity(Gravity.BOTTOM | Gravity.LEFT);
-        testGravity(Gravity.BOTTOM | Gravity.RIGHT);
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, source, /* options */ null, mCurrent, mResult));
+
+        assertEquals(fullscreenDisplay.mDisplayId, mResult.mPreferredDisplayId);
     }
 
-    private void testGravity(int gravity) {
-        try {
-            assertEquals(RESULT_CONTINUE, mPositioner.onCalculate(mTask,
-                    new WindowLayout(0, 0, 0, 0, gravity, 0, 0), null /*activity*/,
-                    null /*source*/, null /*options*/, mCurrent, mResult));
-            assertEquals(mResult.mBounds, getDefaultBounds(gravity));
-        } finally {
-            mCurrent.reset();
-            mResult.reset();
+    @Test
+    public void testUsesOptionsDisplayIdIfSet() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+        final TestActivityDisplay fullscreenDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FULLSCREEN);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+        ActivityRecord source = createSourceActivity(freeformDisplay);
+
+        ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(fullscreenDisplay.mDisplayId);
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, source, options, mCurrent, mResult));
+
+        assertEquals(fullscreenDisplay.mDisplayId, mResult.mPreferredDisplayId);
+    }
+
+    // =====================================
+    // Launch Windowing Mode Related Tests
+    // =====================================
+    @Test
+    public void testBoundsInOptionsInfersFreeformOnFreeformDisplay() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchBounds(new Rect(0, 0, 100, 100));
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testBoundsInOptionsInfersFreeformWithResizeableActivity() {
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchBounds(new Rect(0, 0, 100, 100));
+
+        mCurrent.mPreferredDisplayId = DEFAULT_DISPLAY;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FULLSCREEN);
+    }
+
+    @Test
+    public void testKeepsPictureInPictureLaunchModeInOptions() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_PINNED);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_PINNED, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testKeepsPictureInPictureLaunchModeWithBoundsInOptions() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_PINNED);
+        options.setLaunchBounds(new Rect(0, 0, 100, 100));
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_PINNED, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testKeepsFullscreenLaunchModeInOptionsOnNonFreeformDisplay() {
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
+
+        mCurrent.mPreferredDisplayId = DEFAULT_DISPLAY;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FULLSCREEN);
+    }
+
+    @Test
+    public void testNonEmptyLayoutInfersFreeformOnFreeformDisplay() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testNonEmptyLayoutInfersFreeformWithEmptySize() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setGravity(Gravity.LEFT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testNonEmptyLayoutUsesFullscreenWithResizeableActivity() {
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).build();
+
+        mCurrent.mPreferredDisplayId = DEFAULT_DISPLAY;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, 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);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+        mCurrent.mWindowingMode = WINDOWING_MODE_FULLSCREEN;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testRespectsModeFromFullyResolvedCurrentParam_NonEmptyBounds() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+        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_FREEFORM, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testForceMaximizesPreDApp() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        options.setLaunchBounds(new Rect(0, 0, 200, 100));
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+        mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+        mCurrent.mBounds.set(0, 0, 200, 100);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.CUPCAKE;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testForceMaximizesAppWithoutMultipleDensitySupport() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        options.setLaunchBounds(new Rect(0, 0, 200, 100));
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+        mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+        mCurrent.mBounds.set(0, 0, 200, 100);
+
+        mActivity.appInfo.flags = 0;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testForceMaximizesUnresizeableApp() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        options.setLaunchBounds(new Rect(0, 0, 200, 100));
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+        mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+        mCurrent.mBounds.set(0, 0, 200, 100);
+
+        mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testSkipsForceMaximizingAppsOnNonFreeformDisplay() {
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM);
+        options.setLaunchBounds(new Rect(0, 0, 200, 100));
+
+        mCurrent.mPreferredDisplayId = DEFAULT_DISPLAY;
+        mCurrent.mWindowingMode = WINDOWING_MODE_FREEFORM;
+        mCurrent.mBounds.set(0, 0, 200, 100);
+
+        mActivity.info.resizeMode = RESIZE_MODE_UNRESIZEABLE;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
+                WINDOWING_MODE_FULLSCREEN);
+    }
+
+    @Test
+    public void testUsesFullscreenOnNonFreeformDisplay() {
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(DEFAULT_DISPLAY);
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FULLSCREEN);
+    }
+
+    @Test
+    public void testUsesFreeformByDefaultForPostNApp() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testUsesFreeformByDefaultForPreNResizeableAppWithoutOrientationRequest() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
+                WINDOWING_MODE_FREEFORM);
+    }
+
+    @Test
+    public void testSkipsFreeformForPreNResizeableAppOnNonFullscreenDisplay() {
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(DEFAULT_DISPLAY);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquivalentWindowingMode(WINDOWING_MODE_FULLSCREEN, mResult.mWindowingMode,
+                WINDOWING_MODE_FULLSCREEN);
+    }
+
+    // ================================
+    // Launching Bounds Related Tests
+    // ===============================
+    @Test
+    public void testKeepsBoundsWithPictureInPictureLaunchModeInOptions() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchWindowingMode(WINDOWING_MODE_PINNED);
+
+        final Rect expected = new Rect(0, 0, 100, 100);
+        options.setLaunchBounds(expected);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(expected, mResult.mBounds);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_LeftGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setGravity(Gravity.LEFT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(0, mResult.mBounds.left);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_TopGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setGravity(Gravity.TOP).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(0, mResult.mBounds.top);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_TopLeftGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setGravity(Gravity.TOP | Gravity.LEFT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(0, mResult.mBounds.left);
+        assertEquals(0, mResult.mBounds.top);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_RightGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setGravity(Gravity.RIGHT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(1920, mResult.mBounds.right);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_BottomGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setGravity(Gravity.BOTTOM).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(1080, mResult.mBounds.bottom);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsRespectsGravityWithEmptySize_BottomRightGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setGravity(Gravity.BOTTOM | Gravity.RIGHT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(1920, mResult.mBounds.right);
+        assertEquals(1080, mResult.mBounds.bottom);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsOnFreeformDisplay_CenterToDisplay() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(new Rect(900, 500, 1020, 580), mResult.mBounds);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsOnFreeformDisplay_LeftGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).setGravity(Gravity.LEFT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(new Rect(0, 500, 120, 580), mResult.mBounds);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsOnFreeformDisplay_TopGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).setGravity(Gravity.TOP).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(new Rect(900, 0, 1020, 80), mResult.mBounds);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsOnFreeformDisplay_TopLeftGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).setGravity(Gravity.TOP | Gravity.LEFT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(new Rect(0, 0, 120, 80), mResult.mBounds);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsOnFreeformDisplay_RightGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).setGravity(Gravity.RIGHT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(new Rect(1800, 500, 1920, 580), mResult.mBounds);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsOnFreeformDisplay_BottomGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).setGravity(Gravity.BOTTOM).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(new Rect(900, 1000, 1020, 1080), mResult.mBounds);
+    }
+
+    @Test
+    public void testNonEmptyLayoutBoundsOnFreeformDisplay_RightBottomGravity() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidth(120).setHeight(80).setGravity(Gravity.BOTTOM | Gravity.RIGHT).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(new Rect(1800, 1000, 1920, 1080), mResult.mBounds);
+    }
+
+    @Test
+    public void testNonEmptyLayoutFractionBoundsOnFreeformDisplay() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setWidthFraction(0.0625f).setHeightFraction(0.1f).build();
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, /* options */ null, mCurrent, mResult));
+
+        assertEquals(new Rect(900, 486, 1020, 594), mResult.mBounds);
+    }
+
+    @Test
+    public void testRespectBoundsFromFullyResolvedCurrentParam_NonEmptyBounds() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        mCurrent.mPreferredDisplayId = freeformDisplay.mDisplayId;
+        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));
+
+        assertEquals(new Rect(0, 0, 200, 100), mResult.mBounds);
+    }
+
+    @Test
+    public void testDefaultSizeSmallerThanBigScreen() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        final int resultWidth = mResult.mBounds.width();
+        final int displayWidth = freeformDisplay.getBounds().width();
+        assertTrue("Result width " + resultWidth + " is not smaller than " + displayWidth,
+                resultWidth < displayWidth);
+
+        final int resultHeight = mResult.mBounds.height();
+        final int displayHeight = freeformDisplay.getBounds().height();
+        assertTrue("Result width " + resultHeight + " is not smaller than "
+                        + displayHeight, resultHeight < displayHeight);
+    }
+
+    @Test
+    public void testDefaultFreeformSizeCenteredToDisplay() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        final Rect displayBounds = freeformDisplay.getBounds();
+        assertEquals("Distance to left and right should be equal.",
+                mResult.mBounds.left - displayBounds.left,
+                displayBounds.right - mResult.mBounds.right);
+        assertEquals("Distance to top and bottom should be equal.",
+                mResult.mBounds.top - displayBounds.top,
+                displayBounds.bottom - mResult.mBounds.bottom);
+    }
+
+    @Test
+    public void testCascadesToSourceSizeForFreeform() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        final ActivityRecord source = createSourceActivity(freeformDisplay);
+        source.setBounds(0, 0, 412, 732);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, source, options, mCurrent, mResult));
+
+        final Rect displayBounds = freeformDisplay.getBounds();
+        assertTrue("Left bounds should be larger than 0.", mResult.mBounds.left > 0);
+        assertTrue("Top bounds should be larger than 0.", mResult.mBounds.top > 0);
+        assertTrue("Bounds should be centered at somewhere in the left half, but it's "
+                + "centerX is " + mResult.mBounds.centerX(),
+                mResult.mBounds.centerX() < displayBounds.centerX());
+        assertTrue("Bounds should be centered at somewhere in the top half, but it's "
+                        + "centerY is " + mResult.mBounds.centerY(),
+                mResult.mBounds.centerY() < displayBounds.centerY());
+    }
+
+    @Test
+    public void testAdjustBoundsToFitDisplay_TopLeftOutOfDisplay() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        final ActivityRecord source = createSourceActivity(freeformDisplay);
+        source.setBounds(0, 0, 200, 400);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, source, options, mCurrent, mResult));
+
+        final Rect displayBounds = freeformDisplay.getBounds();
+        assertTrue("display bounds doesn't contain result. display bounds: "
+                + displayBounds + " result: " + mResult.mBounds,
+                displayBounds.contains(mResult.mBounds));
+    }
+
+    @Test
+    public void testAdjustBoundsToFitDisplay_BottomRightOutOfDisplay() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        final ActivityRecord source = createSourceActivity(freeformDisplay);
+        source.setBounds(1720, 680, 1920, 1080);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, source, options, mCurrent, mResult));
+
+        final Rect displayBounds = freeformDisplay.getBounds();
+        assertTrue("display bounds doesn't contain result. display bounds: "
+                        + displayBounds + " result: " + mResult.mBounds,
+                displayBounds.contains(mResult.mBounds));
+    }
+
+    @Test
+    public void testAdjustBoundsToFitDisplay_LargerThanDisplay() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        Configuration overrideConfig = new Configuration();
+        overrideConfig.setTo(mSupervisor.getOverrideConfiguration());
+        overrideConfig.setLayoutDirection(new Locale("ar"));
+        mSupervisor.onConfigurationChanged(overrideConfig);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        final ActivityRecord source = createSourceActivity(freeformDisplay);
+        source.setBounds(1720, 680, 1920, 1080);
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, source, options, mCurrent, mResult));
+
+        final Rect displayBounds = freeformDisplay.getBounds();
+        assertTrue("display bounds doesn't contain result. display bounds: "
+                        + displayBounds + " result: " + mResult.mBounds,
+                displayBounds.contains(mResult.mBounds));
+    }
+
+    @Test
+    public void testRespectsLayoutMinDimensions() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+
+        final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
+                .setMinWidth(500).setMinHeight(800).build();
+
+        mActivity.appInfo.targetSdkVersion = Build.VERSION_CODES.LOLLIPOP;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, layout, mActivity,
+                /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(500, mResult.mBounds.width());
+        assertEquals(800, mResult.mBounds.height());
+    }
+
+    @Test
+    public void testRotatesInPlaceInitialBoundsMismatchOrientation() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+        options.setLaunchBounds(new Rect(100, 100, 500, 300));
+
+        mActivity.info.screenOrientation = SCREEN_ORIENTATION_PORTRAIT;
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(new Rect(200, 0, 400, 400), mResult.mBounds);
+    }
+
+    @Test
+    public void testShiftsToRightForCloseToLeftBoundsWhenConflict() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        addFreeformTaskTo(freeformDisplay, new Rect(50, 50, 100, 150));
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+        options.setLaunchBounds(new Rect(50, 50, 500, 300));
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(new Rect(170, 50, 620, 300), mResult.mBounds);
+    }
+
+    @Test
+    public void testShiftsToLeftForCloseToRightBoundsWhenConflict() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        addFreeformTaskTo(freeformDisplay, new Rect(1720, 50, 1830, 150));
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+        options.setLaunchBounds(new Rect(1720, 50, 1850, 300));
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(new Rect(1600, 50, 1730, 300), mResult.mBounds);
+    }
+
+    @Test
+    public void testShiftsToRightFirstForHorizontallyCenteredAndCloseToTopWhenConflict() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        addFreeformTaskTo(freeformDisplay, new Rect(0, 0, 100, 300));
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+        options.setLaunchBounds(new Rect(0, 0, 1800, 200));
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(new Rect(120, 0, 1920, 200), mResult.mBounds);
+    }
+
+    @Test
+    public void testShiftsToLeftNoSpaceOnRightForHorizontallyCenteredAndCloseToTopWhenConflict() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        addFreeformTaskTo(freeformDisplay, new Rect(120, 0, 240, 300));
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+        options.setLaunchBounds(new Rect(120, 0, 1860, 200));
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(new Rect(0, 0, 1740, 200), mResult.mBounds);
+    }
+
+    @Test
+    public void testShiftsToBottomRightFirstForCenteredBoundsWhenConflict() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        addFreeformTaskTo(freeformDisplay, new Rect(120, 0, 240, 100));
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+        options.setLaunchBounds(new Rect(120, 0, 1800, 1013));
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(new Rect(240, 67, 1920, 1080), mResult.mBounds);
+    }
+
+    @Test
+    public void testShiftsToTopLeftIfNoSpaceOnBottomRightForCenteredBoundsWhenConflict() {
+        final TestActivityDisplay freeformDisplay = createNewActivityDisplay(
+                WINDOWING_MODE_FREEFORM);
+
+        addFreeformTaskTo(freeformDisplay, new Rect(120, 67, 240, 100));
+
+        final ActivityOptions options = ActivityOptions.makeBasic();
+        options.setLaunchDisplayId(freeformDisplay.mDisplayId);
+        options.setLaunchBounds(new Rect(120, 67, 1800, 1020));
+
+        assertEquals(RESULT_CONTINUE, mTarget.onCalculate(/* task */ null, /* layout */ null,
+                mActivity, /* source */ null, options, mCurrent, mResult));
+
+        assertEquals(new Rect(0, 0, 1680,
+                953), mResult.mBounds);
+    }
+
+    private TestActivityDisplay createNewActivityDisplay(int windowingMode) {
+        final TestActivityDisplay display = addNewActivityDisplayAt(ActivityDisplay.POSITION_TOP);
+        display.setWindowingMode(windowingMode);
+        display.setBounds(/* left */ 0, /* top */ 0, /* right */ 1920, /* bottom */ 1080);
+        display.getConfiguration().densityDpi = DENSITY_DEFAULT;
+        return display;
+    }
+
+    private ActivityRecord createSourceActivity(TestActivityDisplay display) {
+        final TestActivityStack stack = display.createStack(display.getWindowingMode(),
+                ACTIVITY_TYPE_STANDARD, true);
+        return new ActivityBuilder(mService).setStack(stack).setCreateTask(true).build();
+    }
+
+    private void addFreeformTaskTo(TestActivityDisplay display, Rect bounds) {
+        final TestActivityStack stack = display.createStack(display.getWindowingMode(),
+                ACTIVITY_TYPE_STANDARD, true);
+        stack.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        final TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+        task.setBounds(bounds);
+    }
+
+    private void assertEquivalentWindowingMode(int expected, int actual, int parentWindowingMode) {
+        if (expected != parentWindowingMode) {
+            assertEquals(expected, actual);
+        } else {
+            assertEquals(WINDOWING_MODE_UNDEFINED, actual);
         }
     }
 
-    /**
-     * Ensures that a task which causes a conflict with another task when positioned is adjusted as
-     * expected.
-     * @throws Exception
-     */
-    @Test
-    public void testLaunchWindowCenterConflict() throws Exception {
-        testConflict(Gravity.NO_GRAVITY);
-        testConflict(Gravity.TOP);
-        testConflict(Gravity.BOTTOM);
-        testConflict(Gravity.TOP | Gravity.LEFT);
-        testConflict(Gravity.TOP | Gravity.RIGHT);
-        testConflict(Gravity.BOTTOM | Gravity.LEFT);
-        testConflict(Gravity.BOTTOM | Gravity.RIGHT);
-    }
+    private static class WindowLayoutBuilder {
+        private int mWidth = -1;
+        private int mHeight = -1;
+        private float mWidthFraction = -1f;
+        private float mHeightFraction = -1f;
+        private int mGravity = Gravity.NO_GRAVITY;
+        private int mMinWidth = -1;
+        private int mMinHeight = -1;
 
-    private void testConflict(int gravity) {
-        final WindowLayout layout = new WindowLayout(0, 0, 0, 0, gravity, 0, 0);
-
-        // layout first task
-        mService.mStackSupervisor.getLaunchParamsController().layoutTask(mTask, layout);
-
-        // Second task will be laid out on top of the first so starting bounds is the same.
-        final Rect expectedBounds = new Rect(mTask.getOverrideBounds());
-
-        ActivityRecord activity = null;
-        TaskRecord secondTask = null;
-
-        // wrap with try/finally to ensure cleanup of activity/stack.
-        try {
-            // empty tasks are ignored in conflicts
-            activity = new ActivityBuilder(mService).setTask(mTask).build();
-
-            // Create secondary task
-            secondTask = new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build();
-
-            // layout second task
-            assertEquals(RESULT_CONTINUE,
-                    mPositioner.onCalculate(secondTask, layout, null /*activity*/,
-                            null /*source*/, null /*options*/, mCurrent, mResult));
-
-            if ((gravity & (Gravity.TOP | Gravity.RIGHT)) == (Gravity.TOP | Gravity.RIGHT)
-                    || (gravity & (Gravity.BOTTOM | Gravity.RIGHT))
-                    == (Gravity.BOTTOM | Gravity.RIGHT)) {
-                expectedBounds.offset(-TaskLaunchParamsModifier.getHorizontalStep(
-                        mStack.getOverrideBounds()), 0);
-            } else if ((gravity & Gravity.TOP) == Gravity.TOP
-                    || (gravity & Gravity.BOTTOM) == Gravity.BOTTOM) {
-                expectedBounds.offset(
-                        TaskLaunchParamsModifier.getHorizontalStep(mStack.getOverrideBounds()), 0);
-            } else {
-                expectedBounds.offset(
-                        TaskLaunchParamsModifier.getHorizontalStep(mStack.getOverrideBounds()),
-                        TaskLaunchParamsModifier.getVerticalStep(mStack.getOverrideBounds()));
-            }
-
-            assertEquals(mResult.mBounds, expectedBounds);
-        } finally {
-            // Remove task and activity to prevent influencing future tests
-            if (activity != null) {
-                mTask.removeActivity(activity);
-            }
-
-            if (secondTask != null) {
-                mStack.removeTask(secondTask, "cleanup", ActivityStack.REMOVE_TASK_MODE_DESTROYING);
-            }
-        }
-    }
-
-    private Rect getDefaultBounds(int gravity) {
-        final Rect bounds = new Rect();
-        bounds.set(mStack.getOverrideBounds());
-
-        final int verticalInset =
-                TaskLaunchParamsModifier.getFreeformStartTop(mStack.getOverrideBounds());
-        final int horizontalInset =
-                TaskLaunchParamsModifier.getFreeformStartLeft(mStack.getOverrideBounds());
-
-        bounds.inset(horizontalInset, verticalInset);
-
-        if ((gravity & (Gravity.TOP | Gravity.RIGHT)) == (Gravity.TOP | Gravity.RIGHT)) {
-            bounds.offsetTo(horizontalInset * 2, 0);
-        } else if ((gravity & Gravity.TOP) == Gravity.TOP) {
-            bounds.offsetTo(0, 0);
-        } else if ((gravity & (Gravity.BOTTOM | Gravity.RIGHT))
-                == (Gravity.BOTTOM | Gravity.RIGHT)) {
-            bounds.offsetTo(horizontalInset * 2, verticalInset * 2);
-        } else if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) {
-            bounds.offsetTo(0, verticalInset * 2);
+        private WindowLayoutBuilder setWidth(int width) {
+            mWidth = width;
+            return this;
         }
 
-        return bounds;
+        private WindowLayoutBuilder setHeight(int height) {
+            mHeight = height;
+            return this;
+        }
+
+        private WindowLayoutBuilder setWidthFraction(float widthFraction) {
+            mWidthFraction = widthFraction;
+            return this;
+        }
+
+        private WindowLayoutBuilder setHeightFraction(float heightFraction) {
+            mHeightFraction = heightFraction;
+            return this;
+        }
+
+        private WindowLayoutBuilder setGravity(int gravity) {
+            mGravity = gravity;
+            return this;
+        }
+
+        private WindowLayoutBuilder setMinWidth(int minWidth) {
+            mMinWidth = minWidth;
+            return this;
+        }
+
+        private WindowLayoutBuilder setMinHeight(int minHeight) {
+            mMinHeight = minHeight;
+            return this;
+        }
+
+        private ActivityInfo.WindowLayout build() {
+            return new ActivityInfo.WindowLayout(mWidth, mWidthFraction, mHeight, mHeightFraction,
+                    mGravity, mMinWidth, mMinHeight);
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
index 8d54bc2..48bfe1d 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskPersisterTest.java
@@ -16,34 +16,43 @@
 
 package com.android.server.am;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import static androidx.test.InstrumentationRegistry.getTargetContext;
+
 import android.content.pm.UserInfo;
-import android.os.Environment;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.test.AndroidTestCase;
-import android.util.Log;
+import android.platform.test.annotations.Presubmit;
 import android.util.SparseBooleanArray;
 
-import com.android.server.am.TaskPersister;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
-import java.io.File;
-import java.util.Random;
+import androidx.test.filters.FlakyTest;
 
 /**
- * atest FrameworksServicesTests:TaskPersisterTest
+ * Tests for {@link TaskPersister}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:TaskPersisterTest
  */
-public class TaskPersisterTest extends AndroidTestCase {
+@Presubmit
+@FlakyTest(detail = "Promote to presubmit if stable")
+public class TaskPersisterTest {
     private static final String TEST_USER_NAME = "AM-Test-User";
 
     private TaskPersister mTaskPersister;
     private int testUserId;
     private UserManager mUserManager;
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-        mUserManager = UserManager.get(getContext());
-        mTaskPersister = new TaskPersister(getContext().getFilesDir());
+        mUserManager = UserManager.get(getTargetContext());
+        mTaskPersister = new TaskPersister(getTargetContext().getFilesDir());
         // In ARC, the maximum number of supported users is one, which is different from the ones of
         // most phones (more than 4). This prevents TaskPersisterTest from creating another user for
         // test. However, since guest users can be added as much as possible, we create guest user
@@ -51,9 +60,8 @@
         testUserId = createUser(TEST_USER_NAME, UserInfo.FLAG_GUEST);
     }
 
-    @Override
+    @After
     public void tearDown() throws Exception {
-        super.tearDown();
         mTaskPersister.unloadUserDataFromMemory(testUserId);
         removeUser(testUserId);
     }
@@ -64,6 +72,7 @@
         return taskId;
     }
 
+    @Test
     public void testTaskIdsPersistence() {
         SparseBooleanArray taskIdsOnFile = new SparseBooleanArray();
         for (int i = 0; i < 100; i++) {
@@ -72,21 +81,18 @@
         mTaskPersister.writePersistedTaskIdsForUser(taskIdsOnFile, testUserId);
         SparseBooleanArray newTaskIdsOnFile = mTaskPersister
                 .loadPersistedTaskIdsForUser(testUserId);
-        assertTrue("TaskIds written differ from TaskIds read back from file",
-                taskIdsOnFile.equals(newTaskIdsOnFile));
+        assertEquals("TaskIds written differ from TaskIds read back from file",
+                taskIdsOnFile, newTaskIdsOnFile);
     }
 
     private int createUser(String name, int flags) {
         UserInfo user = mUserManager.createUser(name, flags);
-        if (user == null) {
-            fail("Error while creating the test user: " + TEST_USER_NAME);
-        }
+        assertNotNull("Error while creating the test user: " + TEST_USER_NAME, user);
         return user.id;
     }
 
     private void removeUser(int userId) {
-        if (!mUserManager.removeUser(userId)) {
-            fail("Error while removing the test user: " + TEST_USER_NAME);
-        }
+        boolean userRemoved = mUserManager.removeUser(userId);
+        assertTrue("Error while removing the test user: " + TEST_USER_NAME, userRemoved);
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
index fa8a09c..27766d3 100644
--- a/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/TaskRecordTests.java
@@ -69,13 +69,11 @@
 
     private static final String TASK_TAG = "task";
 
-    private ActivityManagerService mService;
-
     @Before
     public void setUp() throws Exception {
         super.setUp();
         TaskRecord.setTaskRecordFactory(null);
-        mService = createActivityManagerService();
+        setupActivityTaskManagerService();
     }
 
     @Test
@@ -150,7 +148,7 @@
     }
 
     private TaskRecord createTaskRecord(int taskId) {
-        return new TaskRecord(mService.mActivityTaskManager, taskId, new Intent(), null, null, null,
+        return new TaskRecord(mService, taskId, new Intent(), null, null, null,
                 ActivityBuilder.getDefaultComponent(), null, false, false, false, 0, 10050, null,
                 new ArrayList<>(), 0, false, null, 0, 0, 0, 0, 0, null, 0, false, false, false, 0, 0
         );
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index cc4f519..75e1d0d 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -16,6 +16,41 @@
 
 package com.android.server.am;
 
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
+
+import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
+import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
+import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
+import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
+import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG;
+import static com.android.server.am.UserController.SYSTEM_USER_START_MSG;
+import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
+
+import static com.google.android.collect.Lists.newArrayList;
+import static com.google.android.collect.Sets.newHashSet;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.validateMockitoUsage;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import static androidx.test.InstrumentationRegistry.getTargetContext;
+
 import android.app.IUserSwitchObserver;
 import android.content.Context;
 import android.content.IIntentReceiver;
@@ -31,80 +66,62 @@
 import android.os.RemoteException;
 import android.os.UserManagerInternal;
 import android.platform.test.annotations.Presubmit;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
 import com.android.server.pm.UserManagerService;
 import com.android.server.wm.WindowManagerService;
 
-import org.mockito.Mockito;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
-import static com.android.server.am.UserController.CONTINUE_USER_SWITCH_MSG;
-import static com.android.server.am.UserController.REPORT_LOCKED_BOOT_COMPLETE_MSG;
-import static com.android.server.am.UserController.REPORT_USER_SWITCH_COMPLETE_MSG;
-import static com.android.server.am.UserController.REPORT_USER_SWITCH_MSG;
-import static com.android.server.am.UserController.SYSTEM_USER_CURRENT_MSG;
-import static com.android.server.am.UserController.SYSTEM_USER_START_MSG;
-import static com.android.server.am.UserController.USER_SWITCH_TIMEOUT_MSG;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.when;
+import androidx.test.filters.SmallTest;
 
 /**
- * Usage: bit FrameworksServicesTests:com.android.server.am.UserControllerTest
+ * Tests for {@link UserController}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.am.UserControllerTest
  */
 @Presubmit
-public class UserControllerTest extends AndroidTestCase {
+@SmallTest
+public class UserControllerTest {
     private static final int TEST_USER_ID = 10;
     private static final int NONEXIST_USER_ID = 2;
     private static String TAG = UserControllerTest.class.getSimpleName();
     private UserController mUserController;
     private TestInjector mInjector;
 
-    private static final List<String> START_FOREGROUND_USER_ACTIONS =
-            Arrays.asList(
-                    Intent.ACTION_USER_STARTED,
-                    Intent.ACTION_USER_SWITCHED,
-                    Intent.ACTION_USER_STARTING);
+    private static final List<String> START_FOREGROUND_USER_ACTIONS = newArrayList(
+            Intent.ACTION_USER_STARTED,
+            Intent.ACTION_USER_SWITCHED,
+            Intent.ACTION_USER_STARTING);
 
-    private static final List<String> START_BACKGROUND_USER_ACTIONS =
-            Arrays.asList(
-                    Intent.ACTION_USER_STARTED,
-                    Intent.ACTION_LOCKED_BOOT_COMPLETED,
-                    Intent.ACTION_USER_STARTING);
+    private static final List<String> START_BACKGROUND_USER_ACTIONS = newArrayList(
+            Intent.ACTION_USER_STARTED,
+            Intent.ACTION_LOCKED_BOOT_COMPLETED,
+            Intent.ACTION_USER_STARTING);
 
-    private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES =
-            new HashSet<>(Arrays.asList(REPORT_USER_SWITCH_MSG, USER_SWITCH_TIMEOUT_MSG,
-                    SYSTEM_USER_START_MSG, SYSTEM_USER_CURRENT_MSG));
+    private static final Set<Integer> START_FOREGROUND_USER_MESSAGE_CODES = newHashSet(
+            REPORT_USER_SWITCH_MSG,
+            USER_SWITCH_TIMEOUT_MSG,
+            SYSTEM_USER_START_MSG,
+            SYSTEM_USER_CURRENT_MSG);
 
-    private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES =
-            new HashSet<>(Arrays.asList(SYSTEM_USER_START_MSG, REPORT_LOCKED_BOOT_COMPLETE_MSG));
+    private static final Set<Integer> START_BACKGROUND_USER_MESSAGE_CODES = newHashSet(
+            SYSTEM_USER_START_MSG,
+            REPORT_LOCKED_BOOT_COMPLETE_MSG);
 
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         runWithDexmakerShareClassLoader(() -> {
-            mInjector = Mockito.spy(new TestInjector(getContext()));
+            mInjector = spy(new TestInjector(getTargetContext()));
             doNothing().when(mInjector).clearAllLockedTasks(anyString());
             doNothing().when(mInjector).startHomeActivity(anyInt(), anyString());
             doReturn(false).when(mInjector).stackSupervisorSwitchUser(anyInt(), any());
@@ -114,58 +131,54 @@
         });
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
+    @After
+    public void tearDown() throws Exception {
         mInjector.handlerThread.quit();
-        Mockito.validateMockitoUsage();
+        validateMockitoUsage();
     }
 
-    @SmallTest
-    public void testStartUser_foreground() throws RemoteException {
+    @Test
+    public void testStartUser_foreground() {
         mUserController.startUser(TEST_USER_ID, true /* foreground */);
-        Mockito.verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt());
-        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
-        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
-        Mockito.verify(mInjector.getWindowManager()).setSwitchingUser(true);
-        Mockito.verify(mInjector).clearAllLockedTasks(anyString());
+        verify(mInjector.getWindowManager()).startFreezingScreen(anyInt(), anyInt());
+        verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
+        verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
+        verify(mInjector.getWindowManager()).setSwitchingUser(true);
+        verify(mInjector).clearAllLockedTasks(anyString());
         startForegroundUserAssertions();
     }
 
-    @SmallTest
-    public void testStartUser_background() throws RemoteException {
+    @Test
+    public void testStartUser_background() {
         mUserController.startUser(TEST_USER_ID, false /* foreground */);
-        Mockito.verify(
-                mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
-        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
-        Mockito.verify(mInjector, never()).clearAllLockedTasks(anyString());
+        verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
+        verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
+        verify(mInjector, never()).clearAllLockedTasks(anyString());
         startBackgroundUserAssertions();
     }
 
-    @SmallTest
-    public void testStartUserUIDisabled() throws RemoteException {
+    @Test
+    public void testStartUserUIDisabled() {
         mUserController.mUserSwitchUiEnabled = false;
         mUserController.startUser(TEST_USER_ID, true /* foreground */);
-        Mockito.verify(mInjector.getWindowManager(), never())
-                .startFreezingScreen(anyInt(), anyInt());
-        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
-        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
+        verify(mInjector.getWindowManager(), never()).startFreezingScreen(anyInt(), anyInt());
+        verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
+        verify(mInjector.getWindowManager(), never()).setSwitchingUser(anyBoolean());
         startForegroundUserAssertions();
     }
 
     private void startUserAssertions(
-            List<String> expectedActions, Set<Integer> expectedMessageCodes)
-            throws RemoteException {
+            List<String> expectedActions, Set<Integer> expectedMessageCodes) {
         assertEquals(expectedActions, getActions(mInjector.sentIntents));
         Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
         assertEquals("Unexpected message sent", expectedMessageCodes, actualCodes);
     }
 
-    private void startBackgroundUserAssertions() throws RemoteException {
+    private void startBackgroundUserAssertions() {
         startUserAssertions(START_BACKGROUND_USER_ACTIONS, START_BACKGROUND_USER_MESSAGE_CODES);
     }
 
-    private void startForegroundUserAssertions() throws RemoteException {
+    private void startForegroundUserAssertions() {
         startUserAssertions(START_FOREGROUND_USER_ACTIONS, START_FOREGROUND_USER_MESSAGE_CODES);
         Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
         assertNotNull(reportMsg);
@@ -177,15 +190,15 @@
         assertEquals("Unexpected new user id", TEST_USER_ID, reportMsg.arg2);
     }
 
-    @SmallTest
-    public void testFailedStartUserInForeground() throws RemoteException {
+    @Test
+    public void testFailedStartUserInForeground() {
         mUserController.mUserSwitchUiEnabled = false;
         mUserController.startUserInForeground(NONEXIST_USER_ID);
-        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
-        Mockito.verify(mInjector.getWindowManager()).setSwitchingUser(false);
+        verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(anyBoolean());
+        verify(mInjector.getWindowManager()).setSwitchingUser(false);
     }
 
-    @SmallTest
+    @Test
     public void testDispatchUserSwitch() throws RemoteException {
         // Prepare mock observer and register it
         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
@@ -206,7 +219,7 @@
         // Call dispatchUserSwitch and verify that observer was called only once
         mInjector.handler.clearAllRecordedMessages();
         mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
-        Mockito.verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
+        verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
         Set<Integer> expectedCodes = Collections.singleton(CONTINUE_USER_SWITCH_MSG);
         Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
         assertEquals("Unexpected message sent", expectedCodes, actualCodes);
@@ -220,7 +233,7 @@
         assertEquals("Unexpected new user id", TEST_USER_ID, conMsg.arg2);
     }
 
-    @SmallTest
+    @Test
     public void testDispatchUserSwitchBadReceiver() throws RemoteException {
         // Prepare mock observer which doesn't notify the callback and register it
         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
@@ -236,14 +249,14 @@
         // Call dispatchUserSwitch and verify that observer was called only once
         mInjector.handler.clearAllRecordedMessages();
         mUserController.dispatchUserSwitch(userState, oldUserId, newUserId);
-        Mockito.verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
+        verify(observer, times(1)).onUserSwitching(eq(TEST_USER_ID), any());
         // Verify that CONTINUE_USER_SWITCH_MSG is not sent (triggers timeout)
         Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
-        assertTrue("No messages should be sent", actualCodes.isEmpty());
+        assertWithMessage("No messages should be sent").that(actualCodes).isEmpty();
     }
 
-    @SmallTest
-    public void testContinueUserSwitch() throws RemoteException {
+    @Test
+    public void testContinueUserSwitch() {
         // Start user -- this will update state of mUserController
         mUserController.startUser(TEST_USER_ID, true);
         Message reportMsg = mInjector.handler.getMessageForCode(REPORT_USER_SWITCH_MSG);
@@ -254,12 +267,12 @@
         mInjector.handler.clearAllRecordedMessages();
         // Verify that continueUserSwitch worked as expected
         mUserController.continueUserSwitch(userState, oldUserId, newUserId);
-        Mockito.verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
+        verify(mInjector.getWindowManager(), times(1)).stopFreezingScreen();
         continueUserSwitchAssertions();
     }
 
-    @SmallTest
-    public void testContinueUserSwitchUIDisabled() throws RemoteException {
+    @Test
+    public void testContinueUserSwitchUIDisabled() {
         mUserController.mUserSwitchUiEnabled = false;
         // Start user -- this will update state of mUserController
         mUserController.startUser(TEST_USER_ID, true);
@@ -271,11 +284,11 @@
         mInjector.handler.clearAllRecordedMessages();
         // Verify that continueUserSwitch worked as expected
         mUserController.continueUserSwitch(userState, oldUserId, newUserId);
-        Mockito.verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
+        verify(mInjector.getWindowManager(), never()).stopFreezingScreen();
         continueUserSwitchAssertions();
     }
 
-    private void continueUserSwitchAssertions() throws RemoteException {
+    private void continueUserSwitchAssertions() {
         Set<Integer> expectedCodes = Collections.singleton(REPORT_USER_SWITCH_COMPLETE_MSG);
         Set<Integer> actualCodes = mInjector.handler.getMessageCodes();
         assertEquals("Unexpected message sent", expectedCodes, actualCodes);
@@ -284,7 +297,7 @@
         assertEquals("Unexpected userId", TEST_USER_ID, msg.arg1);
     }
 
-    @SmallTest
+    @Test
     public void testDispatchUserSwitchComplete() throws RemoteException {
         // Prepare mock observer and register it
         IUserSwitchObserver observer = mock(IUserSwitchObserver.class);
@@ -298,12 +311,12 @@
         mInjector.handler.clearAllRecordedMessages();
         // Mockito can't reset only interactions, so just verify that this hasn't been
         // called with 'false' until after dispatchUserSwitchComplete.
-        Mockito.verify(mInjector.getWindowManager(), never()).setSwitchingUser(false);
+        verify(mInjector.getWindowManager(), never()).setSwitchingUser(false);
         // Call dispatchUserSwitchComplete
         mUserController.dispatchUserSwitchComplete(newUserId);
-        Mockito.verify(observer, times(1)).onUserSwitchComplete(anyInt());
-        Mockito.verify(observer).onUserSwitchComplete(TEST_USER_ID);
-        Mockito.verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false);
+        verify(observer, times(1)).onUserSwitchComplete(anyInt());
+        verify(observer).onUserSwitchComplete(TEST_USER_ID);
+        verify(mInjector.getWindowManager(), times(1)).setSwitchingUser(false);
     }
 
     private void setUpUser(int userId, int flags) {
@@ -320,7 +333,7 @@
     }
 
     // Should be public to allow mocking
-    public static class TestInjector extends UserController.Injector {
+    private static class TestInjector extends UserController.Injector {
         TestHandler handler;
         TestHandler uiHandler;
         HandlerThread handlerThread;
@@ -438,4 +451,4 @@
             return super.sendMessageAtTime(msg, uptimeMillis);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
index 79eba68..92211ec 100644
--- a/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/TrampolineTest.java
@@ -887,7 +887,7 @@
         }
 
         @Override
-        protected BackupManagerServiceInterface createBackupManagerService() {
+        protected BackupManagerService createBackupManagerService() {
             mCreateServiceCallsCount++;
             return sBackupManagerServiceMock;
         }
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
index 9fcdf2d..d52051eec 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java
@@ -436,7 +436,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -456,7 +455,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -537,7 +535,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -560,7 +557,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -583,7 +579,6 @@
                         new Signature[] {signature1Copy, signature2Copy},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -606,7 +601,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -629,7 +623,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -654,8 +647,7 @@
                         new Signature[] {SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        new Signature[] {SIGNATURE_1, SIGNATURE_2},
-                        new int[] {0, 0}));
+                        new Signature[] {SIGNATURE_1, SIGNATURE_2}));
         packageInfo.applicationInfo = new ApplicationInfo();
 
         // we know signature1Copy is in history, and we want to assume it has
@@ -682,8 +674,7 @@
                         new Signature[] {SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        new Signature[] {SIGNATURE_1, SIGNATURE_2},
-                        new int[] {0, 0}));
+                        new Signature[] {SIGNATURE_1, SIGNATURE_2}));
         packageInfo.applicationInfo = new ApplicationInfo();
 
         // we know signature1Copy is in history, but we want to assume it does not have
diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
index 12f2991..4774985 100644
--- a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -377,7 +377,6 @@
                         new Signature[] {FAKE_SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         PackageManagerStub.sPackageInfo = packageInfo;
 
@@ -414,7 +413,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         PackageManagerStub.sPackageInfo = packageInfo;
 
@@ -452,7 +450,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         PackageManagerStub.sPackageInfo = packageInfo;
 
@@ -493,7 +490,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.versionCode = 2;
         PackageManagerStub.sPackageInfo = packageInfo;
@@ -537,7 +533,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.versionCode = 1;
         PackageManagerStub.sPackageInfo = packageInfo;
@@ -577,7 +572,6 @@
                         new Signature[] {FAKE_SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.versionCode = 1;
         PackageManagerStub.sPackageInfo = packageInfo;
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index ceee60c..b421280 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.display;
 
+import static com.android.server.display.VirtualDisplayAdapter.UNIQUE_ID_PREFIX;
+
 import android.content.Context;
 import android.hardware.display.BrightnessConfiguration;
 import android.hardware.display.Curve;
@@ -25,35 +27,48 @@
 import android.hardware.input.InputManagerInternal;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.UserHandle;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
+import android.view.Display;
+import android.view.DisplayInfo;
 import android.view.SurfaceControl;
 
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
 import com.android.server.display.DisplayDeviceInfo;
 import com.android.server.display.DisplayManagerService.SyncRoot;
-import com.android.server.display.VirtualDisplayAdapter.SurfaceControlDisplayFactory;
 import com.android.server.lights.LightsManager;
 import com.android.server.wm.WindowManagerInternal;
 
+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.util.Arrays;
 import java.util.List;
 
-import static org.mockito.Matchers.any;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.mock;
 
 @SmallTest
-public class DisplayManagerServiceTest extends AndroidTestCase {
+@RunWith(AndroidJUnit4.class)
+public class DisplayManagerServiceTest {
     private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1;
     private static final long SHORT_DEFAULT_DISPLAY_TIMEOUT_MILLIS = 10;
 
+    private Context mContext;
+
     private final DisplayManagerService.Injector mShortMockedInjector =
             new DisplayManagerService.Injector() {
                 @Override
@@ -86,8 +101,8 @@
     @Mock VirtualDisplayAdapter mMockVirtualDisplayAdapter;
     @Mock IBinder mMockDisplayToken;
 
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
 
         LocalServices.removeServiceForTest(InputManagerInternal.class);
@@ -96,15 +111,12 @@
         LocalServices.addService(WindowManagerInternal.class, mMockWindowManagerInternal);
         LocalServices.removeServiceForTest(LightsManager.class);
         LocalServices.addService(LightsManager.class, mMockLightsManager);
-        super.setUp();
+
+        mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testCreateVirtualDisplay_sentToInputManager() throws Exception {
+    @Test
+    public void testCreateVirtualDisplay_sentToInputManager() {
         DisplayManagerService displayManager =
                 new DisplayManagerService(mContext, mBasicInjector);
         registerDefaultDisplays(displayManager);
@@ -115,7 +127,7 @@
         DisplayManagerService.BinderService bs = displayManager.new BinderService();
 
         String uniqueId = "uniqueId --- Test";
-        String uniqueIdPrefix = "virtual:" + mContext.getPackageName() + ":";
+        String uniqueIdPrefix = UNIQUE_ID_PREFIX + mContext.getPackageName() + ":";
         int width = 600;
         int height = 800;
         int dpi = 320;
@@ -132,19 +144,113 @@
         // flush the handler
         displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
 
-        ArgumentCaptor<List<DisplayViewport>> virtualViewportCaptor =
-                ArgumentCaptor.forClass(List.class);
-        verify(mMockInputManagerInternal).setDisplayViewports(
-                any(), any(), virtualViewportCaptor.capture());
+        ArgumentCaptor<List<DisplayViewport>> viewportCaptor = ArgumentCaptor.forClass(List.class);
+        verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture());
+        List<DisplayViewport> viewports = viewportCaptor.getValue();
 
-        assertEquals(1, virtualViewportCaptor.getValue().size());
-        DisplayViewport dv = virtualViewportCaptor.getValue().get(0);
-        assertEquals(height, dv.deviceHeight);
-        assertEquals(width, dv.deviceWidth);
-        assertEquals(uniqueIdPrefix + uniqueId, dv.uniqueId);
-        assertEquals(displayId, dv.displayId);
+        // Expect to receive 3 viewports: internal, external, and virtual
+        assertEquals(3, viewports.size());
+
+        DisplayViewport virtualViewport = null;
+        DisplayViewport internalViewport = null;
+        DisplayViewport externalViewport = null;
+        for (int i = 0; i < viewports.size(); i++) {
+            DisplayViewport v = viewports.get(i);
+            switch (v.type) {
+                case DisplayViewport.VIEWPORT_INTERNAL: {
+                    internalViewport = v;
+                    break;
+                }
+                case DisplayViewport.VIEWPORT_EXTERNAL: {
+                    externalViewport = v;
+                    break;
+                }
+                case DisplayViewport.VIEWPORT_VIRTUAL: {
+                    virtualViewport = v;
+                    break;
+                }
+            }
+        }
+        // INTERNAL and EXTERNAL viewports get created upon access
+        assertNotNull(internalViewport);
+        assertNotNull(externalViewport);
+        assertNotNull(virtualViewport);
+
+        // INTERNAL and EXTERNAL
+        assertTrue(internalViewport.valid);
+        assertTrue(externalViewport.valid);
+
+        // VIRTUAL
+        assertEquals(height, virtualViewport.deviceHeight);
+        assertEquals(width, virtualViewport.deviceWidth);
+        assertEquals(uniqueIdPrefix + uniqueId, virtualViewport.uniqueId);
+        assertEquals(displayId, virtualViewport.displayId);
     }
 
+    @Test
+    public void testPhysicalViewports() {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mBasicInjector);
+        registerDefaultDisplays(displayManager);
+        displayManager.systemReady(false /* safeMode */, true /* onlyCore */);
+        displayManager.windowManagerAndInputReady();
+
+        // This is effectively the DisplayManager service published to ServiceManager.
+        DisplayManagerService.BinderService bs = displayManager.new BinderService();
+
+        when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+
+        final int displayIds[] = bs.getDisplayIds();
+        assertEquals(1, displayIds.length);
+        final int displayId = displayIds[0];
+        DisplayInfo info = bs.getDisplayInfo(displayId);
+        assertEquals(info.type, Display.TYPE_BUILT_IN);
+
+        displayManager.performTraversalInternal(mock(SurfaceControl.Transaction.class));
+
+        // flush the handler
+        displayManager.getDisplayHandler().runWithScissors(() -> {}, 0 /* now */);
+
+        ArgumentCaptor<List<DisplayViewport>> viewportCaptor = ArgumentCaptor.forClass(List.class);
+        verify(mMockInputManagerInternal).setDisplayViewports(viewportCaptor.capture());
+        List<DisplayViewport> viewports = viewportCaptor.getValue();
+
+        // Expect to receive 2 viewports: 1 internal, 1 external
+        assertEquals(2, viewports.size());
+
+        DisplayViewport internalViewport = null;
+        DisplayViewport externalViewport = null;
+        for (int i = 0; i < viewports.size(); i++) {
+            DisplayViewport v = viewports.get(i);
+            switch (v.type) {
+                case DisplayViewport.VIEWPORT_INTERNAL: {
+                    internalViewport = v;
+                    break;
+                }
+                case DisplayViewport.VIEWPORT_EXTERNAL: {
+                    externalViewport = v;
+                    break;
+                }
+                default: {
+                    fail("Unexpected viewport type: " + DisplayViewport.typeToString(v.type));
+                    break;
+                }
+            }
+        }
+        // INTERNAL and EXTERNAL viewports get created upon access
+        assertNotNull(internalViewport);
+        assertNotNull(externalViewport);
+        assertTrue(internalViewport.valid);
+        assertEquals(displayId, internalViewport.displayId);
+
+        // To simplify comparison, override the type for external Viewport
+        // TODO (b/116850516) remove this
+        externalViewport.type = internalViewport.type;
+        assertEquals(internalViewport, externalViewport);
+        externalViewport.type = DisplayViewport.VIEWPORT_EXTERNAL; // undo the changes above
+    }
+
+    @Test
     public void testCreateVirtualDisplayRotatesWithContent() throws Exception {
         DisplayManagerService displayManager =
                 new DisplayManagerService(mContext, mBasicInjector);
@@ -178,6 +284,7 @@
     /**
      * Tests that the virtual display is created along-side the default display.
      */
+    @Test
     public void testStartVirtualDisplayWithDefaultDisplay_Succeeds() throws Exception {
         DisplayManagerService displayManager =
                 new DisplayManagerService(mContext, mShortMockedInjector);
@@ -188,6 +295,7 @@
     /**
      * Tests that we get a Runtime exception when we cannot initialize the default display.
      */
+    @Test
     public void testStartVirtualDisplayWithDefDisplay_NoDefaultDisplay() throws Exception {
         DisplayManagerService displayManager =
                 new DisplayManagerService(mContext, mShortMockedInjector);
@@ -206,6 +314,7 @@
     /**
      * Tests that we get a Runtime exception when we cannot initialize the virtual display.
      */
+    @Test
     public void testStartVirtualDisplayWithDefDisplay_NoVirtualDisplayAdapter() throws Exception {
         DisplayManagerService displayManager = new DisplayManagerService(mContext,
                 new DisplayManagerService.Injector() {
@@ -232,6 +341,7 @@
     /**
      * Tests that an exception is raised for too dark a brightness configuration.
      */
+    @Test
     public void testTooDarkBrightnessConfigurationThrowException() {
         DisplayManagerService displayManager =
                 new DisplayManagerService(mContext, mShortMockedInjector);
@@ -266,6 +376,7 @@
     /**
      * Tests that no exception is raised for not too dark a brightness configuration.
      */
+    @Test
     public void testBrightEnoughBrightnessConfigurationDoesNotThrowException() {
         DisplayManagerService displayManager =
                 new DisplayManagerService(mContext, mShortMockedInjector);
@@ -279,6 +390,7 @@
     /**
      * Tests that null brightness configurations are alright.
      */
+    @Test
     public void testNullBrightnessConfiguration() {
         DisplayManagerService displayManager =
                 new DisplayManagerService(mContext, mShortMockedInjector);
diff --git a/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
new file mode 100644
index 0000000..0328621
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/inputmethod/InputMethodManagerServiceTests.java
@@ -0,0 +1,102 @@
+/*
+ * 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.inputmethod;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class InputMethodManagerServiceTests {
+    static final int SYSTEM_DECORATION_SUPPORT_DISPLAY_ID = 2;
+    static final int NO_SYSTEM_DECORATION_SUPPORT_DISPLAY_ID = 3;
+
+    static InputMethodManagerService.ImeDisplayValidator sChecker =
+            (displayId) -> {
+                switch (displayId) {
+                    case SYSTEM_DECORATION_SUPPORT_DISPLAY_ID:
+                        return true;
+                    case NO_SYSTEM_DECORATION_SUPPORT_DISPLAY_ID:
+                        return false;
+                    default:
+                        throw new IllegalArgumentException("Unknown displayId=" + displayId);
+                }
+            };
+
+    static InputMethodManagerService.ImeDisplayValidator sMustNotBeCalledChecker =
+            (displayId) -> {
+                fail("Should not pass to display config check for this test case.");
+                return false;
+            };
+
+    @Test
+    public void testComputeImeDisplayId_defaultDisplayId() {
+        // Make sure that there is a short-circuit for DEFAULT_DISPLAY.
+        assertEquals(DEFAULT_DISPLAY,
+                InputMethodManagerService.computeImeDisplayIdForTarget(
+                        DEFAULT_DISPLAY, false /* isVrImeStarted */,
+                        sMustNotBeCalledChecker));
+    }
+
+    @Test
+    public void testComputeImeDisplayId_InvalidDisplayId() {
+        // Make sure that there is a short-circuit for INVALID_DISPLAY.
+        assertEquals(DEFAULT_DISPLAY,
+                InputMethodManagerService.computeImeDisplayIdForTarget(
+                        INVALID_DISPLAY, false /* isVrImeStarted */,
+                        sMustNotBeCalledChecker));
+    }
+
+    @Test
+    public void testComputeImeDisplayId_VrIme() {
+        // Make sure that there is a short-circuit for VR IME.
+        assertEquals(DEFAULT_DISPLAY,
+                InputMethodManagerService.computeImeDisplayIdForTarget(
+                        SYSTEM_DECORATION_SUPPORT_DISPLAY_ID, true /* isVrImeStarted */,
+                        sMustNotBeCalledChecker));
+    }
+
+    @Test
+    public void testComputeImeDisplayId_noSystemDecorationSupportDisplay() {
+        // Presume display didn't support system decoration.
+        // Make sure IME displayId is DEFAULT_DISPLAY.
+        assertEquals(DEFAULT_DISPLAY,
+                InputMethodManagerService.computeImeDisplayIdForTarget(
+                        NO_SYSTEM_DECORATION_SUPPORT_DISPLAY_ID, false /* isVrImeStarted */,
+                        sChecker));
+    }
+
+    @Test
+    public void testComputeImeDisplayId_withSystemDecorationSupportDisplay() {
+        // Presume display support system decoration.
+        // Make sure IME displayId is the same display.
+        assertEquals(SYSTEM_DECORATION_SUPPORT_DISPLAY_ID,
+                InputMethodManagerService.computeImeDisplayIdForTarget(
+                        SYSTEM_DECORATION_SUPPORT_DISPLAY_ID, false /* isVrImeStarted */,
+                        sChecker));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 2de5d87..a3348c2 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -1052,7 +1052,6 @@
                         genSignatures(signatures),
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         return pi;
     }
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index c3c0788..517b5ad 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -37,6 +37,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageParser;
 import android.content.pm.PackageUserState;
+import android.content.pm.SuspendDialogInfo;
 import android.content.pm.UserInfo;
 import android.os.BaseBundle;
 import android.os.PersistableBundle;
@@ -200,13 +201,21 @@
                 PACKAGE_NAME_1, 1L, 0.01, true, "appString1");
         final PersistableBundle launcherExtras1 = getPersistableBundle(
                 PACKAGE_NAME_1, 10L, 0.1, false, "launcherString1");
-        ps1.setSuspended(true, "suspendingPackage1", "dialogMsg1", appExtras1, launcherExtras1, 0);
+
+        final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder()
+                .setIcon(0x11220001)
+                .setTitle(0x11220002)
+                .setMessage("1st message")
+                .setNeutralButtonText(0x11220003)
+                .build();
+
+        ps1.setSuspended(true, "suspendingPackage1", dialogInfo1, appExtras1, launcherExtras1, 0);
         settingsUnderTest.mPackages.put(PACKAGE_NAME_1, ps1);
 
-        ps2.setSuspended(true, "suspendingPackage2", "dialogMsg2", null, null, 0);
+        ps2.setSuspended(true, "suspendingPackage2", null, null, null, 0);
         settingsUnderTest.mPackages.put(PACKAGE_NAME_2, ps2);
 
-        ps3.setSuspended(false, "irrelevant", "irrevelant2", null, null, 0);
+        ps3.setSuspended(false, "irrelevant", dialogInfo1, null, null, 0);
         settingsUnderTest.mPackages.put(PACKAGE_NAME_3, ps3);
 
         settingsUnderTest.writePackageRestrictionsLPr(0);
@@ -221,7 +230,7 @@
                 readUserState(0);
         assertThat(readPus1.suspended, is(true));
         assertThat(readPus1.suspendingPackage, equalTo("suspendingPackage1"));
-        assertThat(readPus1.dialogMessage, equalTo("dialogMsg1"));
+        assertThat(readPus1.dialogInfo, equalTo(dialogInfo1));
         assertThat(BaseBundle.kindofEquals(readPus1.suspendedAppExtras, appExtras1), is(true));
         assertThat(BaseBundle.kindofEquals(readPus1.suspendedLauncherExtras, launcherExtras1),
                 is(true));
@@ -230,7 +239,7 @@
                 readUserState(0);
         assertThat(readPus2.suspended, is(true));
         assertThat(readPus2.suspendingPackage, equalTo("suspendingPackage2"));
-        assertThat(readPus2.dialogMessage, equalTo("dialogMsg2"));
+        assertThat(readPus2.dialogInfo, is(nullValue()));
         assertThat(readPus2.suspendedAppExtras, is(nullValue()));
         assertThat(readPus2.suspendedLauncherExtras, is(nullValue()));
 
@@ -238,7 +247,7 @@
                 readUserState(0);
         assertThat(readPus3.suspended, is(false));
         assertThat(readPus3.suspendingPackage, is(nullValue()));
-        assertThat(readPus3.dialogMessage, is(nullValue()));
+        assertThat(readPus3.dialogInfo, is(nullValue()));
         assertThat(readPus3.suspendedAppExtras, is(nullValue()));
         assertThat(readPus3.suspendedLauncherExtras, is(nullValue()));
     }
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 318ed3a..9af7b1c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -504,7 +504,6 @@
                         new Signature[] { new Signature(new byte[16]) },
                         2,
                         new ArraySet<>(),
-                        null,
                         null);
         pkg.mExtras = new Bundle();
         pkg.mRestrictedAccountType = "foo19";
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
new file mode 100644
index 0000000..d3a77d3
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
@@ -0,0 +1,474 @@
+/*
+ * 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.pm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.content.pm.PackageParser;
+import android.content.pm.Signature;
+import android.util.Xml;
+
+import androidx.test.InstrumentationRegistry;
+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 org.xmlpull.v1.XmlPullParser;
+
+import java.io.File;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class PackageSignaturesTest {
+    private static final String TEST_RESOURCES_FOLDER = "PackageSignaturesTest";
+
+    private Context mContext;
+
+    private PackageSetting mPackageSetting;
+
+    // These signatures are the DER encoding of the ec-p256[_X] X509 certificates in the certs/
+    // directory. The apksigner tool was used to sign a test APK with these certificates and the
+    // corresponding ec-p256{_X].pk8 private key file. For the lineage tests the
+    // ec-p256-lineage-X-signers file was provided as the parameter to the --lineage option when
+    // signing the APK. The APK was then installed on a test device, the packages.xml file was
+    // pulled from the device, and the APK's <sig> tag was used as the basis for these tests.
+    // For more details see the README under the xml/ directory.
+    private static final String FIRST_EXPECTED_SIGNATURE =
+            "3082016c30820111a003020102020900ca0fb64dfb66e772300a06082a8648ce3d04030230123110300e06"
+            + "035504030c0765632d70323536301e170d3136303333313134353830365a170d34333038313731343538"
+            + "30365a30123110300e06035504030c0765632d703235363059301306072a8648ce3d020106082a8648ce"
+            + "3d03010703420004a65f113d22cb4913908307ac31ee2ba0e9138b785fac6536d14ea2ce90d2b4bfe194"
+            + "b50cdc8e169f54a73a991ef0fa76329825be078cc782740703da44b4d7eba350304e301d0603551d0e04"
+            + "160414d4133568b95b30158b322071ea8c43ff5b05ccc8301f0603551d23041830168014d4133568b95b"
+            + "30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d0403020349"
+            + "003046022100f504a0866caef029f417142c5cb71354c79ffcd1d640618dfca4f19e16db78d6022100f8"
+            + "eea4829799c06cad08c6d3d2d2ec05e0574154e747ea0fdbb8042cb655aadd";
+    private static final String SECOND_EXPECTED_SIGNATURE =
+            "3082016d30820113a0030201020209008855bd1dd2b2b225300a06082a8648ce3d04030230123110300e06"
+            + "035504030c0765632d70323536301e170d3138303731333137343135315a170d32383037313031373431"
+            + "35315a30143112301006035504030c0965632d703235365f323059301306072a8648ce3d020106082a86"
+            + "48ce3d030107034200041d4cca0472ad97ee3cecef0da93d62b450c6788333b36e7553cde9f74ab5df00"
+            + "bbba6ba950e68461d70bbc271b62151dad2de2bf6203cd2076801c7a9d4422e1a350304e301d0603551d"
+            + "0e041604147991d92b0208fc448bf506d4efc9fff428cb5e5f301f0603551d23041830168014d4133568"
+            + "b95b30158b322071ea8c43ff5b05ccc8300c0603551d13040530030101ff300a06082a8648ce3d040302"
+            + "034800304502202769abb1b49fc2f53479c4ae92a6631dabfd522c9acb0bba2b43ebeb99c63011022100"
+            + "d260fb1d1f176cf9b7fa60098bfd24319f4905a3e5fda100a6fe1a2ab19ff09e";
+    private static final String THIRD_EXPECTED_SIGNATURE =
+            "3082016e30820115a0030201020209008394f5cad16a89a7300a06082a8648ce3d04030230143112301006"
+            + "035504030c0965632d703235365f32301e170d3138303731343030303532365a170d3238303731313030"
+            + "303532365a30143112301006035504030c0965632d703235365f333059301306072a8648ce3d02010608"
+            + "2a8648ce3d03010703420004f31e62430e9db6fc5928d975fc4e47419bacfcb2e07c89299e6cd7e344dd"
+            + "21adfd308d58cb49a1a2a3fecacceea4862069f30be1643bcc255040d8089dfb3743a350304e301d0603"
+            + "551d0e041604146f8d0828b13efaf577fc86b0e99fa3e54bcbcff0301f0603551d230418301680147991"
+            + "d92b0208fc448bf506d4efc9fff428cb5e5f300c0603551d13040530030101ff300a06082a8648ce3d04"
+            + "030203470030440220256bdaa2784c273e4cc291a595a46779dee9de9044dc9f7ab820309567df9fe902"
+            + "201a4ad8c69891b5a8c47434fe9540ed1f4979b5fad3483f3fa04d5677355a579e";
+
+    // When running tests using the pastSigs tag / lineage the past signers and their capabilities
+    // should be returned in the SigningDetails. The flags attribute of the cert tag under the
+    // pastSigs tag contains these capabilities; for tests that verify the lineage the capabilities
+    // of the signers should be set to the values in this Map.
+    private static final Map<String, Integer> SIGNATURE_TO_CAPABILITY_MAP;
+
+    static {
+        SIGNATURE_TO_CAPABILITY_MAP = new HashMap<>();
+        SIGNATURE_TO_CAPABILITY_MAP.put(FIRST_EXPECTED_SIGNATURE, 3);
+        SIGNATURE_TO_CAPABILITY_MAP.put(SECOND_EXPECTED_SIGNATURE, 7);
+        SIGNATURE_TO_CAPABILITY_MAP.put(THIRD_EXPECTED_SIGNATURE, 23);
+    }
+
+    private static final int[] CAPABILITIES =
+            {PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA,
+                    PackageParser.SigningDetails.CertCapabilities.SHARED_USER_ID,
+                    PackageParser.SigningDetails.CertCapabilities.PERMISSION,
+                    PackageParser.SigningDetails.CertCapabilities.ROLLBACK};
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mPackageSetting = createPackageSetting();
+    }
+
+    @Test
+    public void testReadXmlWithOneSignerCompletesSuccessfully() throws Exception {
+        // Verifies the good path of reading a single sigs tag with one signer returns the
+        // expected signature and scheme version.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer.xml", 1, FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithTwoV1V2Signers() throws Exception {
+        // Verifies the good path of reading a single sigs tag with multiple signers returns the
+        // expected signatures and scheme version.
+        verifyReadXmlReturnsExpectedSignatures("xml/two-signers-v1v2.xml", 2,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlFromTwoSigsTagsWithSameSigner() throws Exception {
+        // Verifies the good path of reading two separate packages tags from the same signer. The
+        // first call to readXml should return the list with the expected signature, then the second
+        // call should reference this signature and complete successfully with no new entries in the
+        // List.
+        XmlPullParser parser = getXMLFromResources("xml/one-signer.xml");
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        Set<String> expectedSignatures = createSetOfSignatures(FIRST_EXPECTED_SIGNATURE);
+        verifySignaturesContainExpectedValues(signatures, expectedSignatures);
+        parser = getXMLFromResources("xml/one-signer-previous-cert.xml");
+        mPackageSetting.signatures.readXml(parser, signatures);
+        expectedSignatures = createSetOfSignatures(FIRST_EXPECTED_SIGNATURE);
+        verifySignaturesContainExpectedValues(signatures, expectedSignatures);
+    }
+
+    @Test
+    public void testReadXmlWithSigningLineage() throws Exception {
+        // Verifies the good path of reading a single sigs tag including pastSigs with the
+        // signing lineage returns the expected signatures and lineage for two and three signers
+        // in the lineage.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage("xml/two-signers-in-lineage.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+        verifyReadXmlReturnsExpectedSignaturesAndLineage("xml/three-signers-in-lineage.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE, THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidPublicKeyInCertKey() throws Exception {
+        // If the cert tag key attribute does not contain a valid public key then a
+        // CertificateException should be thrown when attempting to build the SigningDetails; in
+        // this case the signing details should be set to UNKNOWN.
+        XmlPullParser parser = getXMLFromResources(
+                "xml/one-signer-invalid-public-key-cert-key.xml");
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        assertEquals(
+                "The signing details was not UNKNOWN after parsing an invalid public key cert key"
+                        + " attribute",
+                PackageParser.SigningDetails.UNKNOWN, mPackageSetting.signatures.mSigningDetails);
+    }
+
+    @Test
+    public void testReadXmlWithMissingSigsCount() throws Exception {
+        // Verifies if the sigs count attribute is missing then the signature cannot be read but the
+        // method does not throw an exception.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-sigs-count.xml",
+                PackageParser.SigningDetails.SignatureSchemeVersion.UNKNOWN);
+    }
+
+    @Test
+    public void testReadXmlWithMissingSchemeVersion() throws Exception {
+        // Verifies if the schemeVersion is an invalid value the signature can still be obtained.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-scheme-version.xml",
+                PackageParser.SigningDetails.SignatureSchemeVersion.UNKNOWN,
+                FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithSigningLineageWithMissingSchemeVersion() throws Exception {
+        // Verifies if the scheme version cannot be read the signers in the lineage can still be
+        // obtained.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/three-signers-in-lineage-missing-scheme-version.xml",
+                PackageParser.SigningDetails.SignatureSchemeVersion.UNKNOWN,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE, THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidCertIndex() throws Exception {
+        // If the cert index attribute is invalid the signature will not be read but the call
+        // should exit gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-invalid-cert-index.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithMissingCertIndex() throws Exception {
+        // If the cert index attribute is missing the signature will not be read but the call should
+        // exit gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-cert-index.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidCertKey() throws Exception {
+        // If the cert key value is invalid the signature cannot be read but the call should exit
+        // gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-invalid-cert-key.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithMissingCertKey() throws Exception {
+        // If the cert key is missing the signature cannot be read but the call should exit
+        // gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-cert-key.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithMissingCertTag() throws Exception {
+        // If the cert tag is missing there is no signature to read but the call should exit
+        // gracefully.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-missing-cert-tag.xml", 3);
+    }
+
+    @Test
+    public void testReadXmlWithTooFewCertTags() throws Exception {
+        // If the number of cert tags is less than that specified in the count attribute then the
+        // signatures that could be read are copied to a smaller array to be used when building
+        // the SigningDetails object. This test verifies if there are too few cert tags the
+        // available signatures can still be obtained.
+        verifyReadXmlReturnsExpectedSignatures("xml/two-signers-v1v2-missing-cert-tag.xml", 1,
+                FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithExtraCertTag() throws Exception {
+        // Verifies if there are more cert tags than specified by the count attribute the extra cert
+        // tag is ignored and the expected signature from the first cert tag is returned.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-extra-cert-tag.xml", 3,
+                FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidTag() throws Exception {
+        // Verifies an invalid tag under sigs is ignored and the expected signature is returned.
+        verifyReadXmlReturnsExpectedSignatures("xml/one-signer-invalid-tag.xml", 3,
+                FIRST_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidPastSigsCount() throws Exception {
+        // Verifies if the pastSigs tag contains an invalid count attribute the current signature
+        // is still returned; in this case the third expected signature is the most recent signer.
+        verifyReadXmlReturnsExpectedSignatures(
+                "xml/three-signers-in-lineage-invalid-pastSigs-count.xml", 3,
+                THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithMissingPastSigsCount() throws Exception {
+        // Verifies if the pastSigs tag is missing the count attribute the current signature is
+        // still returned; in this case the third expected signature is the most recent signer.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/three-signers-in-lineage-missing-pastSigs-count.xml", 3,
+                THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidCertFlags() throws Exception {
+        // Verifies if the cert tag contains an invalid flags attribute the expected signatures
+        // are still returned, although since the flags could not be read these signatures will not
+        // include the capabilities of the previous signers in the lineage.
+        verifyReadXmlReturnsExpectedSignatures("xml/two-signers-in-lineage-invalid-certs-flags.xml",
+                3, FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithMissingCertFlags() throws Exception {
+        // Verifies if the cert tag does not contain a flags attribute the expected signatures are
+        // still returned, although since there are no flags to read these signatures will not
+        // include the capabilities of the previous signers in the lineage.
+        verifyReadXmlReturnsExpectedSignatures("xml/two-signers-in-lineage-missing-certs-flags.xml",
+                3, FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithMultiplePastSigsTags() throws Exception {
+        // Verifies if multiple pastSigs tags are found under the sigs tag the additional pastSigs
+        // tag is ignored and the expected signatures are returned along with the previous signer in
+        // the lineage.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/two-signers-in-lineage-multiple-pastSigs-tags.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithInvalidPastSigsCertIndex() throws Exception {
+        // If the pastSigs cert tag contains an invalid index attribute that signature cannot be
+        // read but the current signature should still be returned.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/two-signers-in-lineage-invalid-pastSigs-cert-index.xml", 3,
+                SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithMissingPastSigsCertIndex() throws Exception {
+        // If the pastSigs cert tag does not contain an index attribute that signature cannot be
+        // read but the current signature should still be returned.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/two-signers-in-lineage-missing-pastSigs-cert-index.xml", 3,
+                SECOND_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithUndefinedPastSigsIndex() throws Exception {
+        // If a cert tag does not contain a key attribute it is assumed that the index attribute
+        // refers to a previously seen signature. If a signature does not yet exist at this index
+        // then the current signature cannot be read but any other signatures should still be
+        // returned.
+        verifyReadXmlReturnsExpectedSignatures(
+                "xml/two-signers-in-lineage-undefined-pastSigs-index.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, null);
+    }
+
+    @Test
+    public void testReadXmlWithTooFewPastSigsCertTags() throws Exception {
+        // If the number of cert tags is less than that specified in the count attribute of the
+        // pastSigs tag then the signatures that could be read are copied to a smaller array to be
+        // used when building the SigningDetails object. This test verifies if there are too few
+        // cert tags the available signatures and lineage can still be obtained.
+        verifyReadXmlReturnsExpectedSignaturesAndLineage(
+                "xml/three-signers-in-lineage-missing-pastSigs-cert-tag.xml", 3,
+                FIRST_EXPECTED_SIGNATURE, THIRD_EXPECTED_SIGNATURE);
+    }
+
+    @Test
+    public void testReadXmlWithPastSignerWithNoCapabilities() throws Exception {
+        // When rotating the signing key a developer is able to specify the capabilities granted to
+        // the apps signed with the previous key. This test verifies a previous signing certificate
+        // with the flags set to 0 does not have any capabilities.
+        XmlPullParser parser = getXMLFromResources("xml/two-signers-in-lineage-no-caps.xml");
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        // obtain the Signature in the list matching the previous signing certificate
+        Signature previousSignature = null;
+        for (Signature signature : signatures) {
+            String signatureValue = HexDump.toHexString(signature.toByteArray(), false);
+            if (signatureValue.equals(FIRST_EXPECTED_SIGNATURE)) {
+                previousSignature = signature;
+                break;
+            }
+        }
+        assertNotNull("Unable to find the expected previous signer", previousSignature);
+        for (int capability : CAPABILITIES) {
+            assertFalse("The previous signer should not have the " + capability + " capability",
+                    mPackageSetting.signatures.mSigningDetails.hasCertificate(previousSignature,
+                            capability));
+        }
+    }
+
+    /**
+     * Verifies reading the sigs tag of the provided XML file returns the specified signature scheme
+     * version and the provided signatures.
+     */
+    private void verifyReadXmlReturnsExpectedSignatures(String xmlFile, int expectedSchemeVersion,
+            String... expectedSignatureValues) throws Exception {
+        XmlPullParser parser = getXMLFromResources(xmlFile);
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        Set<String> expectedSignatures = createSetOfSignatures(expectedSignatureValues);
+        verifySignaturesContainExpectedValues(signatures, expectedSignatures);
+        assertEquals("The returned signature scheme is not the expected value",
+                expectedSchemeVersion,
+                mPackageSetting.signatures.mSigningDetails.signatureSchemeVersion);
+    }
+
+    /**
+     * Verifies reading the sigs tag of the provided XML file returns the specified signature scheme
+     * version, the provided signatures, and that the previous signers have the expected
+     * capabilities.
+     */
+    private void verifyReadXmlReturnsExpectedSignaturesAndLineage(String xmlFile,
+            int schemeVersion, String... expectedSignatureValues) throws Exception {
+        XmlPullParser parser = getXMLFromResources(xmlFile);
+        ArrayList<Signature> signatures = new ArrayList<>();
+        mPackageSetting.signatures.readXml(parser, signatures);
+        Set<String> expectedSignatures = createSetOfSignatures(expectedSignatureValues);
+        verifySignaturesContainExpectedValues(signatures, expectedSignatures);
+        assertEquals("The returned signature scheme is not the expected value", schemeVersion,
+                mPackageSetting.signatures.mSigningDetails.signatureSchemeVersion);
+        for (Signature signature : signatures) {
+            String signatureValue = HexDump.toHexString(signature.toByteArray(), false);
+            int expectedCapabilities = SIGNATURE_TO_CAPABILITY_MAP.get(signatureValue);
+            assertTrue("The signature " + signatureValue
+                            + " was not found with the expected capabilities of " +
+                            expectedCapabilities
+                            + " in the signing details",
+                    mPackageSetting.signatures.mSigningDetails.hasCertificate(signature,
+                            expectedCapabilities));
+        }
+    }
+
+    /**
+     * Verifies the provided {@code List} contains Signatures that match the provided hex encoded
+     * signature values.
+     *
+     * The provided {@code Set} will be modified by this method as elements will be removed to
+     * ensure duplicate expected Signatures are not in the {@code List}.
+     */
+    private static void verifySignaturesContainExpectedValues(ArrayList<Signature> signatures,
+            Set<String> expectedSignatures) {
+        assertEquals("The number of signatures does not equal the expected number of signatures",
+                expectedSignatures.size(), signatures.size());
+        for (Signature signature : signatures) {
+            String signatureString = null;
+            if (signature != null) {
+                signatureString = HexDump.toHexString(signature.toByteArray(), false);
+            }
+            // If the signature is in the expected set then remove it so that duplicate matching
+            // signatures are reported.
+            if (expectedSignatures.contains(signatureString)) {
+                expectedSignatures.remove(signatureString);
+            } else {
+                fail("The following unexpected signature was returned: " + signatureString);
+            }
+        }
+    }
+
+    private static Set<String> createSetOfSignatures(String... signatures) {
+        Set<String> result = new HashSet<String>();
+        for (String signature : signatures) {
+            result.add(signature);
+        }
+        return result;
+    }
+
+    private XmlPullParser getXMLFromResources(String xmlFile) throws Exception {
+        InputStream xmlStream = mContext.getResources().getAssets().open(
+                TEST_RESOURCES_FOLDER + "/" + xmlFile);
+        XmlPullParser result = Xml.newPullParser();
+        result.setInput(xmlStream, StandardCharsets.UTF_8.name());
+        int type;
+        // advance the parser to the first tag
+        while ((type = result.next()) != XmlPullParser.START_TAG
+                && type != XmlPullParser.END_DOCUMENT) {
+            ;
+        }
+        return result;
+    }
+
+    private static PackageSetting createPackageSetting() {
+        // Generic PackageSetting object with values from a test app installed on a device to be
+        // used to test the methods under the PackageSignatures signatures data member.
+        File appPath = new File("/data/app/app");
+        PackageSetting result = new PackageSetting("test.app", null, appPath, appPath,
+                "/data/app/app", null, null, null,
+                1, 940097092, 0, null,
+                null, 0 /*userId*/, null, null);
+        return result;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
index 4a33ca3..f0ed612 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageUserStateTest.java
@@ -23,6 +23,7 @@
 import static org.junit.Assert.assertThat;
 
 import android.content.pm.PackageUserState;
+import android.content.pm.SuspendDialogInfo;
 import android.os.PersistableBundle;
 import android.util.ArraySet;
 
@@ -37,7 +38,7 @@
 public class PackageUserStateTest {
 
     @Test
-    public void testPackageUserState01()  {
+    public void testPackageUserState01() {
         final PackageUserState testUserState = new PackageUserState();
         PackageUserState oldUserState;
 
@@ -84,7 +85,7 @@
     }
 
     @Test
-    public void testPackageUserState02()  {
+    public void testPackageUserState02() {
         final PackageUserState testUserState01 = new PackageUserState();
         PackageUserState oldUserState;
 
@@ -102,7 +103,7 @@
     }
 
     @Test
-    public void testPackageUserState03()  {
+    public void testPackageUserState03() {
         final PackageUserState oldUserState = new PackageUserState();
 
         // only new user state has array defined; different
@@ -138,7 +139,7 @@
     }
 
     @Test
-    public void testPackageUserState04()  {
+    public void testPackageUserState04() {
         final PackageUserState oldUserState = new PackageUserState();
 
         // only new user state has array defined; different
@@ -185,15 +186,19 @@
         launcherExtras2.putString("name", "launcherExtras2");
         final String suspendingPackage1 = "package1";
         final String suspendingPackage2 = "package2";
-        final String dialogMessage1 = "dialogMessage1";
-        final String dialogMessage2 = "dialogMessage2";
+        final SuspendDialogInfo dialogInfo1 = new SuspendDialogInfo.Builder()
+                .setMessage("dialogMessage1")
+                .build();
+        final SuspendDialogInfo dialogInfo2 = new SuspendDialogInfo.Builder()
+                .setMessage("dialogMessage2")
+                .build();
 
         final PackageUserState testUserState1 = new PackageUserState();
         testUserState1.suspended = true;
         testUserState1.suspendedAppExtras = appExtras1;
         testUserState1.suspendedLauncherExtras = launcherExtras1;
         testUserState1.suspendingPackage = suspendingPackage1;
-        testUserState1.dialogMessage = dialogMessage1;
+        testUserState1.dialogInfo = dialogInfo1;
 
         PackageUserState testUserState2 = new PackageUserState(testUserState1);
         assertThat(testUserState1.equals(testUserState2), is(true));
@@ -209,14 +214,14 @@
         assertThat(testUserState1.equals(testUserState2), is(false));
 
         testUserState2 = new PackageUserState(testUserState1);
-        testUserState2.dialogMessage = dialogMessage2;
+        testUserState2.dialogInfo = dialogInfo2;
         assertThat(testUserState1.equals(testUserState2), is(false));
 
         testUserState2 = new PackageUserState(testUserState1);
         testUserState2.suspended = testUserState1.suspended = false;
         // Everything is different but irrelevant if suspended is false
         testUserState2.suspendingPackage = suspendingPackage2;
-        testUserState2.dialogMessage = dialogMessage2;
+        testUserState2.dialogInfo = dialogInfo2;
         testUserState2.suspendedAppExtras = appExtras2;
         testUserState2.suspendedLauncherExtras = launcherExtras2;
         assertThat(testUserState1.equals(testUserState2), is(true));
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java
new file mode 100644
index 0000000..7eccd67
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendDialogInfoTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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.pm;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
+
+import android.content.pm.SuspendDialogInfo;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class SuspendDialogInfoTest {
+    private static final int VALID_TEST_RES_ID_1 = 0x11110001;
+    private static final int VALID_TEST_RES_ID_2 = 0x11110002;
+
+    private static SuspendDialogInfo.Builder createDefaultDialogBuilder() {
+        return new SuspendDialogInfo.Builder()
+                .setIcon(VALID_TEST_RES_ID_1)
+                .setTitle(VALID_TEST_RES_ID_1)
+                .setMessage(VALID_TEST_RES_ID_1)
+                .setNeutralButtonText(VALID_TEST_RES_ID_1);
+    }
+
+    @Test
+    public void equalsComparesIcons() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = createDefaultDialogBuilder();
+        final SuspendDialogInfo.Builder dialogBuilder2 = createDefaultDialogBuilder();
+        assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
+        // Only icon is different
+        dialogBuilder2.setIcon(VALID_TEST_RES_ID_2);
+        assertNotEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void equalsComparesTitle() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = createDefaultDialogBuilder();
+        final SuspendDialogInfo.Builder dialogBuilder2 = createDefaultDialogBuilder();
+        assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
+        // Only title is different
+        dialogBuilder2.setTitle(VALID_TEST_RES_ID_2);
+        assertNotEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void equalsComparesButtonText() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = createDefaultDialogBuilder();
+        final SuspendDialogInfo.Builder dialogBuilder2 = createDefaultDialogBuilder();
+        assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
+        // Only button text is different
+        dialogBuilder2.setNeutralButtonText(VALID_TEST_RES_ID_2);
+        assertNotEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void equalsComparesMessageIds() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = createDefaultDialogBuilder();
+        final SuspendDialogInfo.Builder dialogBuilder2 = createDefaultDialogBuilder();
+        assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
+        // Only message is different
+        dialogBuilder2.setMessage(VALID_TEST_RES_ID_2);
+        assertNotEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void equalsIgnoresMessageStringsWhenIdsSet() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = new SuspendDialogInfo.Builder()
+                .setMessage(VALID_TEST_RES_ID_1)
+                .setMessage("1st message");
+        final SuspendDialogInfo.Builder dialogBuilder2 = new SuspendDialogInfo.Builder()
+                .setMessage(VALID_TEST_RES_ID_1)
+                .setMessage("2nd message");
+        // String messages different but should get be ignored when resource ids are set
+        assertEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void equalsComparesMessageStringsWhenNoIdsSet() {
+        final SuspendDialogInfo.Builder dialogBuilder1 = new SuspendDialogInfo.Builder()
+                .setMessage("1st message");
+        final SuspendDialogInfo.Builder dialogBuilder2 = new SuspendDialogInfo.Builder()
+                .setMessage("2nd message");
+        // Both have different messages, which are not ignored as resource ids aren't set
+        assertNotEquals(dialogBuilder1.build(), dialogBuilder2.build());
+    }
+
+    @Test
+    public void messageStringClearedWhenResIdSet() {
+        final SuspendDialogInfo dialogInfo = new SuspendDialogInfo.Builder()
+                .setMessage(VALID_TEST_RES_ID_2)
+                .setMessage("Should be cleared on build")
+                .build();
+        assertNull(dialogInfo.getDialogMessage());
+        assertEquals(VALID_TEST_RES_ID_2, dialogInfo.getDialogMessageResId());
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
index f115b9c..553d234 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
@@ -33,6 +33,7 @@
 import android.content.pm.IPackageManager;
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageManager;
+import android.content.pm.SuspendDialogInfo;
 import android.content.res.Resources;
 import android.os.BaseBundle;
 import android.os.Bundle;
@@ -152,7 +153,7 @@
         }
 
         void drainPendingBroadcasts() {
-            while (pollForIntent(5) != null);
+            while (pollForIntent(5) != null) ;
         }
 
         Intent receiveIntentFromApp() {
@@ -215,15 +216,15 @@
     }
 
     private void suspendTestPackage(PersistableBundle appExtras, PersistableBundle launcherExtras,
-            String dialogMessage) {
+            SuspendDialogInfo dialogInfo) {
         final String[] unchangedPackages = mPackageManager.setPackagesSuspended(
-                PACKAGES_TO_SUSPEND, true, appExtras, launcherExtras, dialogMessage);
+                PACKAGES_TO_SUSPEND, true, appExtras, launcherExtras, dialogInfo);
         assertTrue("setPackagesSuspended returned non-empty list", unchangedPackages.length == 0);
     }
 
     private void unsuspendTestPackage() {
         final String[] unchangedPackages = mPackageManager.setPackagesSuspended(
-                PACKAGES_TO_SUSPEND, false, null, null, null);
+                PACKAGES_TO_SUSPEND, false, null, null, (SuspendDialogInfo) null);
         assertTrue("setPackagesSuspended returned non-empty list", unchangedPackages.length == 0);
     }
 
@@ -318,7 +319,8 @@
     @Test
     public void testCannotSuspendSelf() {
         final String[] unchangedPkgs = mPackageManager.setPackagesSuspended(
-                new String[]{mContext.getOpPackageName()}, true, null, null, null);
+                new String[]{mContext.getOpPackageName()}, true, null, null,
+                (SuspendDialogInfo) null);
         assertTrue(unchangedPkgs.length == 1);
         assertEquals(mContext.getOpPackageName(), unchangedPkgs[0]);
     }
@@ -457,7 +459,8 @@
         mAppCommsReceiver.register(mReceiverHandler, ACTION_REPORT_MORE_DETAILS_ACTIVITY_STARTED,
                 ACTION_REPORT_TEST_ACTIVITY_STARTED);
         final String testMessage = "This is a test message to report suspension of %1$s";
-        suspendTestPackage(null, null, testMessage);
+        suspendTestPackage(null, null,
+                new SuspendDialogInfo.Builder().setMessage(testMessage).build());
         startTestAppActivity();
         assertNull("No broadcast was expected from app", mAppCommsReceiver.pollForIntent(2));
         assertNotNull("Given dialog message not shown", mUiDevice.wait(
diff --git a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
index 13612a1..182760b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java
@@ -99,7 +99,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -119,7 +118,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -203,7 +201,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -226,7 +223,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -248,7 +244,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -271,7 +266,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -295,7 +289,6 @@
                         new Signature[] {SIGNATURE_1},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -320,7 +313,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
@@ -348,7 +340,6 @@
                         new Signature[] {SIGNATURE_1, SIGNATURE_2},
                         PackageParser.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V3,
                         null,
-                        null,
                         null));
         packageInfo.applicationInfo = new ApplicationInfo();
 
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
index acd065e..e16f118 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java
@@ -16,6 +16,10 @@
 
 package com.android.server.policy;
 
+import static android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM;
+import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
+import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT;
+import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
 import static android.view.Surface.ROTATION_0;
 import static android.view.Surface.ROTATION_180;
 import static android.view.Surface.ROTATION_270;
@@ -179,8 +183,25 @@
         transformPhysicalToLogicalCoordinates(rotation, DISPLAY_WIDTH, DISPLAY_HEIGHT, m);
         m.mapRect(rectF);
 
+        int pos = -1;
+        switch (rotation) {
+            case ROTATION_0:
+                pos = BOUNDS_POSITION_TOP;
+                break;
+            case ROTATION_90:
+                pos = BOUNDS_POSITION_LEFT;
+                break;
+            case ROTATION_180:
+                pos = BOUNDS_POSITION_BOTTOM;
+                break;
+            case ROTATION_270:
+                pos = BOUNDS_POSITION_RIGHT;
+                break;
+        }
+
+
         return DisplayCutout.fromBoundingRect((int) rectF.left, (int) rectF.top,
-                (int) rectF.right, (int) rectF.bottom);
+                (int) rectF.right, (int) rectF.bottom, pos);
     }
 
     static class TestContextWrapper extends ContextWrapper {
diff --git a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
index 54ac6fc..77f6a23 100644
--- a/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/BatterySaverPolicyTest.java
@@ -58,7 +58,8 @@
             + "adjust_brightness_factor=0.7,"
             + "fullbackup_deferred=true,"
             + "keyvaluebackup_deferred=false,"
-            + "gps_mode=0";
+            + "gps_mode=0,"
+            + "quick_doze_enabled=true";
     private static final String BATTERY_SAVER_INCORRECT_CONSTANTS = "vi*,!=,,true";
 
     private class BatterySaverPolicyForTest extends BatterySaverPolicy {
@@ -84,9 +85,6 @@
     }
 
     @Mock
-    Handler mHandler;
-
-    @Mock
     MetricsLogger mMetricsLogger = mock(MetricsLogger.class);
 
     private BatterySaverPolicyForTest mBatterySaverPolicy;
@@ -105,48 +103,48 @@
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyNull_DefaultValueCorrect() {
-        testServiceDefaultValue(ServiceType.NULL);
+        testServiceDefaultValue_On(ServiceType.NULL);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyVibration_DefaultValueCorrect() {
-        testServiceDefaultValue(ServiceType.VIBRATION);
+        testServiceDefaultValue_On(ServiceType.VIBRATION);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyVibration_WithAccessibilityEnabled() {
         mBatterySaverPolicy.setAccessibilityEnabledForTest(true);
-        testServiceDefaultValue_unchanged(ServiceType.VIBRATION);
+        testServiceDefaultValue_Off(ServiceType.VIBRATION);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicySound_DefaultValueCorrect() {
-        testServiceDefaultValue(ServiceType.SOUND);
+        testServiceDefaultValue_On(ServiceType.SOUND);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyFullBackup_DefaultValueCorrect() {
-        testServiceDefaultValue(ServiceType.FULL_BACKUP);
+        testServiceDefaultValue_On(ServiceType.FULL_BACKUP);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyKeyValueBackup_DefaultValueCorrect() {
-        testServiceDefaultValue(ServiceType.KEYVALUE_BACKUP);
+        testServiceDefaultValue_On(ServiceType.KEYVALUE_BACKUP);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyAnimation_DefaultValueCorrect() {
-        testServiceDefaultValue_unchanged(ServiceType.ANIMATION);
+        testServiceDefaultValue_Off(ServiceType.ANIMATION);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyBatteryStats_DefaultValueCorrect() {
-        testServiceDefaultValue(ServiceType.BATTERY_STATS);
+        testServiceDefaultValue_On(ServiceType.BATTERY_STATS);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyNetworkFirewall_DefaultValueCorrect() {
-        testServiceDefaultValue(ServiceType.NETWORK_FIREWALL);
+        testServiceDefaultValue_On(ServiceType.NETWORK_FIREWALL);
     }
 
     @SmallTest
@@ -163,12 +161,12 @@
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyScreenBrightness_DefaultValueCorrect() {
-        testServiceDefaultValue_unchanged(ServiceType.SCREEN_BRIGHTNESS);
+        testServiceDefaultValue_Off(ServiceType.SCREEN_BRIGHTNESS);
     }
 
     @SmallTest
     public void testGetBatterySaverPolicy_PolicyGps_DefaultValueCorrect() {
-        testServiceDefaultValue(ServiceType.GPS);
+        testServiceDefaultValue_On(ServiceType.GPS);
 
         PowerSaveState stateOn =
                 mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.GPS, true);
@@ -176,6 +174,11 @@
     }
 
     @SmallTest
+    public void testGetBatterySaverPolicy_PolicyQuickDoze_DefaultValueCorrect() {
+        testServiceDefaultValue_Off(ServiceType.QUICK_DOZE);
+    }
+
+    @SmallTest
     public void testUpdateConstants_getCorrectData() {
         mBatterySaverPolicy.updateConstantsLocked(BATTERY_SAVER_CONSTANTS, "");
 
@@ -217,6 +220,10 @@
                 mBatterySaverPolicy.getBatterySaverPolicy(ServiceType.GPS, BATTERY_SAVER_ON);
         assertThat(gpsState.batterySaverEnabled).isTrue();
         assertThat(gpsState.gpsMode).isEqualTo(GPS_MODE);
+
+        final PowerSaveState quickDozeState = mBatterySaverPolicy.getBatterySaverPolicy(
+                ServiceType.QUICK_DOZE, BATTERY_SAVER_ON);
+        assertThat(quickDozeState.batterySaverEnabled).isTrue();
     }
 
     @SmallTest
@@ -226,7 +233,7 @@
         mBatterySaverPolicy.updateConstantsLocked(null, "");
     }
 
-    private void testServiceDefaultValue(@ServiceType int type) {
+    private void testServiceDefaultValue_On(@ServiceType int type) {
         mBatterySaverPolicy.updateConstantsLocked("", "");
         final PowerSaveState batterySaverStateOn =
                 mBatterySaverPolicy.getBatterySaverPolicy(type, BATTERY_SAVER_ON);
@@ -237,7 +244,7 @@
         assertThat(batterySaverStateOff.batterySaverEnabled).isFalse();
     }
 
-    private void testServiceDefaultValue_unchanged(@ServiceType int type) {
+    private void testServiceDefaultValue_Off(@ServiceType int type) {
         mBatterySaverPolicy.updateConstantsLocked("", "");
         final PowerSaveState batterySaverStateOn =
                 mBatterySaverPolicy.getBatterySaverPolicy(type, BATTERY_SAVER_ON);
diff --git a/services/tests/servicestests/src/com/android/server/textservices/LocaleUtilsTest.java b/services/tests/servicestests/src/com/android/server/textservices/LocaleUtilsTest.java
index 3766d24..ef945e6 100644
--- a/services/tests/servicestests/src/com/android/server/textservices/LocaleUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/textservices/LocaleUtilsTest.java
@@ -19,11 +19,17 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 
+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.Locale;
 
+@SmallTest
+@RunWith(AndroidJUnit4.class)
 public class LocaleUtilsTest {
     private static final Locale LOCALE_EN = new Locale("en");
     private static final Locale LOCALE_EN_US = new Locale("en", "US");
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 869f8fa0..caaa0bb 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -43,6 +43,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 
+import android.app.usage.AppStandbyInfo;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStatsManagerInternal;
 import android.appwidget.AppWidgetManager;
@@ -92,6 +93,8 @@
     private static final int USER_ID = 0;
     private static final int USER_ID2 = 10;
 
+    private static final String PACKAGE_UNKNOWN = "com.example.unknown";
+
     private static final String ADMIN_PKG = "com.android.admin";
     private static final String ADMIN_PKG2 = "com.android.admin2";
     private static final String ADMIN_PKG3 = "com.android.admin3";
@@ -106,6 +109,9 @@
     // Short STABLE_CHARGING_THRESHOLD for testing purposes
     private static final long STABLE_CHARGING_THRESHOLD = 2000;
 
+    /** Mock variable used in {@link MyInjector#isPackageInstalled(String, int, int)} */
+    private static boolean isPackageInstalled = true;
+
     private MyInjector mInjector;
     private AppStandbyController mController;
 
@@ -183,6 +189,12 @@
         }
 
         @Override
+        boolean isPackageInstalled(String packageName, int flags, int userId) {
+            // Should always return true (default value) unless testing for an uninstalled app
+            return isPackageInstalled;
+        }
+
+        @Override
         int[] getRunningUserIds() {
             return new int[] {USER_ID};
         }
@@ -403,30 +415,30 @@
                         false));
     }
 
-    private void reportEvent(AppStandbyController controller, int eventType,
-            long elapsedTime) {
+    private void reportEvent(AppStandbyController controller, int eventType, long elapsedTime,
+            String packageName) {
         // Back to ACTIVE on event
         mInjector.mElapsedRealtime = elapsedTime;
         UsageEvents.Event ev = new UsageEvents.Event();
-        ev.mPackage = PACKAGE_1;
+        ev.mPackage = packageName;
         ev.mEventType = eventType;
         controller.reportEvent(ev, elapsedTime, USER_ID);
     }
 
-    private int getStandbyBucket(AppStandbyController controller) {
-        return controller.getAppStandbyBucket(PACKAGE_1, USER_ID, mInjector.mElapsedRealtime,
+    private int getStandbyBucket(AppStandbyController controller, String packageName) {
+        return controller.getAppStandbyBucket(packageName, USER_ID, mInjector.mElapsedRealtime,
                 true);
     }
 
     private void assertBucket(int bucket) {
-        assertEquals(bucket, getStandbyBucket(mController));
+        assertEquals(bucket, getStandbyBucket(mController, PACKAGE_1));
     }
 
     @Test
     public void testBuckets() throws Exception {
         assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
 
-        reportEvent(mController, USER_INTERACTION, 0);
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
 
         // ACTIVE bucket
         assertTimeout(mController, WORKING_SET_THRESHOLD - 1, STANDBY_BUCKET_ACTIVE);
@@ -443,7 +455,7 @@
         // RARE bucket
         assertTimeout(mController, RARE_THRESHOLD + 1, STANDBY_BUCKET_RARE);
 
-        reportEvent(mController, USER_INTERACTION, RARE_THRESHOLD + 1);
+        reportEvent(mController, USER_INTERACTION, RARE_THRESHOLD + 1, PACKAGE_1);
 
         assertTimeout(mController, RARE_THRESHOLD + 1, STANDBY_BUCKET_ACTIVE);
 
@@ -452,12 +464,48 @@
     }
 
     @Test
+    public void testSetAppStandbyBucket() throws Exception {
+        // For a known package, standby bucket should be set properly
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
+        mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
+                REASON_MAIN_TIMEOUT, HOUR_MS);
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
+
+        // For an unknown package, standby bucket should not be set, hence NEVER is returned
+        // Ensure the unknown package is not already in history by removing it
+        mController.clearAppIdleForPackage(PACKAGE_UNKNOWN, USER_ID);
+        isPackageInstalled = false; // Mock package is not installed
+        mController.setAppStandbyBucket(PACKAGE_UNKNOWN, USER_ID, STANDBY_BUCKET_ACTIVE,
+                REASON_MAIN_TIMEOUT, HOUR_MS);
+        isPackageInstalled = true; // Reset mocked variable for other tests
+        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_UNKNOWN));
+    }
+
+    @Test
+    public void testAppStandbyBucketOnInstallAndUninstall() throws Exception {
+        // On package install, standby bucket should be ACTIVE
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_UNKNOWN);
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_UNKNOWN));
+
+        // On uninstall, package should not exist in history and should return a NEVER bucket
+        mController.clearAppIdleForPackage(PACKAGE_UNKNOWN, USER_ID);
+        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_UNKNOWN));
+        // Ensure uninstalled app is not in history
+        List<AppStandbyInfo> buckets = mController.getAppStandbyBuckets(USER_ID);
+        for(AppStandbyInfo bucket : buckets) {
+            if (bucket.mPackageName.equals(PACKAGE_UNKNOWN)) {
+                fail("packageName found in app idle history after uninstall.");
+            }
+        }
+    }
+
+    @Test
     public void testScreenTimeAndBuckets() throws Exception {
         mInjector.setDisplayOn(false);
 
         assertTimeout(mController, 0, STANDBY_BUCKET_NEVER);
 
-        reportEvent(mController, USER_INTERACTION, 0);
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
 
         // ACTIVE bucket
         assertTimeout(mController, WORKING_SET_THRESHOLD - 1, STANDBY_BUCKET_ACTIVE);
@@ -468,7 +516,7 @@
         // RARE bucket, should fail because the screen wasn't ON.
         mInjector.mElapsedRealtime = RARE_THRESHOLD + 1;
         mController.checkIdleStates(USER_ID);
-        assertNotEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+        assertNotEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
 
         mInjector.setDisplayOn(true);
         assertTimeout(mController, RARE_THRESHOLD * 2 + 2, STANDBY_BUCKET_RARE);
@@ -477,7 +525,7 @@
     @Test
     public void testForcedIdle() throws Exception {
         mController.forceIdleState(PACKAGE_1, USER_ID, true);
-        assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
         assertTrue(mController.isAppIdleFiltered(PACKAGE_1, UID_1, USER_ID, 0));
 
         mController.forceIdleState(PACKAGE_1, USER_ID, false);
@@ -488,35 +536,35 @@
 
     @Test
     public void testNotificationEvent() throws Exception {
-        reportEvent(mController, USER_INTERACTION, 0);
-        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
         mInjector.mElapsedRealtime = 1;
-        reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
-        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+        reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime, PACKAGE_1);
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
 
         mController.forceIdleState(PACKAGE_1, USER_ID, true);
-        reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
-        assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
+        reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime, PACKAGE_1);
+        assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController, PACKAGE_1));
     }
 
     @Test
     public void testSlicePinnedEvent() throws Exception {
-        reportEvent(mController, USER_INTERACTION, 0);
-        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
         mInjector.mElapsedRealtime = 1;
-        reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime);
-        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+        reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime, PACKAGE_1);
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
 
         mController.forceIdleState(PACKAGE_1, USER_ID, true);
-        reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime);
-        assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
+        reportEvent(mController, SLICE_PINNED, mInjector.mElapsedRealtime, PACKAGE_1);
+        assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController, PACKAGE_1));
     }
 
     @Test
     public void testSlicePinnedPrivEvent() throws Exception {
         mController.forceIdleState(PACKAGE_1, USER_ID, true);
-        reportEvent(mController, SLICE_PINNED_PRIV, mInjector.mElapsedRealtime);
-        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+        reportEvent(mController, SLICE_PINNED_PRIV, mInjector.mElapsedRealtime, PACKAGE_1);
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
     }
 
     @Test
@@ -524,28 +572,28 @@
         // Set it to timeout or usage, so that prediction can override it
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RARE,
                 REASON_MAIN_TIMEOUT, HOUR_MS);
-        assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
 
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                 REASON_MAIN_PREDICTED, HOUR_MS);
-        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
 
         // Fast forward 12 hours
         mInjector.mElapsedRealtime += WORKING_SET_THRESHOLD;
         mController.checkIdleStates(USER_ID);
         // Should still be in predicted bucket, since prediction timeout is 1 day since prediction
-        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
         // Fast forward two more hours
         mInjector.mElapsedRealtime += 2 * HOUR_MS;
         mController.checkIdleStates(USER_ID);
         // Should have now applied prediction timeout
-        assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_WORKING_SET, getStandbyBucket(mController, PACKAGE_1));
 
         // Fast forward RARE bucket
         mInjector.mElapsedRealtime += RARE_THRESHOLD;
         mController.checkIdleStates(USER_ID);
         // Should continue to apply prediction timeout
-        assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_RARE, getStandbyBucket(mController, PACKAGE_1));
     }
 
     @Test
@@ -553,33 +601,33 @@
         // Can force to NEVER
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
                 REASON_MAIN_FORCED, 1 * HOUR_MS);
-        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_1));
 
         // Prediction can't override FORCED reason
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_FREQUENT,
                 REASON_MAIN_FORCED, 1 * HOUR_MS);
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
                 REASON_MAIN_PREDICTED, 1 * HOUR_MS);
-        assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_FREQUENT, getStandbyBucket(mController, PACKAGE_1));
 
         // Prediction can't override NEVER
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
                 REASON_MAIN_DEFAULT, 2 * HOUR_MS);
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                 REASON_MAIN_PREDICTED, 2 * HOUR_MS);
-        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_NEVER, getStandbyBucket(mController, PACKAGE_1));
 
         // Prediction can't set to NEVER
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_ACTIVE,
                 REASON_MAIN_USAGE, 2 * HOUR_MS);
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_NEVER,
                 REASON_MAIN_PREDICTED, 2 * HOUR_MS);
-        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController));
+        assertEquals(STANDBY_BUCKET_ACTIVE, getStandbyBucket(mController, PACKAGE_1));
     }
 
     @Test
     public void testTimeout() throws Exception {
-        reportEvent(mController, USER_INTERACTION, 0);
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         mInjector.mElapsedRealtime = 2000;
@@ -601,10 +649,10 @@
 
     @Test
     public void testCascadingTimeouts() throws Exception {
-        reportEvent(mController, USER_INTERACTION, 0);
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
-        reportEvent(mController, NOTIFICATION_SEEN, 1000);
+        reportEvent(mController, NOTIFICATION_SEEN, 1000, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_WORKING_SET,
@@ -622,14 +670,15 @@
 
     @Test
     public void testOverlappingTimeouts() throws Exception {
-        reportEvent(mController, USER_INTERACTION, 0);
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
-        reportEvent(mController, NOTIFICATION_SEEN, 1000);
+        reportEvent(mController, NOTIFICATION_SEEN, 1000, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         // Overlapping USER_INTERACTION before previous one times out
-        reportEvent(mController, USER_INTERACTION, mController.mStrongUsageTimeoutMillis - 1000);
+        reportEvent(mController, USER_INTERACTION, mController.mStrongUsageTimeoutMillis - 1000,
+                PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         // Still in ACTIVE after first USER_INTERACTION times out
@@ -654,14 +703,14 @@
     public void testSystemInteractionTimeout() throws Exception {
         setChargingState(mController, false);
 
-        reportEvent(mController, USER_INTERACTION, 0);
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
         // Fast forward to RARE
         mInjector.mElapsedRealtime = RARE_THRESHOLD + 100;
         mController.checkIdleStates(USER_ID);
         assertBucket(STANDBY_BUCKET_RARE);
 
         // Trigger a SYSTEM_INTERACTION and verify bucket
-        reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime);
+        reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         // Verify it's still in ACTIVE close to end of timeout
@@ -677,11 +726,11 @@
 
     @Test
     public void testPredictionNotOverridden() throws Exception {
-        reportEvent(mController, USER_INTERACTION, 0);
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         mInjector.mElapsedRealtime = WORKING_SET_THRESHOLD - 1000;
-        reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime);
+        reportEvent(mController, NOTIFICATION_SEEN, mInjector.mElapsedRealtime, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         // Falls back to WORKING_SET
@@ -703,7 +752,7 @@
 
     @Test
     public void testPredictionStrikesBack() throws Exception {
-        reportEvent(mController, USER_INTERACTION, 0);
+        reportEvent(mController, USER_INTERACTION, 0, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
 
         // Predict to FREQUENT
@@ -714,7 +763,7 @@
 
         // Add a short timeout event
         mInjector.mElapsedRealtime += 1000;
-        reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime);
+        reportEvent(mController, SYSTEM_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
         assertBucket(STANDBY_BUCKET_ACTIVE);
         mInjector.mElapsedRealtime += 1000;
         mController.checkIdleStates(USER_ID);
diff --git a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
index 5a787ec..473682d 100644
--- a/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
+++ b/services/tests/servicestests/src/com/android/server/usage/UsageStatsDatabaseTest.java
@@ -51,6 +51,10 @@
     private IntervalStats mIntervalStats = new IntervalStats();
     private long mEndTime = 0;
 
+    // Key under which the payload blob is stored
+    // same as UsageStatsBackupHelper.KEY_USAGE_STATS
+    static final String KEY_USAGE_STATS = "usage_stats";
+
     private static final UsageStatsDatabase.StatCombiner<IntervalStats> mIntervalStatsVerifier =
             new UsageStatsDatabase.StatCombiner<IntervalStats>() {
                 @Override
@@ -104,10 +108,11 @@
 
     private void populateIntervalStats() {
         final int numberOfEvents = 3000;
-        long time = 1;
+        final int timeProgression = 23;
+        long time = System.currentTimeMillis() - (numberOfEvents*timeProgression);
         mIntervalStats = new IntervalStats();
 
-        mIntervalStats.beginTime = 1;
+        mIntervalStats.beginTime = time;
         mIntervalStats.interactiveTracker.count = 2;
         mIntervalStats.interactiveTracker.duration = 111111;
         mIntervalStats.nonInteractiveTracker.count = 3;
@@ -158,7 +163,7 @@
             mIntervalStats.events.insert(event);
             mIntervalStats.update(event.mPackage, event.mTimeStamp, event.mEventType);
 
-            time += 23; // Arbitrary progression of time
+            time += timeProgression; // Arbitrary progression of time
         }
         mEndTime = time;
 
@@ -286,9 +291,19 @@
         }
         assertEquals(stats1.activeConfiguration, stats2.activeConfiguration);
 
-        assertEquals(stats1.events.size(), stats2.events.size());
-        for (int i = 0; i < stats1.events.size(); i++) {
-            compareUsageEvent(stats1.events.get(i), stats2.events.get(i), i);
+        if (stats1.events == null) {
+            // If stats1 events are null, stats2 should be null or empty
+            if (stats2.events != null) {
+                assertEquals(stats2.events.size(), 0);
+            }
+        } else if (stats2.events == null) {
+            // If stats2 events are null, stats1 should be null or empty
+            assertEquals(stats1.events.size(), 0);
+        } else {
+            assertEquals(stats1.events.size(), stats2.events.size());
+            for (int i = 0; i < stats1.events.size(); i++) {
+                compareUsageEvent(stats1.events.get(i), stats2.events.get(i), i);
+            }
         }
     }
 
@@ -340,6 +355,47 @@
     }
 
     /**
+     * Runs the Backup and Restore tests.
+     * Will write the generated IntervalStat to a database and create a backup in the specified
+     * version's format. The database will then be restored from the blob and the restored
+     * interval stats will be compared to the generated stats.
+     */
+    void runBackupRestoreTest(int version) throws IOException {
+        UsageStatsDatabase prevDB = new UsageStatsDatabase(mTestDir);
+        prevDB.init(1);
+        prevDB.putUsageStats(UsageStatsManager.INTERVAL_DAILY, mIntervalStats);
+        // Create a backup with a specific version
+        byte[] blob = prevDB.getBackupPayload(KEY_USAGE_STATS, version);
+
+        clearUsageStatsFiles();
+
+        UsageStatsDatabase newDB = new UsageStatsDatabase(mTestDir);
+        newDB.init(1);
+        // Attempt to restore the usage stats from the backup
+        newDB.applyRestoredPayload(KEY_USAGE_STATS, blob);
+        List<IntervalStats> stats = newDB.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, 0, mEndTime,
+                mIntervalStatsVerifier);
+
+
+        if (version > newDB.BACKUP_VERSION || version < 1) {
+            if (stats != null && stats.size() != 0) {
+                fail("UsageStatsDatabase should ne be able to restore from unknown data versions");
+            }
+            return;
+        }
+
+        assertEquals(1, stats.size());
+
+        // Clear non backed up data from expected IntervalStats
+        mIntervalStats.activeConfiguration = null;
+        mIntervalStats.configurations.clear();
+        if (mIntervalStats.events != null) mIntervalStats.events.clear();
+
+        // The written and read IntervalStats should match
+        compareIntervalStats(mIntervalStats, stats.get(0));
+    }
+
+    /**
      * Test the version upgrade from 3 to 4
      */
     @Test
@@ -349,4 +405,18 @@
         runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_MONTHLY);
         runVersionChangeTest(3, 4, UsageStatsManager.INTERVAL_YEARLY);
     }
+
+
+    /**
+     * Test the version upgrade from 3 to 4
+     */
+    @Test
+    public void testBackupRestore() throws IOException {
+        runBackupRestoreTest(1);
+        runBackupRestoreTest(4);
+
+        // test invalid backup versions as well
+        runBackupRestoreTest(0);
+        runBackupRestoreTest(99999);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 6d31dfb..7935ec1 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -16,6 +16,8 @@
 
 package com.android.server.wm;
 
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
@@ -33,10 +35,12 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyInt;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 
+import android.graphics.Point;
+import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.view.Surface;
 import android.view.WindowManager;
@@ -255,4 +259,30 @@
         closingWindow.removeIfPossible();
         assertTrue(closingWindow.mRemoved);
     }
+
+    @Test
+    public void testTransitionAnimationPositionAndBounds() {
+        final Rect stackBounds = new Rect(
+                0/* left */, 0 /* top */, 1000 /* right */, 1000 /* bottom */);
+        final Rect taskBounds = new Rect(
+                100/* left */, 200 /* top */, 600 /* right */, 600 /* bottom */);
+        mStack.setBounds(stackBounds);
+        mTask.setBounds(taskBounds);
+
+        mTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        assertTransitionAnimationPositionAndBounds(taskBounds.left, taskBounds.top, stackBounds);
+
+        mTask.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
+        assertTransitionAnimationPositionAndBounds(stackBounds.left, stackBounds.top, stackBounds);
+    }
+
+    private void assertTransitionAnimationPositionAndBounds(int expectedX, int expectedY,
+            Rect expectedBounds) {
+        final Point outPosition = new Point();
+        final Rect outBounds = new Rect();
+        mToken.getAnimationBounds(outPosition, outBounds);
+        assertEquals(expectedX, outPosition.x);
+        assertEquals(expectedY, outPosition.y);
+        assertEquals(expectedBounds, outBounds);
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index 12be0b3..e6e08bb 100644
--- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -90,7 +90,7 @@
         private AppTransitionListener mListener;
 
         MockAppTransition(Context context) {
-            super(context, null);
+            super(context, sWm);
         }
 
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index b330304..cb8ca7e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -24,6 +24,8 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 import static android.view.Display.DEFAULT_DISPLAY;
+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.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
@@ -32,10 +34,12 @@
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
 
 import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 
 import static org.hamcrest.Matchers.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doNothing;
@@ -285,35 +289,28 @@
         final WindowTestUtils.TestAppWindowToken token =
                 WindowTestUtils.createTestAppWindowToken(dc0);
         task0.addChild(token, 0);
-        dc0.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
-        sWm.registerPointerEventListener(dc0.mTapDetector);
+        dc0.configureDisplayPolicy();
+        assertNotNull(dc0.mTapDetector);
+
         final TaskStack stack1 = createTaskStackOnDisplay(dc1);
         final Task task1 = createTaskInStack(stack1, 0 /* userId */);
         final WindowTestUtils.TestAppWindowToken token1 =
                 WindowTestUtils.createTestAppWindowToken(dc0);
         task1.addChild(token1, 0);
-        dc1.mTapDetector = new TaskTapPointerEventListener(sWm, dc0);
-        sWm.registerPointerEventListener(dc1.mTapDetector);
+        dc1.configureDisplayPolicy();
+        assertNotNull(dc1.mTapDetector);
 
-        // tap on primary display (by sending ACTION_DOWN followed by ACTION_UP)
-        DisplayMetrics dm0 = dc0.getDisplayMetrics();
-        dc0.mTapDetector.onPointerEvent(
-                createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, true));
-        dc0.mTapDetector.onPointerEvent(
-                createTapEvent(dm0.widthPixels / 2, dm0.heightPixels / 2, false));
-
+        // tap on primary display.
+        tapOnDisplay(dc0);
         // Check focus is on primary display.
-        assertEquals(sWm.mCurrentFocus, dc0.findFocusedWindow());
+        assertEquals(sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
+                dc0.findFocusedWindow());
 
-        // Tap on secondary display
-        DisplayMetrics dm1 = dc1.getDisplayMetrics();
-        dc1.mTapDetector.onPointerEvent(
-                createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, true));
-        dc1.mTapDetector.onPointerEvent(
-                createTapEvent(dm1.widthPixels / 2, dm1.heightPixels / 2, false));
-
+        // Tap on secondary display.
+        tapOnDisplay(dc1);
         // Check focus is on secondary.
-        assertEquals(sWm.mCurrentFocus, dc1.findFocusedWindow());
+        assertEquals(sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
+                dc1.findFocusedWindow());
     }
 
     @Test
@@ -321,34 +318,29 @@
         // Create a focusable window and check that focus is calculated correctly
         final WindowState window1 =
                 createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
-        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+        updateFocusedWindow();
+        assertTrue(window1.isFocused());
+        assertEquals(window1, sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
 
         // Check that a new display doesn't affect focus
         final DisplayContent dc = createNewDisplay();
-        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
+        updateFocusedWindow();
+        assertTrue(window1.isFocused());
+        assertEquals(window1, sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
 
         // Add a window to the second display, and it should be focused
         final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
-        assertEquals(window2, sWm.mRoot.computeFocusedWindow());
+        updateFocusedWindow();
+        assertTrue(window1.isFocused());
+        assertTrue(window2.isFocused());
+        assertEquals(window2, sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
 
         // Move the first window to the to including parents, and make sure focus is updated
         window1.getParent().positionChildAt(POSITION_TOP, window1, true);
-        assertEquals(window1, sWm.mRoot.computeFocusedWindow());
-    }
-
-    @Test
-    public void testKeyguard_preventsSecondaryDisplayFocus() throws Exception {
-        final WindowState keyguard = createWindow(null, TYPE_STATUS_BAR,
-                sWm.getDefaultDisplayContentLocked(), "keyguard");
-        assertEquals(keyguard, sWm.mRoot.computeFocusedWindow());
-
-        // Add a window to a second display, and it should be focused
-        final DisplayContent dc = createNewDisplay();
-        final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, dc, "win");
-        assertEquals(win, sWm.mRoot.computeFocusedWindow());
-
-        mWmRule.getWindowManagerPolicy().keyguardShowingAndNotOccluded = true;
-        assertEquals(keyguard, sWm.mRoot.computeFocusedWindow());
+        updateFocusedWindow();
+        assertTrue(window1.isFocused());
+        assertTrue(window2.isFocused());
+        assertEquals(window1, sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
     }
 
     /**
@@ -454,7 +446,7 @@
             dc.mInitialDisplayHeight = 400;
             Rect r = new Rect(80, 0, 120, 10);
             final DisplayCutout cutout = new WmDisplayCutout(
-                    fromBoundingRect(r.left, r.top, r.right, r.bottom), null)
+                    fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_TOP), null)
                     .computeSafeInsets(200, 400).getDisplayCutout();
 
             dc.mInitialDisplayCutout = cutout;
@@ -484,7 +476,7 @@
 
             final Rect r1 = new Rect(left, top, right, bottom);
             final DisplayCutout cutout = new WmDisplayCutout(
-                    fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom), null)
+                    fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP), null)
                     .computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
 
             dc.mInitialDisplayCutout = cutout;
@@ -501,7 +493,7 @@
             // |             |      -------------
             final Rect r = new Rect(top, left, bottom, right);
             assertEquals(new WmDisplayCutout(
-                    fromBoundingRect(r.left, r.top, r.right, r.bottom), null)
+                    fromBoundingRect(r.left, r.top, r.right, r.bottom, BOUNDS_POSITION_LEFT), null)
                     .computeSafeInsets(displayHeight, displayWidth)
                     .getDisplayCutout(), dc.getDisplayInfo().displayCutout);
         }
@@ -590,6 +582,12 @@
         assertEquals(displayContent.mBaseDisplayDensity, expectedBaseDensity);
     }
 
+    private void updateFocusedWindow() {
+        synchronized (sWm.mWindowMap) {
+            sWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false);
+        }
+    }
+
     /**
      * Create DisplayContent that does not update display base/initial values from device to keep
      * the values set by test.
@@ -620,17 +618,32 @@
         return result;
     }
 
-    private MotionEvent createTapEvent(float x, float y, boolean isDownEvent) {
+    private void tapOnDisplay(final DisplayContent dc) {
+        final DisplayMetrics dm = dc.getDisplayMetrics();
+        final float x = dm.widthPixels / 2;
+        final float y = dm.heightPixels / 2;
         final long downTime = SystemClock.uptimeMillis();
         final long eventTime = SystemClock.uptimeMillis() + 100;
-        final int metaState = 0;
-
-        return MotionEvent.obtain(
+        // sending ACTION_DOWN
+        final MotionEvent downEvent = MotionEvent.obtain(
                 downTime,
-                eventTime,
-                isDownEvent ? MotionEvent.ACTION_DOWN : MotionEvent.ACTION_UP,
+                downTime,
+                MotionEvent.ACTION_DOWN,
                 x,
                 y,
-                metaState);
+                0 /*metaState*/);
+        downEvent.setDisplayId(dc.getDisplayId());
+        dc.mTapDetector.onPointerEvent(downEvent);
+
+        // sending ACTION_UP
+        final MotionEvent upEvent = MotionEvent.obtain(
+                downTime,
+                eventTime,
+                MotionEvent.ACTION_UP,
+                x,
+                y,
+                0 /*metaState*/);
+        upEvent.setDisplayId(dc.getDisplayId());
+        dc.mTapDetector.onPointerEvent(upEvent);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
index 07eafa5..a028d5ee 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
@@ -18,23 +18,34 @@
 package com.android.server.wm;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.app.WindowConfiguration;
 import android.platform.test.annotations.Presubmit;
 import android.view.Display;
 import android.view.DisplayInfo;
+import android.view.Surface;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.policy.WindowManagerPolicy;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.io.File;
 
+/**
+ * Tests for the {@link DisplaySettings} class.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.wm.DisplaySettingsTests
+ */
 @SmallTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
@@ -155,6 +166,71 @@
         assertOverscan(mPrimaryDisplay, 1 /* left */, 2 /* top */, 3 /* right */, 4 /* bottom */);
     }
 
+    @Test
+    public void testDefaultToFreeUserRotation() {
+        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+        final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
+        assertEquals(WindowManagerPolicy.USER_ROTATION_FREE, rotation.getUserRotationMode());
+        assertFalse(rotation.isRotationFrozen());
+    }
+
+    @Test
+    public void testDefaultTo0DegRotation() {
+        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+        assertEquals(Surface.ROTATION_0, mSecondaryDisplay.getDisplayRotation().getUserRotation());
+    }
+
+    @Test
+    public void testPersistUserRotationModeInSameInstance() {
+        mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
+                Surface.ROTATION_90);
+
+        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+        final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
+        assertEquals(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation.getUserRotationMode());
+        assertTrue(rotation.isRotationFrozen());
+    }
+
+    @Test
+    public void testPersistUserRotationInSameInstance() {
+        mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
+                Surface.ROTATION_90);
+
+        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+        assertEquals(Surface.ROTATION_90, mSecondaryDisplay.getDisplayRotation().getUserRotation());
+    }
+
+    @Test
+    public void testPersistUserRotationModeAcrossInstances() {
+        mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
+                Surface.ROTATION_270);
+        mTarget.writeSettingsLocked();
+
+        DisplaySettings target = new DisplaySettings(sWm, mTestFolder);
+        target.readSettingsLocked();
+
+        target.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+        final DisplayRotation rotation = mSecondaryDisplay.getDisplayRotation();
+        assertEquals(WindowManagerPolicy.USER_ROTATION_LOCKED, rotation.getUserRotationMode());
+        assertTrue(rotation.isRotationFrozen());
+    }
+
+    @Test
+    public void testPersistUserRotationAcrossInstances() {
+        mTarget.setUserRotation(mSecondaryDisplay, WindowManagerPolicy.USER_ROTATION_LOCKED,
+                Surface.ROTATION_270);
+
+        mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
+
+        assertEquals(Surface.ROTATION_270,
+                mSecondaryDisplay.getDisplayRotation().getUserRotation());
+    }
+
     private static void assertOverscan(DisplayContent display, int left, int top, int right,
             int bottom) {
         final DisplayInfo info = display.getDisplayInfo();
diff --git a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
index 7125246..3c8b2a0 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
@@ -40,27 +40,25 @@
 import android.view.SurfaceSession;
 import android.view.View;
 
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.internal.annotations.GuardedBy;
 import com.android.server.LocalServices;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import androidx.test.filters.SmallTest;
+
 /**
  * Tests for the {@link DragDropController} class.
  *
- * atest FrameworksServicesTests:com.android.server.wm.DragDropControllerTests
+ * Build/Install/Run:
+ *  atest FrameworksServicesTests:com.android.server.wm.DragDropControllerTests
  */
 @SmallTest
-@RunWith(AndroidJUnit4.class)
 @Presubmit
 public class DragDropControllerTests extends WindowTestsBase {
     private static final int TIMEOUT_MS = 3000;
@@ -109,6 +107,7 @@
         return window;
     }
 
+    @Override
     @Before
     public void setUp() throws Exception {
         final UserManagerInternal userManager = mock(UserManagerInternal.class);
@@ -127,6 +126,7 @@
         }
     }
 
+    @Override
     @After
     public void tearDown() throws Exception {
         LocalServices.removeServiceForTest(UserManagerInternal.class);
@@ -139,25 +139,25 @@
                 mTarget.cancelDragAndDrop(mToken);
             }
             latch = new CountDownLatch(1);
-            mTarget.setOnClosedCallbackLocked(() -> {
-                latch.countDown();
-            });
+            mTarget.setOnClosedCallbackLocked(latch::countDown);
         }
         assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+        super.tearDown();
     }
 
     @Test
-    public void testDragFlow() throws Exception {
+    public void testDragFlow() {
         dragFlow(0, ClipData.newPlainText("label", "Test"), 0, 0);
     }
 
     @Test
-    public void testPerformDrag_NullDataWithGrantUri() throws Exception {
+    public void testPerformDrag_NullDataWithGrantUri() {
         dragFlow(View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ, null, 0, 0);
     }
 
     @Test
-    public void testPerformDrag_NullDataToOtherUser() throws Exception {
+    public void testPerformDrag_NullDataToOtherUser() {
         final WindowState otherUsersWindow =
                 createDropTargetWindow("Other user's window", 1 * UserHandle.PER_USER_RANGE);
         doReturn(otherUsersWindow).when(mDisplayContent).getTouchableWinAtPointLocked(10, 10);
diff --git a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
index 60025f0..ae40f7e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ScreenDecorWindowTests.java
@@ -334,7 +334,7 @@
         final Activity activity = mInstrumentation.startActivitySync(intent, options.toBundle());
         waitForIdle();
 
-        assertEquals(displayId, activity.getDisplay().getDisplayId());
+        assertEquals(displayId, activity.getDisplayId());
         return activity;
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
index ced0847..f8e7403 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -30,6 +30,7 @@
 import android.platform.test.annotations.Presubmit;
 import android.view.InputChannel;
 
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -43,6 +44,7 @@
  * atest com.android.server.wm.TaskPositioningControllerTests
  */
 @SmallTest
+@FlakyTest(bugId = 117924387)
 @RunWith(AndroidJUnit4.class)
 @Presubmit
 public class TaskPositioningControllerTests extends WindowTestsBase {
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index 6f4f173..33b137e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -29,14 +29,14 @@
 import android.graphics.Rect;
 import android.os.UserManager;
 
-import androidx.test.InstrumentationRegistry;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.BeforeClass;
 
 import java.io.File;
 
+import androidx.test.InstrumentationRegistry;
+
 /**
  * Base class for tests that use a {@link TaskSnapshotPersister}.
  */
@@ -54,9 +54,11 @@
         sFilesDir = InstrumentationRegistry.getContext().getFilesDir();
     }
 
+    @Override
     @Before
     public void setUp() throws Exception {
         super.setUp();
+
         final UserManager um = UserManager.get(InstrumentationRegistry.getContext());
         mTestUserId = um.getUserHandle();
         mPersister = new TaskSnapshotPersister(userId -> sFilesDir);
@@ -64,9 +66,12 @@
         mPersister.start();
     }
 
+    @Override
     @After
     public void tearDown() throws Exception {
         cleanDirectory();
+
+        super.tearDown();
     }
 
     private void cleanDirectory() {
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
index ea44279..0e9a63c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -19,36 +19,37 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
+
+import androidx.test.filters.SmallTest;
 
 /**
  * Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}.
  *
  * Build/Install/Run:
- *  bit FrameworksServicesTests:com.android.server.wm.TaskStackContainersTests
+ *  atest FrameworksServicesTests:com.android.server.wm.TaskStackContainersTests
  */
 @SmallTest
 @Presubmit
-@RunWith(AndroidJUnit4.class)
 public class TaskStackContainersTests extends WindowTestsBase {
 
     private TaskStack mPinnedStack;
 
+    @Override
     @Before
     public void setUp() throws Exception {
         super.setUp();
+
         mPinnedStack = createStackControllerOnStackOnDisplay(
                 WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
         // Stack should contain visible app window to be considered visible.
@@ -60,13 +61,16 @@
         assertTrue(mPinnedStack.isVisible());
     }
 
+    @Override
     @After
     public void tearDown() throws Exception {
         mPinnedStack.removeImmediately();
+
+        super.tearDown();
     }
 
     @Test
-    public void testStackPositionChildAt() throws Exception {
+    public void testStackPositionChildAt() {
         // Test that always-on-top stack can't be moved to position other than top.
         final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
         final TaskStack stack2 = createTaskStackOnDisplay(mDisplayContent);
@@ -76,8 +80,8 @@
         final int stack1Pos = taskStackContainer.mChildren.indexOf(stack1);
         final int stack2Pos = taskStackContainer.mChildren.indexOf(stack2);
         final int pinnedStackPos = taskStackContainer.mChildren.indexOf(mPinnedStack);
-        assertGreaterThan(pinnedStackPos, stack2Pos);
-        assertGreaterThan(stack2Pos, stack1Pos);
+        assertThat(pinnedStackPos).isGreaterThan(stack2Pos);
+        assertThat(stack2Pos).isGreaterThan(stack1Pos);
 
         taskStackContainer.positionChildAt(WindowContainer.POSITION_BOTTOM, mPinnedStack, false);
         assertEquals(taskStackContainer.mChildren.get(stack1Pos), stack1);
@@ -91,7 +95,7 @@
     }
 
     @Test
-    public void testStackPositionBelowPinnedStack() throws Exception {
+    public void testStackPositionBelowPinnedStack() {
         // Test that no stack can be above pinned stack.
         final TaskStack stack1 = createTaskStackOnDisplay(mDisplayContent);
 
@@ -99,7 +103,7 @@
 
         final int stackPos = taskStackContainer.mChildren.indexOf(stack1);
         final int pinnedStackPos = taskStackContainer.mChildren.indexOf(mPinnedStack);
-        assertGreaterThan(pinnedStackPos, stackPos);
+        assertThat(pinnedStackPos).isGreaterThan(stackPos);
 
         taskStackContainer.positionChildAt(WindowContainer.POSITION_TOP, stack1, false);
         assertEquals(taskStackContainer.mChildren.get(stackPos), stack1);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 474e5b7..5159551 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -432,17 +432,6 @@
     }
 
     @Override
-    public int getUserRotationMode() {
-        return 0;
-    }
-
-    @Override
-    public void setUserRotationMode(int mode,
-            int rotation) {
-
-    }
-
-    @Override
     public int adjustSystemUiVisibilityLw(int visibility) {
         return 0;
     }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 0886729..7cd1314 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -16,12 +16,12 @@
 
 package com.android.server.wm;
 
+import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
 import static android.view.DisplayCutout.fromBoundingRect;
 import static android.view.WindowManager.LayoutParams.FILL_PARENT;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 
 import android.app.ActivityManager.TaskDescription;
 import android.content.res.Configuration;
@@ -474,7 +474,8 @@
         final Rect pf = new Rect(0, 0, 1000, 2000);
         // Create a display cutout of size 50x50, aligned top-center
         final WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(500, 0, 550, 50), pf.width(), pf.height());
+                fromBoundingRect(500, 0, 550, 50, BOUNDS_POSITION_TOP),
+                pf.width(), pf.height());
 
         final WindowFrames windowFrames = w.getWindowFrames();
         windowFrames.setFrames(pf, pf, pf, pf, pf, pf, pf, pf);
@@ -499,7 +500,8 @@
         final Rect pf = new Rect(0, -500, 1000, 1500);
         // Create a display cutout of size 50x50, aligned top-center
         final WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(500, 0, 550, 50), pf.width(), pf.height());
+                fromBoundingRect(500, 0, 550, 50, BOUNDS_POSITION_TOP),
+                pf.width(), pf.height());
 
         final WindowFrames windowFrames = w.getWindowFrames();
         windowFrames.setFrames(pf, pf, pf, pf, pf, pf, pf, pf);
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
index 54fd7db..389eba5 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
@@ -34,8 +34,8 @@
 import android.os.PowerManagerInternal;
 import android.os.PowerSaveState;
 import android.view.InputChannel;
-
-import androidx.test.InstrumentationRegistry;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.Transaction;
 
 import com.android.server.LocalServices;
 import com.android.server.input.InputManagerService;
@@ -46,6 +46,12 @@
 import org.junit.runners.model.Statement;
 import org.mockito.invocation.InvocationOnMock;
 
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.test.InstrumentationRegistry;
+
 /**
  * A test rule that sets up a fresh WindowManagerService instance before each test and makes sure
  * to properly tear it down after.
@@ -61,6 +67,12 @@
 
     private WindowManagerService mService;
     private TestWindowManagerPolicy mPolicy;
+    // Record all {@link SurfaceControl.Transaction} created while testing and releases native
+    // resources when test finishes.
+    private final List<WeakReference<Transaction>> mSurfaceTransactions = new ArrayList<>();
+    // Record all {@link SurfaceControl} created while testing and releases native resources when
+    // test finishes.
+    private final List<WeakReference<SurfaceControl>> mSurfaceControls = new ArrayList<>();
 
     @Override
     public Statement apply(Statement base, Description description) {
@@ -108,12 +120,25 @@
                 // InputChannel is final and can't be mocked.
                 InputChannel[] input = InputChannel.openInputChannelPair(TAG_WM);
                 if (input != null && input.length > 1) {
-                    doReturn(input[1]).when(ims).monitorInput(anyString());
+                    doReturn(input[1]).when(ims).monitorInput(anyString(), anyInt());
                 }
 
                 mService = WindowManagerService.main(context, ims, false,
                         false, mPolicy = new TestWindowManagerPolicy(
                                 WindowManagerServiceRule.this::getWindowManagerService));
+                mService.mTransactionFactory = () -> {
+                    final SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+                    mSurfaceTransactions.add(new WeakReference<>(transaction));
+                    return transaction;
+                };
+                mService.mSurfaceBuilderFactory = session -> new SurfaceControl.Builder(session) {
+                    @Override
+                    public SurfaceControl build() {
+                        final SurfaceControl control = super.build();
+                        mSurfaceControls.add(new WeakReference<>(control));
+                        return control;
+                    }
+                };
 
                 mService.onInitReady();
 
@@ -135,6 +160,8 @@
 
             private void tearDown() {
                 waitUntilWindowManagerHandlersIdle();
+                destroyAllSurfaceTransactions();
+                destroyAllSurfaceControls();
                 removeServices();
                 mService = null;
                 mPolicy = null;
@@ -158,4 +185,24 @@
             SurfaceAnimationThread.getHandler().runWithScissors(() -> { }, 0);
         }
     }
+
+    private void destroyAllSurfaceTransactions() {
+        for (final WeakReference<Transaction> reference : mSurfaceTransactions) {
+            final Transaction transaction = reference.get();
+            if (transaction != null) {
+                reference.clear();
+                transaction.close();
+            }
+        }
+    }
+
+    private void destroyAllSurfaceControls() {
+        for (final WeakReference<SurfaceControl> reference : mSurfaceControls) {
+            final SurfaceControl control = reference.get();
+            if (control != null) {
+                reference.clear();
+                control.destroy();
+            }
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index b7cc9ce..3637baf 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -49,6 +49,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 
+import android.graphics.Insets;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
@@ -404,8 +405,12 @@
         WindowFrames wf = app.getWindowFrames();
         wf.mParentFrame.set(7, 10, 185, 380);
         wf.mDisplayFrame.set(wf.mParentFrame);
-        final DisplayCutout cutout = new DisplayCutout(new Rect(0, 15, 0, 22),
-                Arrays.asList(new Rect(95, 0, 105, 15), new Rect(95, 378, 105, 400)));
+        final DisplayCutout cutout = new DisplayCutout(
+                Insets.of(0, 15, 0, 22) /* safeInset */,
+                null /* boundLeft */,
+                new Rect(95, 0, 105, 15),
+                null /* boundRight */,
+                new Rect(95, 378, 105, 400));
         wf.setDisplayCutout(new WmDisplayCutout(cutout, new Size(200, 400)));
 
         app.computeFrameLw();
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 70e4ce4..cf67d78 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -48,18 +48,17 @@
 import android.view.IWindow;
 import android.view.WindowManager;
 
-import androidx.test.InstrumentationRegistry;
-
 import com.android.server.AttributeCache;
 
 import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 
 import java.util.HashSet;
 import java.util.LinkedList;
 
+import androidx.test.InstrumentationRegistry;
+
 /**
  * Common base class for window manager unit test classes.
  *
@@ -194,14 +193,6 @@
         }
     }
 
-    /**
-     * @return A SurfaceBuilderFactory to inject in to the WindowManagerService during
-     *         set-up (or null).
-     */
-    SurfaceBuilderFactory getSurfaceBuilderFactory() {
-        return null;
-    }
-
     private WindowState createCommonWindow(WindowState parent, int type, String name) {
         synchronized (sWm.mWindowMap) {
             final WindowState win = createWindow(parent, type, name);
@@ -212,16 +203,6 @@
         }
     }
 
-    /** Asserts that the first entry is greater than the second entry. */
-    void assertGreaterThan(int first, int second) throws Exception {
-        Assert.assertTrue("Excepted " + first + " to be greater than " + second, first > second);
-    }
-
-    /** Asserts that the first entry is greater than the second entry. */
-    void assertLessThan(int first, int second) throws Exception {
-        Assert.assertTrue("Excepted " + first + " to be less than " + second, first < second);
-    }
-
     /**
      * Waits until the main handler for WM has processed all messages.
      */
diff --git a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
index 8f9fb1b..3a8c4ae 100644
--- a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
@@ -32,36 +32,35 @@
 import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL;
 import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import android.platform.test.annotations.Presubmit;
 import android.view.SurfaceControl;
 import android.view.SurfaceSession;
 
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
 import org.junit.After;
 import org.junit.Test;
-import org.junit.runner.RunWith;
 
 import java.util.HashMap;
 import java.util.LinkedList;
 
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.SmallTest;
+
 /**
  * Tests for the {@link WindowLayersController} class.
  *
  * Build/Install/Run:
- *  bit FrameworksServicesTests:com.android.server.wm.ZOrderingTests
+ *  atest FrameworksServicesTests:com.android.server.wm.ZOrderingTests
  */
 @SmallTest
 @FlakyTest(bugId = 74078662)
 @Presubmit
-@RunWith(AndroidJUnit4.class)
 public class ZOrderingTests extends WindowTestsBase {
 
     private class LayerRecordingTransaction extends SurfaceControl.Transaction {
-        HashMap<SurfaceControl, Integer> mLayersForControl = new HashMap();
-        HashMap<SurfaceControl, SurfaceControl> mRelativeLayersForControl = new HashMap();
+        HashMap<SurfaceControl, Integer> mLayersForControl = new HashMap<>();
+        HashMap<SurfaceControl, SurfaceControl> mRelativeLayersForControl = new HashMap<>();
 
         @Override
         public SurfaceControl.Transaction setLayer(SurfaceControl sc, int layer) {
@@ -86,11 +85,11 @@
         private SurfaceControl getRelativeLayer(SurfaceControl sc) {
             return mRelativeLayersForControl.get(sc);
         }
-    };
+    }
 
     // We have WM use our Hierarchy recording subclass of SurfaceControl.Builder
     // such that we can keep track of the parents of Surfaces as they are constructed.
-    private HashMap<SurfaceControl, SurfaceControl> mParentFor = new HashMap();
+    private HashMap<SurfaceControl, SurfaceControl> mParentFor = new HashMap<>();
 
     private class HierarchyRecorder extends SurfaceControl.Builder {
         SurfaceControl mPendingParent;
@@ -99,23 +98,26 @@
             super(s);
         }
 
+        @Override
         public SurfaceControl.Builder setParent(SurfaceControl sc) {
             mPendingParent = sc;
             return super.setParent(sc);
         }
+
+        @Override
         public SurfaceControl build() {
             SurfaceControl sc = super.build();
             mParentFor.put(sc, mPendingParent);
             mPendingParent = null;
             return sc;
         }
-    };
+    }
 
-    class HierarchyRecordingBuilderFactory implements SurfaceBuilderFactory {
+    private class HierarchyRecordingBuilderFactory implements SurfaceBuilderFactory {
         public SurfaceControl.Builder make(SurfaceSession s) {
             return new HierarchyRecorder(s);
         }
-    };
+    }
 
     private LayerRecordingTransaction mTransaction;
 
@@ -132,11 +134,12 @@
     @After
     public void after() {
         mTransaction.close();
+        mParentFor.keySet().forEach(SurfaceControl::destroy);
         mParentFor.clear();
     }
 
     LinkedList<SurfaceControl> getAncestors(LayerRecordingTransaction t, SurfaceControl sc) {
-        LinkedList<SurfaceControl> p = new LinkedList();
+        LinkedList<SurfaceControl> p = new LinkedList<>();
         SurfaceControl current = sc;
         do {
             p.addLast(current);
@@ -153,7 +156,7 @@
 
 
     void assertZOrderGreaterThan(LayerRecordingTransaction t, SurfaceControl left,
-            SurfaceControl right) throws Exception {
+            SurfaceControl right) {
         final LinkedList<SurfaceControl> leftParentChain = getAncestors(t, left);
         final LinkedList<SurfaceControl> rightParentChain = getAncestors(t, right);
 
@@ -168,16 +171,15 @@
         }
 
         if (rightTop == null) { // right is the parent of left.
-            assertGreaterThan(t.getLayer(leftTop), 0);
+            assertThat(t.getLayer(leftTop)).isGreaterThan(0);
         } else if (leftTop == null) { // left is the parent of right.
-            assertGreaterThan(0, t.getLayer(rightTop));
+            assertThat(t.getLayer(rightTop)).isLessThan(0);
         } else {
-            assertGreaterThan(t.getLayer(leftTop),
-                    t.getLayer(rightTop));
+            assertThat(t.getLayer(leftTop)).isGreaterThan(t.getLayer(rightTop));
         }
     }
 
-    void assertWindowHigher(WindowState left, WindowState right) throws Exception {
+    void assertWindowHigher(WindowState left, WindowState right) {
         assertZOrderGreaterThan(mTransaction, left.getSurfaceControl(), right.getSurfaceControl());
     }
 
@@ -186,7 +188,7 @@
     }
 
     @Test
-    public void testAssignWindowLayers_ForImeWithNoTarget() throws Exception {
+    public void testAssignWindowLayers_ForImeWithNoTarget() {
         sWm.mInputMethodTarget = null;
         mDisplayContent.assignChildLayers(mTransaction);
 
@@ -203,7 +205,7 @@
     }
 
     @Test
-    public void testAssignWindowLayers_ForImeWithAppTarget() throws Exception {
+    public void testAssignWindowLayers_ForImeWithAppTarget() {
         final WindowState imeAppTarget = createWindow("imeAppTarget");
         sWm.mInputMethodTarget = imeAppTarget;
 
@@ -222,7 +224,7 @@
     }
 
     @Test
-    public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() throws Exception {
+    public void testAssignWindowLayers_ForImeWithAppTargetWithChildWindows() {
         final WindowState imeAppTarget = createWindow("imeAppTarget");
         final WindowState imeAppTargetChildAboveWindow = createWindow(imeAppTarget,
                 TYPE_APPLICATION_ATTACHED_DIALOG, imeAppTarget.mToken,
@@ -248,7 +250,7 @@
     }
 
     @Test
-    public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() throws Exception {
+    public void testAssignWindowLayers_ForImeWithAppTargetAndAppAbove() {
         final WindowState appBelowImeTarget = createWindow("appBelowImeTarget");
         final WindowState imeAppTarget = createWindow("imeAppTarget");
         final WindowState appAboveImeTarget = createWindow("appAboveImeTarget");
@@ -271,7 +273,7 @@
     }
 
     @Test
-    public void testAssignWindowLayers_ForImeNonAppImeTarget() throws Exception {
+    public void testAssignWindowLayers_ForImeNonAppImeTarget() {
         final WindowState imeSystemOverlayTarget = createWindow(null, TYPE_SYSTEM_OVERLAY,
                 mDisplayContent, "imeSystemOverlayTarget",
                 true /* ownerCanAddInternalSystemWindow */);
@@ -298,7 +300,7 @@
     }
 
     @Test
-    public void testAssignWindowLayers_ForStatusBarImeTarget() throws Exception {
+    public void testAssignWindowLayers_ForStatusBarImeTarget() {
         sWm.mInputMethodTarget = mStatusBarWindow;
         mDisplayContent.assignChildLayers(mTransaction);
 
@@ -312,7 +314,7 @@
     }
 
     @Test
-    public void testStackLayers() throws Exception {
+    public void testStackLayers() {
         final WindowState anyWindow1 = createWindow("anyWindow");
         final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
                 ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION, mDisplayContent,
@@ -342,7 +344,7 @@
     }
 
     @Test
-    public void testAssignWindowLayers_ForSysUiPanels() throws Exception {
+    public void testAssignWindowLayers_ForSysUiPanels() {
         final WindowState navBarPanel =
                 createWindow(null, TYPE_NAVIGATION_BAR_PANEL, mDisplayContent, "NavBarPanel");
         final WindowState statusBarPanel =
@@ -359,7 +361,7 @@
     }
 
     @Test
-    public void testAssignWindowLayers_ForNegativelyZOrderedSubtype() throws Exception {
+    public void testAssignWindowLayers_ForNegativelyZOrderedSubtype() {
         // TODO(b/70040778): We should aim to eliminate the last user of TYPE_APPLICATION_MEDIA
         // then we can drop all negative layering on the windowing side.
 
@@ -376,7 +378,7 @@
     }
 
     @Test
-    public void testDockedDividerPosition() throws Exception {
+    public void testDockedDividerPosition() {
         final WindowState pinnedStackWindow = createWindowOnStack(null, WINDOWING_MODE_PINNED,
                 ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION, mDisplayContent,
                 "pinnedStackWindow");
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/DisplayRotationUtilTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/DisplayRotationUtilTest.java
new file mode 100644
index 0000000..ba8869b
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/DisplayRotationUtilTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.wm.utils;
+
+import static android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM;
+import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
+import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT;
+import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
+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 com.android.server.wm.utils.DisplayRotationUtil.getBoundIndexFromRotation;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import android.graphics.Rect;
+import android.platform.test.annotations.Presubmit;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+
+
+/**
+ * Tests for {@link DisplayRotationUtil}
+ *
+ * Run with: atest DisplayRotationUtilTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class DisplayRotationUtilTest {
+    private static Rect ZERO_RECT = new Rect();
+
+    @Test
+    public void testGetBoundIndexFromRotation_rot0() {
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_LEFT, ROTATION_0),
+                equalTo(BOUNDS_POSITION_LEFT));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_TOP, ROTATION_0),
+                equalTo(BOUNDS_POSITION_TOP));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_RIGHT, ROTATION_0),
+                equalTo(BOUNDS_POSITION_RIGHT));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_BOTTOM, ROTATION_0),
+                equalTo(BOUNDS_POSITION_BOTTOM));
+    }
+
+    @Test
+    public void testGetBoundIndexFromRotation_rot90() {
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_LEFT, ROTATION_90),
+                equalTo(BOUNDS_POSITION_BOTTOM));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_TOP, ROTATION_90),
+                equalTo(BOUNDS_POSITION_LEFT));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_RIGHT, ROTATION_90),
+                equalTo(BOUNDS_POSITION_TOP));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_BOTTOM, ROTATION_90),
+                equalTo(BOUNDS_POSITION_RIGHT));
+    }
+
+    @Test
+    public void testGetBoundIndexFromRotation_rot180() {
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_LEFT, ROTATION_180),
+                equalTo(BOUNDS_POSITION_RIGHT));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_TOP, ROTATION_180),
+                equalTo(BOUNDS_POSITION_BOTTOM));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_RIGHT, ROTATION_180),
+                equalTo(BOUNDS_POSITION_LEFT));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_BOTTOM, ROTATION_180),
+                equalTo(BOUNDS_POSITION_TOP));
+    }
+
+    @Test
+    public void testGetBoundIndexFromRotation_rot270() {
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_LEFT, ROTATION_270),
+                equalTo(BOUNDS_POSITION_TOP));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_TOP, ROTATION_270),
+                equalTo(BOUNDS_POSITION_RIGHT));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_RIGHT, ROTATION_270),
+                equalTo(BOUNDS_POSITION_BOTTOM));
+        assertThat(getBoundIndexFromRotation(BOUNDS_POSITION_BOTTOM, ROTATION_270),
+                equalTo(BOUNDS_POSITION_LEFT));
+
+    }
+
+    @Test
+    public void testGetRotatedBounds_top_rot0() {
+        DisplayRotationUtil util = new DisplayRotationUtil();
+        Rect[] bounds = new Rect[] { ZERO_RECT, new Rect(50,0,150,10), ZERO_RECT, ZERO_RECT };
+        assertThat(util.getRotatedBounds(bounds, ROTATION_0, 200, 300),
+                equalTo(bounds));
+    }
+
+    @Test
+    public void testGetRotatedBounds_top_rot90() {
+        DisplayRotationUtil util = new DisplayRotationUtil();
+        Rect[] bounds = new Rect[] { ZERO_RECT, new Rect(50,0,150,10), ZERO_RECT, ZERO_RECT };
+        assertThat(util.getRotatedBounds(bounds, ROTATION_90, 200, 300),
+                equalTo(new Rect[] { new Rect(0, 50, 10, 150), ZERO_RECT, ZERO_RECT, ZERO_RECT }));
+    }
+
+    @Test
+    public void testGetRotatedBounds_top_rot180() {
+        DisplayRotationUtil util = new DisplayRotationUtil();
+        Rect[] bounds = new Rect[] { ZERO_RECT, new Rect(50,0,150,10), ZERO_RECT, ZERO_RECT };
+        assertThat(util.getRotatedBounds(bounds, ROTATION_180, 200, 300),
+                equalTo(new Rect[] { ZERO_RECT, ZERO_RECT, ZERO_RECT, new Rect(50, 290, 150, 300) }));
+    }
+
+    @Test
+    public void testGetRotatedBounds_top_rot270() {
+        DisplayRotationUtil util = new DisplayRotationUtil();
+        Rect[] bounds = new Rect[] { ZERO_RECT, new Rect(50,0,150,10), ZERO_RECT, ZERO_RECT };
+        assertThat(util.getRotatedBounds(bounds, ROTATION_270, 200, 300),
+                equalTo(new Rect[] { ZERO_RECT, ZERO_RECT, new Rect(290, 50, 300, 150), ZERO_RECT }));
+    }
+
+    @Test
+    public void testGetRotatedBounds_left_rot0() {
+        DisplayRotationUtil util = new DisplayRotationUtil();
+        Rect[] bounds = new Rect[] { new Rect(0, 50, 10, 150), ZERO_RECT, ZERO_RECT, ZERO_RECT };
+        assertThat(util.getRotatedBounds(bounds, ROTATION_0, 300, 200),
+                equalTo(bounds));
+    }
+
+    @Test
+    public void testGetRotatedBounds_left_rot90() {
+        DisplayRotationUtil util = new DisplayRotationUtil();
+        Rect[] bounds = new Rect[] { new Rect(0, 50, 10, 150), ZERO_RECT, ZERO_RECT, ZERO_RECT };
+        assertThat(util.getRotatedBounds(bounds, ROTATION_90, 300, 200),
+                equalTo(new Rect[]{ ZERO_RECT, ZERO_RECT, ZERO_RECT, new Rect(50, 290, 150, 300) }));
+    }
+
+    @Test
+    public void testGetRotatedBounds_left_rot180() {
+        DisplayRotationUtil util = new DisplayRotationUtil();
+        Rect[] bounds = new Rect[] { new Rect(0, 50, 10, 150), ZERO_RECT, ZERO_RECT, ZERO_RECT };
+        assertThat(util.getRotatedBounds(bounds, ROTATION_180, 300, 200),
+                equalTo(new Rect[]{ ZERO_RECT, ZERO_RECT, new Rect(290, 50, 300, 150), ZERO_RECT }));
+    }
+
+    @Test
+    public void testGetRotatedBounds_left_rot270() {
+        DisplayRotationUtil util = new DisplayRotationUtil();
+        Rect[] bounds = new Rect[] { new Rect(0, 50, 10, 150), ZERO_RECT, ZERO_RECT, ZERO_RECT };
+        assertThat(util.getRotatedBounds(bounds, ROTATION_270, 300, 200),
+                equalTo(new Rect[]{ ZERO_RECT, new Rect(50, 0, 150, 10), ZERO_RECT, ZERO_RECT }));
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
index 9ce3dca..c5e35e7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/utils/WmDisplayCutoutTest.java
@@ -18,11 +18,19 @@
 
 
 import static android.view.DisplayCutout.NO_CUTOUT;
+import static android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM;
+import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
+import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT;
+import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
 import static android.view.DisplayCutout.fromBoundingRect;
 
+import static org.hamcrest.Matchers.equalTo;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertThat;
 
+
+import android.graphics.Insets;
 import android.graphics.Rect;
 import android.platform.test.annotations.Presubmit;
 import android.util.Size;
@@ -45,15 +53,17 @@
 @SmallTest
 @Presubmit
 public class WmDisplayCutoutTest {
+    private static final Rect ZERO_RECT = new Rect();
 
     private final DisplayCutout mCutoutTop = new DisplayCutout(
-            new Rect(0, 100, 0, 0),
-            Arrays.asList(new Rect(50, 0, 75, 100)));
+            Insets.of(0, 100, 0, 0),
+            null /* boundLeft */, new Rect(50, 0, 75, 100) /* boundTop */,
+            null /* boundRight */, null /* boundBottom */);
 
     @Test
     public void calculateRelativeTo_top() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(0, 0, 100, 20), 200, 400)
+                fromBoundingRect(0, 0, 100, 20, BOUNDS_POSITION_TOP), 200, 400)
                 .calculateRelativeTo(new Rect(5, 5, 95, 195));
 
         assertEquals(new Rect(0, 15, 0, 0), cutout.getDisplayCutout().getSafeInsets());
@@ -62,7 +72,7 @@
     @Test
     public void calculateRelativeTo_left() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(0, 0, 20, 100), 400, 200)
+                fromBoundingRect(0, 0, 20, 100, BOUNDS_POSITION_LEFT), 400, 200)
                 .calculateRelativeTo(new Rect(5, 5, 195, 95));
 
         assertEquals(new Rect(15, 0, 0, 0), cutout.getDisplayCutout().getSafeInsets());
@@ -71,7 +81,7 @@
     @Test
     public void calculateRelativeTo_bottom() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(0, 180, 100, 200), 100, 200)
+                fromBoundingRect(0, 180, 100, 200, BOUNDS_POSITION_BOTTOM), 100, 200)
                 .calculateRelativeTo(new Rect(5, 5, 95, 195));
 
         assertEquals(new Rect(0, 0, 0, 15), cutout.getDisplayCutout().getSafeInsets());
@@ -80,7 +90,7 @@
     @Test
     public void calculateRelativeTo_right() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(180, 0, 200, 100), 200, 100)
+                fromBoundingRect(180, 0, 200, 100, BOUNDS_POSITION_RIGHT), 200, 100)
                 .calculateRelativeTo(new Rect(5, 5, 195, 95));
 
         assertEquals(new Rect(0, 0, 15, 0), cutout.getDisplayCutout().getSafeInsets());
@@ -89,16 +99,17 @@
     @Test
     public void calculateRelativeTo_bounds() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(0, 0, 100, 20), 200, 400)
+                fromBoundingRect(0, 0, 100, 20, BOUNDS_POSITION_TOP), 200, 400)
                 .calculateRelativeTo(new Rect(5, 10, 95, 180));
 
-        assertEquals(new Rect(-5, -10, 95, 10), cutout.getDisplayCutout().getBounds().getBounds());
+        assertThat(cutout.getDisplayCutout().getBoundingRectTop(),
+                equalTo(new Rect(-5, -10, 95, 10)));
     }
 
     @Test
     public void computeSafeInsets_top() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(0, 0, 100, 20), 200, 400);
+                fromBoundingRect(0, 0, 100, 20, BOUNDS_POSITION_TOP), 200, 400);
 
         assertEquals(new Rect(0, 20, 0, 0), cutout.getDisplayCutout().getSafeInsets());
     }
@@ -106,7 +117,7 @@
     @Test
     public void computeSafeInsets_left() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(0, 0, 20, 100), 400, 200);
+                fromBoundingRect(0, 0, 20, 100, BOUNDS_POSITION_LEFT), 400, 200);
 
         assertEquals(new Rect(20, 0, 0, 0), cutout.getDisplayCutout().getSafeInsets());
     }
@@ -114,7 +125,7 @@
     @Test
     public void computeSafeInsets_bottom() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(0, 180, 100, 200), 100, 200);
+                fromBoundingRect(0, 180, 100, 200, BOUNDS_POSITION_BOTTOM), 100, 200);
 
         assertEquals(new Rect(0, 0, 0, 20), cutout.getDisplayCutout().getSafeInsets());
     }
@@ -122,7 +133,7 @@
     @Test
     public void computeSafeInsets_right() {
         WmDisplayCutout cutout = WmDisplayCutout.computeSafeInsets(
-                fromBoundingRect(180, 0, 200, 100), 200, 100);
+                fromBoundingRect(180, 0, 200, 100, BOUNDS_POSITION_RIGHT), 200, 100);
 
         assertEquals(new Rect(0, 0, 20, 0), cutout.getDisplayCutout().getSafeInsets());
     }
@@ -132,8 +143,7 @@
         DisplayCutout cutout = WmDisplayCutout.computeSafeInsets(mCutoutTop, 1000,
                 2000).getDisplayCutout();
 
-        assertEquals(mCutoutTop.getBounds().getBounds(),
-                cutout.getBounds().getBounds());
+        assertEquals(mCutoutTop.getBoundingRects(), cutout.getBoundingRects());
     }
 
     @Test
diff --git a/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk b/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
index 7e7decf..ab222b9 100644
--- a/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
+++ b/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
@@ -20,7 +20,7 @@
 
 LOCAL_COMPATIBILITY_SUITE := device-tests
 
-LOCAL_STATIC_JAVA_LIBRARIES := androidx-test ub-uiautomator
+LOCAL_STATIC_JAVA_LIBRARIES := androidx.test.runner ub-uiautomator
 
 LOCAL_SRC_FILES := $(call all-subdir-java-files)
 LOCAL_SRC_FILES += ../../src/com/android/server/pm/SuspendPackagesTest.java
diff --git a/services/tests/uiservicestests/Android.mk b/services/tests/uiservicestests/Android.mk
index 8405179..f3f4355 100644
--- a/services/tests/uiservicestests/Android.mk
+++ b/services/tests/uiservicestests/Android.mk
@@ -45,6 +45,7 @@
     libbacktrace \
     libbase \
     libbinder \
+    libbinderthreadstate \
     libc++ \
     libcutils \
     liblog \
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 58aae2b..3266b8b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.notification;
 
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
 import static android.app.Notification.FLAG_FOREGROUND_SERVICE;
 import static android.app.NotificationManager.EXTRA_BLOCKED_STATE;
 import static android.app.NotificationManager.IMPORTANCE_HIGH;
@@ -74,6 +76,7 @@
 import android.app.NotificationChannel;
 import android.app.NotificationChannelGroup;
 import android.app.NotificationManager;
+import android.app.ITransientNotification;
 import android.app.IUriGrantsManager;
 import android.app.admin.DevicePolicyManagerInternal;
 import android.app.usage.UsageStatsManagerInternal;
@@ -118,12 +121,14 @@
 import com.android.internal.R;
 import com.android.internal.statusbar.NotificationVisibility;
 import com.android.server.LocalServices;
+import com.android.server.SystemService;
 import com.android.server.UiServiceTestCase;
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
 import com.android.server.notification.NotificationManagerService.NotificationAssistants;
 import com.android.server.notification.NotificationManagerService.NotificationListeners;
 import com.android.server.uri.UriGrantsManagerInternal;
+import com.android.server.wm.WindowManagerInternal;
 
 import org.junit.After;
 import org.junit.Before;
@@ -160,6 +165,8 @@
     private IPackageManager mPackageManager;
     @Mock
     private PackageManager mPackageManagerClient;
+    @Mock
+    private WindowManagerInternal mWindowManagerInternal;
     private TestableContext mContext = spy(getContext());
     private final String PKG = mContext.getPackageName();
     private TestableLooper mTestableLooper;
@@ -238,6 +245,16 @@
         }
     }
 
+    private class TestableToastCallback extends ITransientNotification.Stub {
+        @Override
+        public void show(IBinder windowToken) {
+        }
+
+        @Override
+        public void hide() {
+        }
+    }
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -249,6 +266,8 @@
 
         LocalServices.removeServiceForTest(UriGrantsManagerInternal.class);
         LocalServices.addService(UriGrantsManagerInternal.class, mUgmInternal);
+        LocalServices.removeServiceForTest(WindowManagerInternal.class);
+        LocalServices.addService(WindowManagerInternal.class, mWindowManagerInternal);
 
         mService = new TestableNotificationManagerService(mContext);
 
@@ -302,6 +321,7 @@
                     mGroupHelper, mAm, mAppUsageStats,
                     mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal,
                     mAppOpsManager);
+            mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
         } catch (SecurityException e) {
             if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
                 throw e;
@@ -1669,7 +1689,7 @@
     }
 
     @Test
-    public void testGetNotificationChannelFromPrivilegedListener_success() throws Exception {
+    public void testGetNotificationChannelFromPrivilegedListener_cdm_success() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
         List<String> associations = new ArrayList<>();
         associations.add("a");
@@ -1683,7 +1703,7 @@
     }
 
     @Test
-    public void testGetNotificationChannelFromPrivilegedListener_noAccess() throws Exception {
+    public void testGetNotificationChannelFromPrivilegedListener_cdm_noAccess() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
         List<String> associations = new ArrayList<>();
         when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(associations);
@@ -1701,6 +1721,38 @@
     }
 
     @Test
+    public void testGetNotificationChannelFromPrivilegedListener_assistant_success()
+            throws Exception {
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(new ArrayList<>());
+        when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(true);
+
+        mBinderService.getNotificationChannelsFromPrivilegedListener(
+                null, PKG, Process.myUserHandle());
+
+        verify(mPreferencesHelper, times(1)).getNotificationChannels(
+                anyString(), anyInt(), anyBoolean());
+    }
+
+    @Test
+    public void testGetNotificationChannelFromPrivilegedListener_assistant_noAccess() throws Exception {
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mCompanionMgr.getAssociations(PKG, mUid)).thenReturn(new ArrayList<>());
+        when(mAssistants.isServiceTokenValidLocked(any())).thenReturn(false);
+
+        try {
+            mBinderService.getNotificationChannelsFromPrivilegedListener(
+                    null, PKG, Process.myUserHandle());
+            fail("listeners that don't have a companion device shouldn't be able to call this");
+        } catch (SecurityException e) {
+            // pass
+        }
+
+        verify(mPreferencesHelper, never()).getNotificationChannels(
+                anyString(), anyInt(), anyBoolean());
+    }
+
+    @Test
     public void testGetNotificationChannelFromPrivilegedListener_badUser() throws Exception {
         mService.setPreferencesHelper(mPreferencesHelper);
         List<String> associations = new ArrayList<>();
@@ -3548,4 +3600,93 @@
 
         assertEquals(0, captor.getValue().getNotification().flags);
     }
+
+    @Test
+    public void testAllowForegroundToasts() throws Exception {
+        final String testPackage = "testPackageName";
+        assertEquals(0, mService.mToastQueue.size());
+        mService.isSystemUid = false;
+
+        // package is not suspended
+        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+                .thenReturn(false);
+
+        // notifications from this package are blocked by the user
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
+
+        // this app is in the foreground
+        when(mActivityManager.getUidImportance(mUid)).thenReturn(IMPORTANCE_FOREGROUND);
+
+        // enqueue toast -> toast should still enqueue
+        ((INotificationManager)mService.mService).enqueueToast(testPackage,
+                new TestableToastCallback(), 2000, 0);
+        assertEquals(1, mService.mToastQueue.size());
+    }
+
+    @Test
+    public void testDisallowToastsFromSuspendedPackages() throws Exception {
+        final String testPackage = "testPackageName";
+        assertEquals(0, mService.mToastQueue.size());
+        mService.isSystemUid = false;
+
+        // package is suspended
+        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+                .thenReturn(true);
+
+        // notifications from this package are NOT blocked by the user
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_LOW);
+
+        // enqueue toast -> no toasts enqueued
+        ((INotificationManager)mService.mService).enqueueToast(testPackage,
+                new TestableToastCallback(), 2000, 0);
+        assertEquals(0, mService.mToastQueue.size());
+    }
+
+    @Test
+    public void testDisallowToastsFromBlockedApps() throws Exception {
+        final String testPackage = "testPackageName";
+        assertEquals(0, mService.mToastQueue.size());
+        mService.isSystemUid = false;
+
+        // package is not suspended
+        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+                .thenReturn(false);
+
+        // notifications from this package are blocked by the user
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
+
+        // this app is NOT in the foreground
+        when(mActivityManager.getUidImportance(mUid)).thenReturn(IMPORTANCE_GONE);
+
+        // enqueue toast -> no toasts enqueued
+        ((INotificationManager)mService.mService).enqueueToast(testPackage,
+                new TestableToastCallback(), 2000, 0);
+        assertEquals(0, mService.mToastQueue.size());
+    }
+
+    @Test
+    public void testAlwaysAllowSystemToasts() throws Exception {
+        final String testPackage = "testPackageName";
+        assertEquals(0, mService.mToastQueue.size());
+        mService.isSystemUid = true;
+
+        // package is suspended
+        when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+                .thenReturn(true);
+
+        // notifications from this package ARE blocked by the user
+        mService.setPreferencesHelper(mPreferencesHelper);
+        when(mPreferencesHelper.getImportance(testPackage, mUid)).thenReturn(IMPORTANCE_NONE);
+
+        // this app is NOT in the foreground
+        when(mActivityManager.getUidImportance(mUid)).thenReturn(IMPORTANCE_GONE);
+
+        // enqueue toast -> system toast can still be enqueued
+        ((INotificationManager)mService.mService).enqueueToast(testPackage,
+                new TestableToastCallback(), 2000, 0);
+        assertEquals(1, mService.mToastQueue.size());
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
index 11b086c..1b59e75 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationRecordTest.java
@@ -32,6 +32,7 @@
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -54,7 +55,6 @@
 import android.metrics.LogMaker;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.notification.Adjustment;
@@ -74,35 +74,31 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
-import java.util.Objects;
+import java.util.Arrays;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class NotificationRecordTest extends UiServiceTestCase {
 
     private final Context mMockContext = mock(Context.class);
-    @Mock PackageManager mPm;
+    @Mock private PackageManager mPm;
 
     private final String pkg = PKG_N_MR1;
     private final int uid = 9583;
-    private final String pkg2 = PKG_O;
-    private final int uid2 = 1111111;
     private final int id1 = 1;
-    private final int id2 = 2;
     private final String tag1 = "tag1";
-    private final String tag2 = "tag2";
     private final String channelId = "channel";
-    NotificationChannel channel =
+    private NotificationChannel channel =
             new NotificationChannel(channelId, "test", NotificationManager.IMPORTANCE_DEFAULT);
     private final String channelIdLong =
             "give_a_developer_a_string_argument_and_who_knows_what_they_will_pass_in_there";
-    final String groupId = "group";
-    final String groupIdOverride = "other_group";
+    private final String groupId = "group";
+    private final String groupIdOverride = "other_group";
     private final String groupIdLong =
             "0|com.foo.bar|g:content://com.foo.bar.ui/account%3A-0000000/account/";
-    NotificationChannel channelLongId =
+    private NotificationChannel channelLongId =
             new NotificationChannel(channelIdLong, "long", NotificationManager.IMPORTANCE_DEFAULT);
-    NotificationChannel defaultChannel =
+    private NotificationChannel defaultChannel =
             new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "test",
                     NotificationManager.IMPORTANCE_UNSPECIFIED);
     private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
@@ -185,7 +181,7 @@
     //
 
     @Test
-    public void testSound_default_preUpgradeUsesNotification() throws Exception {
+    public void testSound_default_preUpgradeUsesNotification() {
         defaultChannel.setSound(null, null);
         // pre upgrade, default sound.
         StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
@@ -198,7 +194,7 @@
     }
 
     @Test
-    public void testSound_custom_preUpgradeUsesNotification() throws Exception {
+    public void testSound_custom_preUpgradeUsesNotification() {
         defaultChannel.setSound(null, null);
         // pre upgrade, custom sound.
         StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
@@ -211,7 +207,7 @@
     }
 
     @Test
-    public void testSound_default_userLocked_preUpgrade() throws Exception {
+    public void testSound_default_userLocked_preUpgrade() {
         defaultChannel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
         defaultChannel.lockFields(NotificationChannel.USER_LOCKED_SOUND);
         // pre upgrade, default sound.
@@ -225,19 +221,19 @@
     }
 
     @Test
-    public void testSound_noSound_preUpgrade() throws Exception {
+    public void testSound_noSound_preUpgrade() {
         // pre upgrade, default sound.
         StatusBarNotification sbn = getNotification(PKG_N_MR1, false /* noisy */,
                 false /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, null /* group */);
 
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
-        assertEquals(null, record.getSound());
+        assertNull(record.getSound());
         assertEquals(Notification.AUDIO_ATTRIBUTES_DEFAULT, record.getAudioAttributes());
     }
 
     @Test
-    public void testSound_default_upgradeUsesChannel() throws Exception {
+    public void testSound_default_upgradeUsesChannel() {
         channel.setSound(CUSTOM_SOUND, CUSTOM_ATTRIBUTES);
         // post upgrade, default sound.
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
@@ -250,7 +246,7 @@
     }
 
     @Test
-    public void testVibration_default_preUpgradeUsesNotification() throws Exception {
+    public void testVibration_default_preUpgradeUsesNotification() {
         defaultChannel.enableVibration(false);
         // pre upgrade, default vibration.
         StatusBarNotification sbn = getNotification(PKG_N_MR1, false /* noisy */,
@@ -262,7 +258,7 @@
     }
 
     @Test
-    public void testVibration_custom_preUpgradeUsesNotification() throws Exception {
+    public void testVibration_custom_preUpgradeUsesNotification() {
         defaultChannel.enableVibration(false);
         // pre upgrade, custom vibration.
         StatusBarNotification sbn = getNotification(PKG_N_MR1, false /* noisy */,
@@ -274,7 +270,7 @@
     }
 
     @Test
-    public void testVibration_custom_userLocked_preUpgrade() throws Exception {
+    public void testVibration_custom_userLocked_preUpgrade() {
         defaultChannel.enableVibration(true);
         defaultChannel.lockFields(NotificationChannel.USER_LOCKED_VIBRATION);
         // pre upgrade, custom vibration.
@@ -283,11 +279,11 @@
                 false /* lights */, false /* defaultLights */, null /* group */);
 
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
-        assertTrue(!Objects.equals(CUSTOM_VIBRATION, record.getVibration()));
+        assertTrue(!Arrays.equals(CUSTOM_VIBRATION, record.getVibration()));
     }
 
     @Test
-    public void testVibration_custom_upgradeUsesChannel() throws Exception {
+    public void testVibration_custom_upgradeUsesChannel() {
         channel.enableVibration(true);
         // post upgrade, custom vibration.
         StatusBarNotification sbn = getNotification(PKG_O, false /* noisy */,
@@ -299,7 +295,7 @@
     }
 
     @Test
-    public void testImportance_preUpgrade() throws Exception {
+    public void testImportance_preUpgrade() {
         StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, null /* group */);
@@ -308,7 +304,7 @@
     }
 
     @Test
-    public void testImportance_locked_preUpgrade() throws Exception {
+    public void testImportance_locked_preUpgrade() {
         defaultChannel.setImportance(IMPORTANCE_LOW);
         defaultChannel.lockFields(USER_LOCKED_IMPORTANCE);
         StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
@@ -320,7 +316,7 @@
     }
 
     @Test
-    public void testImportance_locked_unspecified_preUpgrade() throws Exception {
+    public void testImportance_locked_unspecified_preUpgrade() {
         defaultChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
         defaultChannel.lockFields(USER_LOCKED_IMPORTANCE);
         StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
@@ -332,7 +328,7 @@
     }
 
     @Test
-    public void testImportance_upgrade() throws Exception {
+    public void testImportance_upgrade() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, null /* group */);
@@ -341,7 +337,7 @@
     }
 
     @Test
-    public void testLights_preUpgrade_noLight() throws Exception {
+    public void testLights_preUpgrade_noLight() {
         StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, null /* group */);
@@ -351,7 +347,7 @@
 
 
     @Test
-    public void testLights_preUpgrade() throws Exception {
+    public void testLights_preUpgrade() {
         StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 true /* lights */, false /* defaultLights */, null /* group */);
@@ -360,7 +356,7 @@
     }
 
     @Test
-    public void testLights_locked_preUpgrade() throws Exception {
+    public void testLights_locked_preUpgrade() {
         defaultChannel.enableLights(true);
         defaultChannel.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
         StatusBarNotification sbn = getNotification(PKG_N_MR1, true /* noisy */,
@@ -368,11 +364,11 @@
                 true /* lights */, false /* defaultLights */, null /* group */);
 
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, defaultChannel);
-        assertFalse(CUSTOM_LIGHT.equals(record.getLight()));
+        assertNotEquals(CUSTOM_LIGHT, record.getLight());
     }
 
     @Test
-    public void testLights_upgrade_defaultLights() throws Exception {
+    public void testLights_upgrade_defaultLights() {
         int defaultLightColor = mMockContext.getResources().getColor(
                 com.android.internal.R.color.config_defaultNotificationColor);
         int defaultLightOn = mMockContext.getResources().getInteger(
@@ -390,7 +386,7 @@
     }
 
     @Test
-    public void testLights_upgrade() throws Exception {
+    public void testLights_upgrade() {
         int defaultLightOn = mMockContext.getResources().getInteger(
                 com.android.internal.R.integer.config_defaultNotificationLedOn);
         int defaultLightOff = mMockContext.getResources().getInteger(
@@ -406,7 +402,7 @@
     }
 
     @Test
-    public void testLights_upgrade_noLight() throws Exception {
+    public void testLights_upgrade_noLight() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, null /* group */);
@@ -415,7 +411,7 @@
     }
 
     @Test
-    public void testLogmakerShortChannel() throws Exception {
+    public void testLogmakerShortChannel() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, null /* group */);
@@ -428,7 +424,7 @@
     }
 
     @Test
-    public void testLogmakerLongChannel() throws Exception {
+    public void testLogmakerLongChannel() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
         true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
         false /* lights */, false /*defaultLights */, null /* group */);
@@ -439,7 +435,7 @@
     }
 
     @Test
-    public void testLogmakerNoGroup() throws Exception {
+    public void testLogmakerNoGroup() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /*defaultLights */, null /* group */);
@@ -448,7 +444,7 @@
     }
 
     @Test
-    public void testLogmakerShortGroup() throws Exception {
+    public void testLogmakerShortGroup() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupId /* group */);
@@ -458,7 +454,7 @@
     }
 
     @Test
-    public void testLogmakerLongGroup() throws Exception {
+    public void testLogmakerLongGroup() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupIdLong /* group */);
@@ -469,7 +465,7 @@
     }
 
     @Test
-    public void testLogmakerOverrideGroup() throws Exception {
+    public void testLogmakerOverrideGroup() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupId /* group */);
@@ -485,7 +481,7 @@
     }
 
     @Test
-    public void testNotificationStats() throws Exception {
+    public void testNotificationStats() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupId /* group */);
@@ -528,7 +524,7 @@
     }
 
     @Test
-    public void testUserSentiment() throws Exception {
+    public void testUserSentiment() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupId /* group */);
@@ -546,7 +542,7 @@
     }
 
     @Test
-    public void testUserSentiment_appImportanceUpdatesSentiment() throws Exception {
+    public void testUserSentiment_appImportanceUpdatesSentiment() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupId /* group */);
@@ -558,7 +554,7 @@
     }
 
     @Test
-    public void testUserSentiment_appImportanceBlocksNegativeSentimentUpdate() throws Exception {
+    public void testUserSentiment_appImportanceBlocksNegativeSentimentUpdate() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupId /* group */);
@@ -574,7 +570,7 @@
     }
 
     @Test
-    public void testUserSentiment_userLocked() throws Exception {
+    public void testUserSentiment_userLocked() {
         channel.lockFields(USER_LOCKED_IMPORTANCE);
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
@@ -593,17 +589,17 @@
     }
 
     @Test
-    public void testAppImportance_returnsCorrectly() throws Exception {
+    public void testAppImportance_returnsCorrectly() {
         StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
                 true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
                 false /* lights */, false /* defaultLights */, groupId /* group */);
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
 
         record.setIsAppImportanceLocked(true);
-        assertEquals(true, record.getIsAppImportanceLocked());
+        assertTrue(record.getIsAppImportanceLocked());
 
         record.setIsAppImportanceLocked(false);
-        assertEquals(false, record.getIsAppImportanceLocked());
+        assertFalse(record.getIsAppImportanceLocked());
     }
 
     @Test
@@ -613,10 +609,10 @@
                 false /* lights */, false /* defaultLights */, null /* group */);
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
 
-        assertEquals(false, record.isInterruptive());
+        assertFalse(record.isInterruptive());
 
         record.setTextChanged(true);
-        assertEquals(false, record.isInterruptive());
+        assertFalse(record.isInterruptive());
     }
 
     @Test
@@ -626,11 +622,11 @@
                 false /* lights */, false /* defaultLights */, null /* group */);
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
 
-        assertEquals(false, record.isInterruptive());
+        assertFalse(record.isInterruptive());
 
         record.setTextChanged(true);
         record.setSeen();
-        assertEquals(true, record.isInterruptive());
+        assertTrue(record.isInterruptive());
     }
 
     @Test
@@ -640,15 +636,15 @@
                 false /* lights */, false /* defaultLights */, null /* group */);
         NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
 
-        assertEquals(false, record.isInterruptive());
+        assertFalse(record.isInterruptive());
 
         record.setTextChanged(false);
         record.setSeen();
-        assertEquals(false, record.isInterruptive());
+        assertFalse(record.isInterruptive());
     }
 
     @Test
-    public void testCalculateGrantableUris_PappProvided() throws RemoteException {
+    public void testCalculateGrantableUris_PappProvided() {
         IActivityManager am = mock(IActivityManager.class);
         UriGrantsManagerInternal ugm = mock(UriGrantsManagerInternal.class);
         when(ugm.checkGrantUriPermission(anyInt(), eq(null), any(Uri.class),
@@ -671,7 +667,7 @@
     }
 
     @Test
-    public void testCalculateGrantableUris_PuserOverridden() throws RemoteException {
+    public void testCalculateGrantableUris_PuserOverridden() {
         IActivityManager am = mock(IActivityManager.class);
         UriGrantsManagerInternal ugm = mock(UriGrantsManagerInternal.class);
         when(ugm.checkGrantUriPermission(anyInt(), eq(null), any(Uri.class),
@@ -689,7 +685,7 @@
     }
 
     @Test
-    public void testCalculateGrantableUris_prePappProvided() throws RemoteException {
+    public void testCalculateGrantableUris_prePappProvided() {
         IActivityManager am = mock(IActivityManager.class);
         UriGrantsManagerInternal ugm = mock(UriGrantsManagerInternal.class);
         when(ugm.checkGrantUriPermission(anyInt(), eq(null), any(Uri.class),
@@ -790,4 +786,19 @@
 
         assertEquals(IMPORTANCE_LOW, record.getImportance());
     }
+
+    @Test
+    public void testSetContactAffinity() {
+        channel.setImportance(IMPORTANCE_LOW);
+        channel.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+        StatusBarNotification sbn = getNotification(PKG_O, true /* noisy */,
+                true /* defaultSound */, false /* buzzy */, false /* defaultBuzz */,
+                false /* lights */, false /* defaultLights */, groupId /* group */);
+        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
+
+        record.setContactAffinity(1.0f);
+
+        assertEquals(1.0f, record.getContactAffinity());
+        assertEquals(IMPORTANCE_LOW, record.getImportance());
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
index 9db823c..55c16b3 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationTest.java
@@ -48,6 +48,7 @@
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.StyleSpan;
+import android.util.Pair;
 import android.widget.RemoteViews;
 
 import com.android.server.UiServiceTestCase;
@@ -541,5 +542,94 @@
 
         assertFalse(Notification.areActionsVisiblyDifferent(n1, n2));
     }
+
+    @Test
+    public void testFreeformRemoteInputActionPair_noRemoteInput() {
+        PendingIntent intent = mock(PendingIntent.class);
+        Icon icon = mock(Icon.class);
+        Notification notification = new Notification.Builder(mContext, "test")
+                .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent)
+                        .build())
+                .build();
+        assertNull(notification.findRemoteInputActionPair(false));
+    }
+
+    @Test
+    public void testFreeformRemoteInputActionPair_hasRemoteInput() {
+        PendingIntent intent = mock(PendingIntent.class);
+        Icon icon = mock(Icon.class);
+
+        RemoteInput remoteInput = new RemoteInput.Builder("a").build();
+
+        Notification.Action actionWithRemoteInput =
+                new Notification.Action.Builder(icon, "TEXT 1", intent)
+                        .addRemoteInput(remoteInput)
+                        .addRemoteInput(remoteInput)
+                        .build();
+
+        Notification.Action actionWithoutRemoteInput =
+                new Notification.Action.Builder(icon, "TEXT 2", intent)
+                        .build();
+
+        Notification notification = new Notification.Builder(mContext, "test")
+                .addAction(actionWithoutRemoteInput)
+                .addAction(actionWithRemoteInput)
+                .build();
+
+        Pair<RemoteInput, Notification.Action> remoteInputActionPair =
+                notification.findRemoteInputActionPair(false);
+
+        assertNotNull(remoteInputActionPair);
+        assertEquals(remoteInput, remoteInputActionPair.first);
+        assertEquals(actionWithRemoteInput, remoteInputActionPair.second);
+    }
+
+    @Test
+    public void testFreeformRemoteInputActionPair_requestFreeform_noFreeformRemoteInput() {
+        PendingIntent intent = mock(PendingIntent.class);
+        Icon icon = mock(Icon.class);
+        Notification notification = new Notification.Builder(mContext, "test")
+                .addAction(new Notification.Action.Builder(icon, "TEXT 1", intent)
+                        .addRemoteInput(
+                                new RemoteInput.Builder("a")
+                                        .setAllowFreeFormInput(false).build())
+                        .build())
+                .build();
+        assertNull(notification.findRemoteInputActionPair(true));
+    }
+
+    @Test
+    public void testFreeformRemoteInputActionPair_requestFreeform_hasFreeformRemoteInput() {
+        PendingIntent intent = mock(PendingIntent.class);
+        Icon icon = mock(Icon.class);
+
+        RemoteInput remoteInput =
+                new RemoteInput.Builder("a").setAllowFreeFormInput(false).build();
+        RemoteInput freeformRemoteInput =
+                new RemoteInput.Builder("b").setAllowFreeFormInput(true).build();
+
+        Notification.Action actionWithFreeformRemoteInput =
+                new Notification.Action.Builder(icon, "TEXT 1", intent)
+                        .addRemoteInput(remoteInput)
+                        .addRemoteInput(freeformRemoteInput)
+                        .build();
+
+        Notification.Action actionWithoutFreeformRemoteInput =
+                new Notification.Action.Builder(icon, "TEXT 2", intent)
+                        .addRemoteInput(remoteInput)
+                        .build();
+
+        Notification notification = new Notification.Builder(mContext, "test")
+                .addAction(actionWithoutFreeformRemoteInput)
+                .addAction(actionWithFreeformRemoteInput)
+                .build();
+
+        Pair<RemoteInput, Notification.Action> remoteInputActionPair =
+                notification.findRemoteInputActionPair(true);
+
+        assertNotNull(remoteInputActionPair);
+        assertEquals(freeformRemoteInput, remoteInputActionPair.first);
+        assertEquals(actionWithFreeformRemoteInput, remoteInputActionPair.second);
+    }
 }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
index 100f9c6..9bd3f26 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java
@@ -19,7 +19,9 @@
 import static junit.framework.Assert.assertEquals;
 
 import android.app.NotificationManager.Policy;
+import android.net.Uri;
 import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeConfig.EventInfo;
 import android.service.notification.ZenPolicy;
 import android.support.test.runner.AndroidJUnit4;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -112,6 +114,30 @@
         assertEquals(true, ZenModeConfig.areAllZenBehaviorSoundsMuted(config));
     }
 
+    @Test
+    public void testParseOldEvent() {
+        EventInfo oldEvent = new EventInfo();
+        oldEvent.userId = 1;
+        oldEvent.calName = "calName";
+        oldEvent.calendarId = null; // old events will have null ids
+
+        Uri conditionId = ZenModeConfig.toEventConditionId(oldEvent);
+        EventInfo eventParsed = ZenModeConfig.tryParseEventConditionId(conditionId);
+        assertEquals(oldEvent, eventParsed);
+    }
+
+    @Test
+    public void testParseNewEvent() {
+        EventInfo event = new EventInfo();
+        event.userId = 1;
+        event.calName = "calName";
+        event.calendarId = 12345L;
+
+        Uri conditionId = ZenModeConfig.toEventConditionId(event);
+        EventInfo eventParsed = ZenModeConfig.tryParseEventConditionId(conditionId);
+        assertEquals(event, eventParsed);
+    }
+
     private ZenModeConfig getMutedNotificationsConfig() {
         ZenModeConfig config = new ZenModeConfig();
         // Allow alarms, media, and system
diff --git a/services/tests/wmtests/Android.mk b/services/tests/wmtests/Android.mk
index 0f8b18a..c095ae0 100644
--- a/services/tests/wmtests/Android.mk
+++ b/services/tests/wmtests/Android.mk
@@ -14,7 +14,7 @@
     $(call all-java-files-under, ../servicestests/utils)
 
 LOCAL_STATIC_JAVA_LIBRARIES := \
-    androidx-test \
+    androidx.test.runner \
     mockito-target-minus-junit4 \
     platform-test-annotations \
 
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java
index 4e99732..bc54a5d 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java
@@ -320,14 +320,7 @@
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         AppUsageHistory appUsageHistory =
                 getPackageHistory(userHistory, packageName, elapsedRealtime, true);
-        if (appUsageHistory == null) {
-            return false; // Default to not idle
-        } else {
-            return appUsageHistory.currentBucket >= STANDBY_BUCKET_RARE;
-            // Whether or not it's passed will now be externally calculated and the
-            // bucket will be pushed to the history using setAppStandbyBucket()
-            //return hasPassedThresholds(appUsageHistory, elapsedRealtime);
-        }
+        return appUsageHistory.currentBucket >= STANDBY_BUCKET_RARE;
     }
 
     public AppUsageHistory getAppUsageHistory(String packageName, int userId,
@@ -404,17 +397,19 @@
     public long getTimeSinceLastJobRun(String packageName, int userId, long elapsedRealtime) {
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         AppUsageHistory appUsageHistory =
-                getPackageHistory(userHistory, packageName, elapsedRealtime, true);
+                getPackageHistory(userHistory, packageName, elapsedRealtime, false);
         // Don't adjust the default, else it'll wrap around to a positive value
-        if (appUsageHistory.lastJobRunTime == Long.MIN_VALUE) return Long.MAX_VALUE;
+        if (appUsageHistory == null || appUsageHistory.lastJobRunTime == Long.MIN_VALUE) {
+            return Long.MAX_VALUE;
+        }
         return getElapsedTime(elapsedRealtime) - appUsageHistory.lastJobRunTime;
     }
 
     public int getAppStandbyBucket(String packageName, int userId, long elapsedRealtime) {
         ArrayMap<String, AppUsageHistory> userHistory = getUserHistory(userId);
         AppUsageHistory appUsageHistory =
-                getPackageHistory(userHistory, packageName, elapsedRealtime, true);
-        return appUsageHistory.currentBucket;
+                getPackageHistory(userHistory, packageName, elapsedRealtime, false);
+        return appUsageHistory == null ? STANDBY_BUCKET_NEVER : appUsageHistory.currentBucket;
     }
 
     public ArrayList<AppStandbyInfo> getAppStandbyBuckets(int userId, boolean appIdleEnabled) {
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 02ad3a8..6a74564 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -1161,6 +1161,10 @@
     void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
             int reason, long elapsedRealtime, boolean resetTimeout) {
         synchronized (mAppIdleLock) {
+            // If the package is not installed, don't allow the bucket to be set.
+            if (!mInjector.isPackageInstalled(packageName, 0, userId)) {
+                return;
+            }
             AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
                     userId, elapsedRealtime);
             boolean predicted = (reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED;
@@ -1594,6 +1598,10 @@
             return mPackageManagerInternal.isPackageEphemeral(userId, packageName);
         }
 
+        boolean isPackageInstalled(String packageName, int flags, int userId) {
+            return mPackageManagerInternal.getPackageUid(packageName, flags, userId) >= 0;
+        }
+
         int[] getRunningUserIds() throws RemoteException {
             return ActivityManager.getService().getRunningUserIds();
         }
diff --git a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
index c616685..0e15947 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsDatabase.java
@@ -58,31 +58,31 @@
  * When the UsageStatsDatabase version is upgraded, the files on disk are migrated to the new
  * version on init. The steps of migration are as follows:
  * 1) Check if version upgrade breadcrumb exists on disk, if so skip to step 4.
- * 2) Copy current files to versioned backup files.
- * 3) Write a temporary breadcrumb file with some info about the backed up files.
- * 4) Deserialize a versioned backup file using the info written to the breadcrumb for the
- * correct deserialization methodology.
+ * 2) Move current files to a timestamped backup directory.
+ * 3) Write a temporary breadcrumb file with some info about the backup directory.
+ * 4) Deserialize the backup files in the timestamped backup folder referenced by the breadcrumb.
  * 5) Reserialize the data read from the file with the new version format and replace the old files
- * 6) Repeat Step 3 and 4 for each versioned backup file matching the breadcrumb file.
+ * 6) Repeat Step 3 and 4 for each file in the backup folder.
  * 7) Update the version file with the new version and build fingerprint.
- * 8) Delete the versioned backup files (unless flagged to be kept).
+ * 8) Delete the time stamped backup folder (unless flagged to be kept).
  * 9) Delete the breadcrumb file.
  *
  * Performing the upgrade steps in this order, protects against unexpected shutdowns mid upgrade
  *
- * A versioned backup file is simply a copy of a Usage Stats file with some extra info embedded in
- * the file name. The structure of the versioned backup filename is as followed:
- * (original file name).(backup timestamp).(original file version).vak
- *
- * During the version upgrade process, the new upgraded file will have it's name set to the original
- * file name. The backup timestamp helps distinguish between versioned backups if multiple upgrades
- * and downgrades have taken place. The original file version denotes how to parse the file.
+ * The backup directory will contain directories with timestamp names. If the upgrade breadcrumb
+ * exists on disk, it will contain a timestamp which will match one of the backup directories. The
+ * breadcrumb will also contain a version number which will denote how the files in the backup
+ * directory should be deserialized.
  */
 public class UsageStatsDatabase {
     private static final int DEFAULT_CURRENT_VERSION = 4;
-
-    // Current version of the backup schema
-    static final int BACKUP_VERSION = 1;
+    /**
+     * Current version of the backup schema
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public static final int BACKUP_VERSION = 4;
 
     // Key under which the payload blob is stored
     // same as UsageStatsBackupHelper.KEY_USAGE_STATS
@@ -91,13 +91,12 @@
     // Persist versioned backup files.
     // Should be false, except when testing new versions
     // STOPSHIP: b/111422946 this should be false on launch
-    static final boolean KEEP_VAK_FILES = true;
+    static final boolean KEEP_BACKUP_DIR = true;
 
     private static final String TAG = "UsageStatsDatabase";
     // STOPSHIP: b/111422946 this should be boolean DEBUG = UsageStatsService.DEBUG; on launch
     private static final boolean DEBUG = true;
     private static final String BAK_SUFFIX = ".bak";
-    private static final String VERSIONED_BAK_SUFFIX = ".vak";
     private static final String CHECKED_IN_SUFFIX = UsageStatsXml.CHECKED_IN_SUFFIX;
     private static final String RETENTION_LEN_KEY = "ro.usagestats.chooser.retention";
     private static final int SELECTION_LOG_RETENTION_LEN =
@@ -108,12 +107,13 @@
     private final TimeSparseArray<AtomicFile>[] mSortedStatFiles;
     private final UnixCalendar mCal;
     private final File mVersionFile;
+    private final File mBackupsDir;
     // If this file exists on disk, UsageStatsDatabase is in the middle of migrating files to a new
     // version. If this file exists on boot, the upgrade was interrupted and needs to be picked up
     // where it left off.
     private final File mUpdateBreadcrumb;
     // Current version of the database files schema
-    private final int mCurrentVersion;
+    private int mCurrentVersion;
     private boolean mFirstUpdate;
     private boolean mNewUpdate;
 
@@ -133,6 +133,7 @@
         };
         mCurrentVersion = version;
         mVersionFile = new File(dir, "version");
+        mBackupsDir = new File(dir, "backups");
         mUpdateBreadcrumb = new File(dir, "breadcrumb");
         mSortedStatFiles = new TimeSparseArray[mIntervalDirs.length];
         mCal = new UnixCalendar(0);
@@ -251,7 +252,7 @@
         final FilenameFilter backupFileFilter = new FilenameFilter() {
             @Override
             public boolean accept(File dir, String name) {
-                return !name.endsWith(BAK_SUFFIX) && !name.endsWith(VERSIONED_BAK_SUFFIX);
+                return !name.endsWith(BAK_SUFFIX);
             }
         };
 
@@ -316,24 +317,33 @@
         if (version != mCurrentVersion) {
             Slog.i(TAG, "Upgrading from version " + version + " to " + mCurrentVersion);
             if (!mUpdateBreadcrumb.exists()) {
-                doUpgradeLocked(version);
+                try {
+                    doUpgradeLocked(version);
+                } catch (Exception e) {
+                    Slog.e(TAG,
+                            "Failed to upgrade from version " + version + " to " + mCurrentVersion,
+                            e);
+                    // Fallback to previous version.
+                    mCurrentVersion = version;
+                    return;
+                }
             } else {
                 Slog.i(TAG, "Version upgrade breadcrumb found on disk! Continuing version upgrade");
             }
+        }
 
-            if (mUpdateBreadcrumb.exists()) {
-                int previousVersion;
-                long token;
-                try (BufferedReader reader = new BufferedReader(
-                        new FileReader(mUpdateBreadcrumb))) {
-                    token = Long.parseLong(reader.readLine());
-                    previousVersion = Integer.parseInt(reader.readLine());
-                } catch (NumberFormatException | IOException e) {
-                    Slog.e(TAG, "Failed read version upgrade breadcrumb");
-                    throw new RuntimeException(e);
-                }
-                continueUpgradeLocked(previousVersion, token);
+        if (mUpdateBreadcrumb.exists()) {
+            int previousVersion;
+            long token;
+            try (BufferedReader reader = new BufferedReader(
+                    new FileReader(mUpdateBreadcrumb))) {
+                token = Long.parseLong(reader.readLine());
+                previousVersion = Integer.parseInt(reader.readLine());
+            } catch (NumberFormatException | IOException e) {
+                Slog.e(TAG, "Failed read version upgrade breadcrumb");
+                throw new RuntimeException(e);
             }
+            continueUpgradeLocked(previousVersion, token);
         }
 
         if (version != mCurrentVersion || mNewUpdate) {
@@ -351,11 +361,12 @@
 
         if (mUpdateBreadcrumb.exists()) {
             // Files should be up to date with current version. Clear the version update breadcrumb
-            if (!KEEP_VAK_FILES) {
-                removeVersionedBackupFiles();
-            }
             mUpdateBreadcrumb.delete();
         }
+
+        if (mBackupsDir.exists() && !KEEP_BACKUP_DIR) {
+            deleteDirectory(mBackupsDir);
+        }
     }
 
     private String getBuildFingerprint() {
@@ -378,22 +389,36 @@
                 }
             }
         } else {
-            // Turn all current usage stats files into versioned backup files
+            // Create a dir in backups based on current timestamp
             final long token = System.currentTimeMillis();
-            final FilenameFilter backupFileFilter = new FilenameFilter() {
-                @Override
-                public boolean accept(File dir, String name) {
-                    return !name.endsWith(BAK_SUFFIX) && !name.endsWith(VERSIONED_BAK_SUFFIX);
-                }
-            };
+            final File backupDir = new File(mBackupsDir, Long.toString(token));
+            backupDir.mkdirs();
+            if (!backupDir.exists()) {
+                throw new IllegalStateException(
+                        "Failed to create backup directory " + backupDir.getAbsolutePath());
+            }
+            try {
+                Files.copy(mVersionFile.toPath(),
+                        new File(backupDir, mVersionFile.getName()).toPath(),
+                        StandardCopyOption.REPLACE_EXISTING);
+            } catch (IOException e) {
+                Slog.e(TAG, "Failed to back up version file : " + mVersionFile.toString());
+                throw new RuntimeException(e);
+            }
 
             for (int i = 0; i < mIntervalDirs.length; i++) {
-                File[] files = mIntervalDirs[i].listFiles(backupFileFilter);
+                final File backupIntervalDir = new File(backupDir, mIntervalDirs[i].getName());
+                backupIntervalDir.mkdir();
+
+                if (!backupIntervalDir.exists()) {
+                    throw new IllegalStateException(
+                            "Failed to create interval backup directory "
+                                    + backupIntervalDir.getAbsolutePath());
+                }
+                File[] files = mIntervalDirs[i].listFiles();
                 if (files != null) {
                     for (int j = 0; j < files.length; j++) {
-                        final File backupFile = new File(
-                                files[j].toString() + "." + Long.toString(token) + "."
-                                        + Integer.toString(thisVersion) + VERSIONED_BAK_SUFFIX);
+                        final File backupFile = new File(backupIntervalDir, files[j].getName());
                         if (DEBUG) {
                             Slog.d(TAG, "Creating versioned (" + Integer.toString(thisVersion)
                                     + ") backup of " + files[j].toString()
@@ -403,9 +428,8 @@
 
                         try {
                             // Backup file should not already exist, but make sure it doesn't
-                            Files.deleteIfExists(backupFile.toPath());
                             Files.move(files[j].toPath(), backupFile.toPath(),
-                                    StandardCopyOption.ATOMIC_MOVE);
+                                    StandardCopyOption.REPLACE_EXISTING);
                         } catch (IOException e) {
                             Slog.e(TAG, "Failed to back up file : " + files[j].toString());
                             throw new RuntimeException(e);
@@ -414,8 +438,7 @@
                 }
             }
 
-            // Leave a breadcrumb behind noting that all the usage stats have been copied to a
-            // versioned backup.
+            // Leave a breadcrumb behind noting that all the usage stats have been moved to a backup
             BufferedWriter writer = null;
             try {
                 writer = new BufferedWriter(new FileWriter(mUpdateBreadcrumb));
@@ -434,18 +457,13 @@
     }
 
     private void continueUpgradeLocked(int version, long token) {
-        // Read all the backed ups for the specified version and rewrite them with the current
-        // version's file format.
-        final FilenameFilter versionedBackupFileFilter = new FilenameFilter() {
-            @Override
-            public boolean accept(File dir, String name) {
-                return name.endsWith("." + Long.toString(token) + "." + Integer.toString(version)
-                        + VERSIONED_BAK_SUFFIX);
-            }
-        };
+        final File backupDir = new File(mBackupsDir, Long.toString(token));
 
+        // Read each file in the backup according to the version and write to the interval
+        // directories in the current versions format
         for (int i = 0; i < mIntervalDirs.length; i++) {
-            File[] files = mIntervalDirs[i].listFiles(versionedBackupFileFilter);
+            final File backedUpInterval = new File(backupDir, mIntervalDirs[i].getName());
+            File[] files = backedUpInterval.listFiles();
             if (files != null) {
                 for (int j = 0; j < files.length; j++) {
                     if (DEBUG) {
@@ -459,34 +477,9 @@
                         readLocked(new AtomicFile(files[j]), stats, version);
                         writeLocked(new AtomicFile(new File(mIntervalDirs[i],
                                 Long.toString(stats.beginTime))), stats, mCurrentVersion);
-                    } catch (IOException e) {
-                        Slog.e(TAG,
-                                "Failed to upgrade versioned backup file : " + files[j].toString());
-                        throw new RuntimeException(e);
-                    }
-                }
-            }
-        }
-    }
-
-    private void removeVersionedBackupFiles() {
-        final FilenameFilter versionedBackupFileFilter = new FilenameFilter() {
-            @Override
-            public boolean accept(File dir, String name) {
-                return name.endsWith(VERSIONED_BAK_SUFFIX);
-            }
-        };
-
-        for (int i = 0; i < mIntervalDirs.length; i++) {
-            File[] files = mIntervalDirs[i].listFiles(versionedBackupFileFilter);
-            if (files != null) {
-                for (int j = 0; j < files.length; j++) {
-                    if (DEBUG) {
-                        Slog.d(TAG,
-                                "Removing " + files[j].toString() + " for interval " + i);
-                    }
-                    if (!files[j].delete()) {
-                        Slog.e(TAG, "Failed to delete file : " + files[j].toString());
+                    } catch (Exception e) {
+                        // This method is called on boot, log the exception and move on
+                        Slog.e(TAG, "Failed to upgrade backup file : " + files[j].toString());
                     }
                 }
             }
@@ -761,7 +754,7 @@
                             }
                         }
                         writeLocked(af, stats);
-                    } catch (IOException e) {
+                    } catch (Exception e) {
                         Slog.e(TAG, "Failed to delete chooser counts from usage stats file", e);
                     }
                 }
@@ -856,6 +849,9 @@
             Slog.e(TAG, "UsageStatsDatabase", e);
             throw e;
         }
+        // If old version, don't bother sanity checking
+        if (version < 4) return;
+
         // STOPSHIP: b/111422946, b/115429334
         // Everything below this comment is sanity check against the new database version.
         // After the new version has soaked for some time the following should removed.
@@ -958,7 +954,7 @@
             sb.append("\nError found in:\n");
             sb.append(file.getBaseFile().getAbsolutePath());
             sb.append("\nPlease go to b/115429334 to help root cause this issue");
-            Slog.wtf(TAG,sb.toString());
+            Slog.wtf(TAG, sb.toString());
         }
     }
 
@@ -1010,40 +1006,53 @@
 
     /* Backup/Restore Code */
     byte[] getBackupPayload(String key) {
+        return getBackupPayload(key, BACKUP_VERSION);
+    }
+
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public byte[] getBackupPayload(String key, int version) {
         synchronized (mLock) {
             ByteArrayOutputStream baos = new ByteArrayOutputStream();
             if (KEY_USAGE_STATS.equals(key)) {
                 prune(System.currentTimeMillis());
                 DataOutputStream out = new DataOutputStream(baos);
                 try {
-                    out.writeInt(BACKUP_VERSION);
+                    out.writeInt(version);
 
                     out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].size());
+
                     for (int i = 0; i < mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].size();
                             i++) {
                         writeIntervalStatsToStream(out,
-                                mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].valueAt(i));
+                                mSortedStatFiles[UsageStatsManager.INTERVAL_DAILY].valueAt(i),
+                                version);
                     }
 
                     out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].size());
                     for (int i = 0; i < mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].size();
                             i++) {
                         writeIntervalStatsToStream(out,
-                                mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].valueAt(i));
+                                mSortedStatFiles[UsageStatsManager.INTERVAL_WEEKLY].valueAt(i),
+                                version);
                     }
 
                     out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].size());
                     for (int i = 0; i < mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].size();
                             i++) {
                         writeIntervalStatsToStream(out,
-                                mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].valueAt(i));
+                                mSortedStatFiles[UsageStatsManager.INTERVAL_MONTHLY].valueAt(i),
+                                version);
                     }
 
                     out.writeInt(mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].size());
                     for (int i = 0; i < mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].size();
                             i++) {
                         writeIntervalStatsToStream(out,
-                                mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].valueAt(i));
+                                mSortedStatFiles[UsageStatsManager.INTERVAL_YEARLY].valueAt(i),
+                                version);
                     }
                     if (DEBUG) Slog.i(TAG, "Written " + baos.size() + " bytes of data");
                 } catch (IOException ioe) {
@@ -1056,7 +1065,11 @@
 
     }
 
-    void applyRestoredPayload(String key, byte[] payload) {
+    /**
+     * @hide
+     */
+    @VisibleForTesting
+    public void applyRestoredPayload(String key, byte[] payload) {
         synchronized (mLock) {
             if (KEY_USAGE_STATS.equals(key)) {
                 // Read stats files for the current device configs
@@ -1084,28 +1097,32 @@
 
                     int fileCount = in.readInt();
                     for (int i = 0; i < fileCount; i++) {
-                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in));
+                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
+                                backupDataVersion);
                         stats = mergeStats(stats, dailyConfigSource);
                         putUsageStats(UsageStatsManager.INTERVAL_DAILY, stats);
                     }
 
                     fileCount = in.readInt();
                     for (int i = 0; i < fileCount; i++) {
-                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in));
+                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
+                                backupDataVersion);
                         stats = mergeStats(stats, weeklyConfigSource);
                         putUsageStats(UsageStatsManager.INTERVAL_WEEKLY, stats);
                     }
 
                     fileCount = in.readInt();
                     for (int i = 0; i < fileCount; i++) {
-                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in));
+                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
+                                backupDataVersion);
                         stats = mergeStats(stats, monthlyConfigSource);
                         putUsageStats(UsageStatsManager.INTERVAL_MONTHLY, stats);
                     }
 
                     fileCount = in.readInt();
                     for (int i = 0; i < fileCount; i++) {
-                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in));
+                        IntervalStats stats = deserializeIntervalStats(getIntervalStatsBytes(in),
+                                backupDataVersion);
                         stats = mergeStats(stats, yearlyConfigSource);
                         putUsageStats(UsageStatsManager.INTERVAL_YEARLY, stats);
                     }
@@ -1132,7 +1149,7 @@
         return beingRestored;
     }
 
-    private void writeIntervalStatsToStream(DataOutputStream out, AtomicFile statsFile)
+    private void writeIntervalStatsToStream(DataOutputStream out, AtomicFile statsFile, int version)
             throws IOException {
         IntervalStats stats = new IntervalStats();
         try {
@@ -1143,7 +1160,7 @@
             return;
         }
         sanitizeIntervalStatsForBackup(stats);
-        byte[] data = serializeIntervalStats(stats);
+        byte[] data = serializeIntervalStats(stats, version);
         out.writeInt(data.length);
         out.write(data);
     }
@@ -1162,26 +1179,26 @@
         if (stats.events != null) stats.events.clear();
     }
 
-    private byte[] serializeIntervalStats(IntervalStats stats) {
+    private byte[] serializeIntervalStats(IntervalStats stats, int version) {
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         DataOutputStream out = new DataOutputStream(baos);
         try {
             out.writeLong(stats.beginTime);
-            writeLocked(out, stats);
-        } catch (IOException ioe) {
+            writeLocked(out, stats, version);
+        } catch (Exception ioe) {
             Slog.d(TAG, "Serializing IntervalStats Failed", ioe);
             baos.reset();
         }
         return baos.toByteArray();
     }
 
-    private IntervalStats deserializeIntervalStats(byte[] data) {
+    private IntervalStats deserializeIntervalStats(byte[] data, int version) {
         ByteArrayInputStream bais = new ByteArrayInputStream(data);
         DataInputStream in = new DataInputStream(bais);
         IntervalStats stats = new IntervalStats();
         try {
             stats.beginTime = in.readLong();
-            readLocked(in, stats);
+            readLocked(in, stats, version);
         } catch (IOException ioe) {
             Slog.d(TAG, "DeSerializing IntervalStats Failed", ioe);
             stats = null;
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 57f1668..9918395 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -20,8 +20,6 @@
 import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull;
 
 import android.app.ActivityManager;
-
-import com.android.server.wm.ActivityTaskManagerInternal;
 import android.app.KeyguardManager;
 import android.app.Notification;
 import android.app.NotificationChannel;
@@ -82,6 +80,7 @@
 import com.android.internal.util.dump.DualDumpOutputStream;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
+import com.android.server.wm.ActivityTaskManagerInternal;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -540,7 +539,8 @@
             // We do not show the USB notification if the primary volume supports mass storage.
             // The legacy mass storage UI will be used instead.
             final StorageManager storageManager = StorageManager.from(mContext);
-            final StorageVolume primary = storageManager.getPrimaryVolume();
+            final StorageVolume primary =
+                    storageManager != null ? storageManager.getPrimaryVolume() : null;
 
             boolean massStorageSupported = primary != null && primary.allowMassStorage();
             mUseUsbNotification = !massStorageSupported && mContext.getResources().getBoolean(
@@ -658,7 +658,19 @@
                 // successfully entered accessory mode
                 String[] accessoryStrings = mUsbDeviceManager.getAccessoryStrings();
                 if (accessoryStrings != null) {
-                    mCurrentAccessory = new UsbAccessory(accessoryStrings);
+                    UsbSerialReader serialReader = new UsbSerialReader(mContext, mSettingsManager,
+                            accessoryStrings[UsbAccessory.SERIAL_STRING]);
+
+                    mCurrentAccessory = new UsbAccessory(
+                            accessoryStrings[UsbAccessory.MANUFACTURER_STRING],
+                            accessoryStrings[UsbAccessory.MODEL_STRING],
+                            accessoryStrings[UsbAccessory.DESCRIPTION_STRING],
+                            accessoryStrings[UsbAccessory.VERSION_STRING],
+                            accessoryStrings[UsbAccessory.URI_STRING],
+                            serialReader);
+
+                    serialReader.setDevice(mCurrentAccessory);
+
                     Slog.d(TAG, "entering USB accessory mode: " + mCurrentAccessory);
                     // defer accessoryAttached if system is not ready
                     if (mBootCompleted) {
@@ -1969,9 +1981,10 @@
      * opens the currently attached USB accessory.
      *
      * @param accessory accessory to be openened.
+     * @param uid Uid of the caller
      */
     public ParcelFileDescriptor openAccessory(UsbAccessory accessory,
-            UsbUserSettingsManager settings) {
+            UsbUserSettingsManager settings, int uid) {
         UsbAccessory currentAccessory = mHandler.getCurrentAccessory();
         if (currentAccessory == null) {
             throw new IllegalArgumentException("no accessory attached");
@@ -1982,7 +1995,7 @@
                     + currentAccessory;
             throw new IllegalArgumentException(error);
         }
-        settings.checkPermission(accessory);
+        settings.checkPermission(accessory, uid);
         return nativeOpenAccessory();
     }
 
diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java
index cf47ad3..613ba00 100644
--- a/services/usb/java/com/android/server/usb/UsbHostManager.java
+++ b/services/usb/java/com/android/server/usb/UsbHostManager.java
@@ -378,13 +378,18 @@
                 return false;
             }
 
-            UsbDevice newDevice = parser.toAndroidUsbDevice();
-            if (newDevice == null) {
+            UsbDevice.Builder newDeviceBuilder = parser.toAndroidUsbDevice();
+            if (newDeviceBuilder == null) {
                 Slog.e(TAG, "Couldn't create UsbDevice object.");
                 // Tracking
                 addConnectionRecord(deviceAddress, ConnectionRecord.CONNECT_BADDEVICE,
                         parser.getRawDescriptors());
             } else {
+                UsbSerialReader serialNumberReader = new UsbSerialReader(mContext, mSettingsManager,
+                        newDeviceBuilder.serialNumber);
+                UsbDevice newDevice = newDeviceBuilder.build(serialNumberReader);
+                serialNumberReader.setDevice(newDevice);
+
                 mDevices.put(deviceAddress, newDevice);
                 Slog.d(TAG, "Added device " + newDevice);
 
diff --git a/services/usb/java/com/android/server/usb/UsbPermissionManager.java b/services/usb/java/com/android/server/usb/UsbPermissionManager.java
index 2c9ee36..dd2f29b 100644
--- a/services/usb/java/com/android/server/usb/UsbPermissionManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPermissionManager.java
@@ -148,11 +148,11 @@
      * Returns true if caller has permission to access the accessory.
      *
      * @param accessory to check permission for
+     * @param uid to check permission for
      * @return {@code true} if caller has permssion
      */
-    boolean hasPermission(@NonNull UsbAccessory accessory) {
+    boolean hasPermission(@NonNull UsbAccessory accessory, int uid) {
         synchronized (mLock) {
-            int uid = Binder.getCallingUid();
             if (uid == Process.SYSTEM_UID || mDisablePermissionDialogs) {
                 return true;
             }
diff --git a/services/usb/java/com/android/server/usb/UsbSerialReader.java b/services/usb/java/com/android/server/usb/UsbSerialReader.java
new file mode 100644
index 0000000..32fc796
--- /dev/null
+++ b/services/usb/java/com/android/server/usb/UsbSerialReader.java
@@ -0,0 +1,117 @@
+/*
+ * 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.usb;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.hardware.usb.IUsbSerialReader;
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbDevice;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+import com.android.internal.util.ArrayUtils;
+
+/**
+ * Allows an app to read the serial number of the {@link UsbDevice}/{@link UsbAccessory} only if
+ * the app has got the permission to do so.
+ */
+class UsbSerialReader extends IUsbSerialReader.Stub {
+    private final @Nullable String mSerialNumber;
+    private final @NonNull Context mContext;
+    private final @NonNull UsbSettingsManager mSettingsManager;
+
+    private Object mDevice;
+
+    /**
+     * Create an new {@link UsbSerialReader}. It is mandatory to call {@link #setDevice(Object)}
+     * immediately after this.
+     *
+     * @param context A context to be used by the reader
+     * @param settingsManager The USB settings manager
+     * @param serialNumber The serial number that might be read
+     */
+    UsbSerialReader(@NonNull Context context, @NonNull UsbSettingsManager settingsManager,
+            @Nullable String serialNumber) {
+        mContext = context;
+        mSettingsManager = settingsManager;
+        mSerialNumber = serialNumber;
+    }
+
+    /**
+     * Set the {@link UsbDevice}/{@link UsbAccessory} the serial number belongs to
+     *
+     * @param device The device/accessory
+     */
+    public void setDevice(@NonNull Object device) {
+        mDevice = device;
+    }
+
+    @Override
+    public String getSerial(String packageName) throws RemoteException {
+        int pid = Binder.getCallingPid();
+        int uid = Binder.getCallingUid();
+
+        if (uid != Process.SYSTEM_UID) {
+            enforcePackageBelongsToUid(uid, packageName);
+
+            int packageTargetSdkVersion;
+            long token = Binder.clearCallingIdentity();
+            try {
+                PackageInfo pkg;
+                try {
+                    pkg = mContext.getPackageManager().getPackageInfo(packageName, 0);
+                } catch (PackageManager.NameNotFoundException e) {
+                    throw new RemoteException("package " + packageName + " cannot be found");
+                }
+                packageTargetSdkVersion = pkg.applicationInfo.targetSdkVersion;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+
+            if (packageTargetSdkVersion >= Build.VERSION_CODES.Q) {
+                if (mContext.checkPermission(android.Manifest.permission.MANAGE_USB, pid, uid)
+                        == PackageManager.PERMISSION_DENIED) {
+                    UsbUserSettingsManager settings = mSettingsManager.getSettingsForUser(
+                            UserHandle.getUserId(uid));
+
+                    if (mDevice instanceof UsbDevice) {
+                        settings.checkPermission((UsbDevice) mDevice, packageName, uid);
+                    } else {
+                        settings.checkPermission((UsbAccessory) mDevice, uid);
+                    }
+                }
+            }
+        }
+
+        return mSerialNumber;
+    }
+
+    private void enforcePackageBelongsToUid(int uid, @NonNull String packageName) {
+        String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
+
+        if (!ArrayUtils.contains(packages, packageName)) {
+            throw new IllegalArgumentException(packageName + " does to belong to the " + uid);
+        }
+    }
+}
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index e92bd74..e0f3685 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -230,42 +230,29 @@
         }
     }
 
-    /**
-     * Check if the calling user is in the same profile group as the {@link #mCurrentUserId
-     * current user}.
-     *
-     * @return Iff the caller is in the current user's profile group
-     */
-    @GuardedBy("mLock")
-    private boolean isCallerInCurrentUserProfileGroupLocked() {
-        int userIdInt = UserHandle.getCallingUserId();
-
-        long ident = clearCallingIdentity();
-        try {
-            return mUserManager.isSameProfileGroup(userIdInt, mCurrentUserId);
-        } finally {
-            restoreCallingIdentity(ident);
-        }
-    }
-
     /* Opens the specified USB device (host mode) */
     @Override
     public ParcelFileDescriptor openDevice(String deviceName, String packageName) {
         ParcelFileDescriptor fd = null;
 
         if (mHostManager != null) {
-            synchronized (mLock) {
-                if (deviceName != null) {
-                    int userIdInt = UserHandle.getCallingUserId();
-                    boolean isCurrentUser = isCallerInCurrentUserProfileGroupLocked();
+            if (deviceName != null) {
+                int uid = Binder.getCallingUid();
+                int user = UserHandle.getUserId(uid);
 
-                    if (isCurrentUser) {
-                        fd = mHostManager.openDevice(deviceName, getSettingsForUser(userIdInt),
-                                packageName, Binder.getCallingUid());
-                    } else {
-                        Slog.w(TAG, "Cannot open " + deviceName + " for user " + userIdInt +
-                               " as user is not active.");
+                long ident = clearCallingIdentity();
+                try {
+                    synchronized (mLock) {
+                        if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) {
+                            fd = mHostManager.openDevice(deviceName, getSettingsForUser(user),
+                                    packageName, uid);
+                        } else {
+                            Slog.w(TAG, "Cannot open " + deviceName + " for user " + user
+                                    + " as user is not active.");
+                        }
                     }
+                } finally {
+                    restoreCallingIdentity(ident);
                 }
             }
         }
@@ -287,17 +274,22 @@
     @Override
     public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
         if (mDeviceManager != null) {
-            int userIdInt = UserHandle.getCallingUserId();
+            int uid = Binder.getCallingUid();
+            int user = UserHandle.getUserId(uid);
 
-            synchronized (mLock) {
-                boolean isCurrentUser = isCallerInCurrentUserProfileGroupLocked();
-
-                if (isCurrentUser) {
-                    return mDeviceManager.openAccessory(accessory, getSettingsForUser(userIdInt));
-                } else {
-                    Slog.w(TAG, "Cannot open " + accessory + " for user " + userIdInt +
-                            " as user is not active.");
+            long ident = clearCallingIdentity();
+            try {
+                synchronized (mLock) {
+                    if (mUserManager.isSameProfileGroup(user, mCurrentUserId)) {
+                        return mDeviceManager.openAccessory(accessory, getSettingsForUser(user),
+                                uid);
+                    } else {
+                        Slog.w(TAG, "Cannot open " + accessory + " for user " + user
+                                + " as user is not active.");
+                    }
                 }
+            } finally {
+                restoreCallingIdentity(ident);
             }
         }
 
@@ -318,8 +310,13 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
 
         UserHandle user = UserHandle.of(userId);
-        mSettingsManager.getSettingsForProfileGroup(user).setDevicePackage(device, packageName,
-                user);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mSettingsManager.getSettingsForProfileGroup(user).setDevicePackage(device, packageName,
+                    user);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
@@ -329,49 +326,93 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
 
         UserHandle user = UserHandle.of(userId);
-        mSettingsManager.getSettingsForProfileGroup(user).setAccessoryPackage(accessory,
-                packageName, user);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mSettingsManager.getSettingsForProfileGroup(user).setAccessoryPackage(accessory,
+                    packageName, user);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
     public boolean hasDevicePermission(UsbDevice device, String packageName) {
-        final int userId = UserHandle.getCallingUserId();
-        return getSettingsForUser(userId).hasPermission(device, packageName,
-                Binder.getCallingUid());
+        final int uid = Binder.getCallingUid();
+        final int userId = UserHandle.getUserId(uid);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return getSettingsForUser(userId).hasPermission(device, packageName, uid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
     public boolean hasAccessoryPermission(UsbAccessory accessory) {
-        final int userId = UserHandle.getCallingUserId();
-        return getSettingsForUser(userId).hasPermission(accessory);
+        final int uid = Binder.getCallingUid();
+        final int userId = UserHandle.getUserId(uid);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return getSettingsForUser(userId).hasPermission(accessory, uid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
     public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) {
-        final int userId = UserHandle.getCallingUserId();
-        getSettingsForUser(userId).requestPermission(device, packageName, pi,
-                Binder.getCallingUid());
+        final int uid = Binder.getCallingUid();
+        final int userId = UserHandle.getUserId(uid);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            getSettingsForUser(userId).requestPermission(device, packageName, pi, uid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
     public void requestAccessoryPermission(
             UsbAccessory accessory, String packageName, PendingIntent pi) {
-        final int userId = UserHandle.getCallingUserId();
-        getSettingsForUser(userId).requestPermission(accessory, packageName, pi);
+        final int uid = Binder.getCallingUid();
+        final int userId = UserHandle.getUserId(uid);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            getSettingsForUser(userId).requestPermission(accessory, packageName, pi, uid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
     public void grantDevicePermission(UsbDevice device, int uid) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
         final int userId = UserHandle.getUserId(uid);
-        getSettingsForUser(userId).grantDevicePermission(device, uid);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            getSettingsForUser(userId).grantDevicePermission(device, uid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
     public void grantAccessoryPermission(UsbAccessory accessory, int uid) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
         final int userId = UserHandle.getUserId(uid);
-        getSettingsForUser(userId).grantAccessoryPermission(accessory, uid);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            getSettingsForUser(userId).grantAccessoryPermission(accessory, uid);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
@@ -381,7 +422,13 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
 
         UserHandle user = UserHandle.of(userId);
-        return mSettingsManager.getSettingsForProfileGroup(user).hasDefaults(packageName, user);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            return mSettingsManager.getSettingsForProfileGroup(user).hasDefaults(packageName, user);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
@@ -391,7 +438,13 @@
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
 
         UserHandle user = UserHandle.of(userId);
-        mSettingsManager.getSettingsForProfileGroup(user).clearDefaults(packageName, user);
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            mSettingsManager.getSettingsForProfileGroup(user).clearDefaults(packageName, user);
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
     }
 
     @Override
diff --git a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java
index fe93399..0121d30 100644
--- a/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbUserSettingsManager.java
@@ -168,19 +168,21 @@
         return mUsbPermissionManager.hasPermission(device, uid);
     }
 
-    public boolean hasPermission(UsbAccessory accessory) {
-        return mUsbPermissionManager.hasPermission(accessory);
+    public boolean hasPermission(UsbAccessory accessory, int uid) {
+        return mUsbPermissionManager.hasPermission(accessory, uid);
     }
 
     public void checkPermission(UsbDevice device, String packageName, int uid) {
         if (!hasPermission(device, packageName, uid)) {
-            throw new SecurityException("User has not given permission to device " + device);
+            throw new SecurityException("User has not given " + uid + "/" + packageName
+                    + " permission to access device " + device.getDeviceName());
         }
     }
 
-    public void checkPermission(UsbAccessory accessory) {
-        if (!hasPermission(accessory)) {
-            throw new SecurityException("User has not given permission to accessory " + accessory);
+    public void checkPermission(UsbAccessory accessory, int uid) {
+        if (!hasPermission(accessory, uid)) {
+            throw new SecurityException("User has not given " + uid + " permission to accessory "
+                    + accessory);
         }
     }
 
@@ -236,9 +238,10 @@
         requestPermissionDialog(device, null, canBeDefault(device, packageName), packageName, pi);
     }
 
-    public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi) {
+    public void requestPermission(UsbAccessory accessory, String packageName, PendingIntent pi,
+            int uid) {
         // respond immediately if permission has already been granted
-        if (hasPermission(accessory)) {
+        if (hasPermission(accessory, uid)) {
             Intent intent = new Intent();
             intent.putExtra(UsbManager.EXTRA_ACCESSORY, accessory);
             intent.putExtra(UsbManager.EXTRA_PERMISSION_GRANTED, true);
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
index e615428..c021101 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java
@@ -271,13 +271,13 @@
     /**
      * @hide
      */
-    public UsbDevice toAndroidUsbDevice() {
+    public UsbDevice.Builder toAndroidUsbDevice() {
         if (mDeviceDescriptor == null) {
             Log.e(TAG, "toAndroidUsbDevice() ERROR - No Device Descriptor");
             return null;
         }
 
-        UsbDevice device = mDeviceDescriptor.toAndroid(this);
+        UsbDevice.Builder device = mDeviceDescriptor.toAndroid(this);
         if (device == null) {
             Log.e(TAG, "toAndroidUsbDevice() ERROR Creating Device");
         }
diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
index fae594a..f50b9cb 100644
--- a/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
+++ b/services/usb/java/com/android/server/usb/descriptors/UsbDeviceDescriptor.java
@@ -135,7 +135,7 @@
     /**
      * @hide
      */
-    public UsbDevice toAndroid(UsbDescriptorParser parser) {
+    public UsbDevice.Builder toAndroid(UsbDescriptorParser parser) {
         if (DEBUG) {
             Log.d(TAG, "toAndroid()");
         }
@@ -152,16 +152,14 @@
             Log.d(TAG, "  versionString:" + versionString + " serialStr:" + serialStr);
         }
 
-        UsbDevice device = new UsbDevice(parser.getDeviceAddr(), mVendorID, mProductID,
-                mDevClass, mDevSubClass,
-                mProtocol, mfgName, prodName,
-                versionString, serialStr);
         UsbConfiguration[] configs = new UsbConfiguration[mConfigDescriptors.size()];
         Log.d(TAG, "  " + configs.length + " configs");
         for (int index = 0; index < mConfigDescriptors.size(); index++) {
             configs[index] = mConfigDescriptors.get(index).toAndroid(parser);
         }
-        device.setConfigurations(configs);
+        UsbDevice.Builder device = new UsbDevice.Builder(parser.getDeviceAddr(), mVendorID,
+                mProductID, mDevClass, mDevSubClass, mProtocol, mfgName, prodName, versionString,
+                configs, serialStr);
 
         return device;
     }
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index bafb0a2..ad2501d 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -566,6 +566,40 @@
         }
     }
 
+    SoundTrigger.RecognitionEvent getGenericModelState(UUID modelId) {
+        synchronized (mLock) {
+            MetricsLogger.count(mContext, "sth_get_generic_model_state", 1);
+            if (modelId == null || mModule == null) {
+                return null;
+            }
+            ModelData modelData = mModelDataMap.get(modelId);
+            if (modelData == null || !modelData.isGenericModel()) {
+                Slog.w(TAG, "GetGenericModelState error: Invalid generic model id:" +
+                        modelId);
+                return null;
+            }
+            if (!modelData.isModelLoaded()) {
+                Slog.i(TAG, "GetGenericModelState: Given generic model is not loaded:" + modelId);
+                return null;
+            }
+            if (!modelData.isModelStarted()) {
+                Slog.i(TAG, "GetGenericModelState: Given generic model is not started:" + modelId);
+                return null;
+            }
+
+            SoundTrigger.RecognitionEvent ret = mModule.getModelState(modelData.getHandle());
+            if (ret == null) {
+                Slog.w(TAG, "GetGenericModelState() call failed");
+            }
+            return ret;
+        }
+    }
+
+    SoundTrigger.RecognitionEvent getKeyphraseModelState(UUID modelId) {
+        Slog.w(TAG, "GetKeyphraseModelState error: Not implemented");
+        return null;
+    }
+
     //---- SoundTrigger.StatusListener methods
     @Override
     public void onRecognition(RecognitionEvent event) {
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 7c22613..d57fcb1 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -434,6 +434,40 @@
             }
             return mSoundTriggerHelper.isRecognitionRequested(parcelUuid.getUuid());
         }
+
+        @Override
+        public SoundTrigger.RecognitionEvent getModelState(ParcelUuid soundModelId) {
+            enforceCallingPermission(Manifest.permission.MANAGE_SOUND_TRIGGER);
+            if (!isInitialized()) return null;
+            if (DEBUG) {
+                Slog.i(TAG, "getModelState(): id = " + soundModelId);
+            }
+
+            synchronized (mLock) {
+                SoundModel soundModel = mLoadedModels.get(soundModelId.getUuid());
+                if (soundModel == null) {
+                    Slog.e(TAG, soundModelId + " is not loaded");
+                    return null;
+                }
+                SoundTrigger.RecognitionEvent ret = null;
+                switch (soundModel.type) {
+                    case SoundModel.TYPE_KEYPHRASE:
+                        ret = mSoundTriggerHelper.getKeyphraseModelState(soundModel.uuid);
+                        break;
+                    case SoundModel.TYPE_GENERIC_SOUND:
+                        ret = mSoundTriggerHelper.getGenericModelState(soundModel.uuid);
+                        break;
+                    default:
+                        Slog.e(TAG, "Unknown model type");
+                        break;
+                }
+                if (ret == null) {
+                    Slog.e(TAG, "Failed to get model state");
+                }
+
+                return ret;
+            }
+        }
     }
 
     /**
diff --git a/startop/iorap/Android.bp b/startop/iorap/Android.bp
new file mode 100644
index 0000000..b3b0900
--- /dev/null
+++ b/startop/iorap/Android.bp
@@ -0,0 +1,28 @@
+// 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_static {
+  name: "libiorap-java",
+
+  aidl: {
+    include_dirs: [
+      "system/iorap/binder",
+    ],
+  },
+
+  srcs: [
+      ":iorap-aidl",
+      "**/*.java",
+  ],
+}
diff --git a/startop/iorap/TEST_MAPPING b/startop/iorap/TEST_MAPPING
new file mode 100644
index 0000000..8c9d4df
--- /dev/null
+++ b/startop/iorap/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+  "presubmit": [
+    {
+      "name": "libiorap-java-tests"
+    }
+  ],
+  "imports": [
+    {
+      "path": "system/iorap"
+    }
+  ]
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java
new file mode 100644
index 0000000..1d38f4c
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java
@@ -0,0 +1,139 @@
+/*
+ * 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.google.android.startop.iorap;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Provide a hint to iorapd that an activity has transitioned state.<br /><br />
+ *
+ * Knowledge of when an activity starts/stops can be used by iorapd to increase system
+ * performance (e.g. by launching perfetto tracing to record an io profile, or by
+ * playing back an ioprofile via readahead) over the long run.<br /><br />
+ *
+ * /@see com.google.android.startop.iorap.IIorap#onActivityHintEvent<br /><br />
+ *
+ * Once an activity hint is in {@link #TYPE_STARTED} it must transition to another type.
+ * All other states could be terminal, see below: <br /><br />
+ *
+ * <pre>
+ *
+ *          ┌──────────────────────────────────────┐
+ *          │                                      ▼
+ *        ┌─────────┐     ╔════════════════╗     ╔═══════════╗
+ *    ──▶ │ STARTED │ ──▶ ║   COMPLETED    ║ ──▶ ║ CANCELLED ║
+ *        └─────────┘     ╚════════════════╝     ╚═══════════╝
+ *                          │
+ *                          │
+ *                          ▼
+ *                        ╔════════════════╗
+ *                        ║ POST_COMPLETED ║
+ *                        ╚════════════════╝
+ *
+ * </pre> <!-- system/iorap/docs/binder/ActivityHint.dot -->
+ *
+ * @hide
+ */
+public class ActivityHintEvent implements Parcelable {
+
+    public static final int TYPE_STARTED = 0;
+    public static final int TYPE_CANCELLED = 1;
+    public static final int TYPE_COMPLETED = 2;
+    public static final int TYPE_POST_COMPLETED = 3;
+    private static final int TYPE_MAX = TYPE_POST_COMPLETED;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
+            TYPE_STARTED,
+            TYPE_CANCELLED,
+            TYPE_COMPLETED,
+            TYPE_POST_COMPLETED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    @Type public final int type;
+    public final ActivityInfo activityInfo;
+
+    public ActivityHintEvent(@Type int type, ActivityInfo activityInfo) {
+        this.type = type;
+        this.activityInfo = activityInfo;
+        checkConstructorArguments();
+    }
+
+    private void checkConstructorArguments() {
+        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
+        Objects.requireNonNull(activityInfo, "activityInfo");
+    }
+
+    @Override
+    public String toString() {
+        return String.format("{type: %d, activityInfo: %s}", type, activityInfo);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof ActivityHintEvent) {
+            return equals((ActivityHintEvent) other);
+        }
+        return false;
+    }
+
+    private boolean equals(ActivityHintEvent other) {
+        return type == other.type &&
+                Objects.equals(activityInfo, other.activityInfo);
+    }
+
+    //<editor-fold desc="Binder boilerplate">
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(type);
+        activityInfo.writeToParcel(out, flags);
+    }
+
+    private ActivityHintEvent(Parcel in) {
+        this.type = in.readInt();
+        this.activityInfo = ActivityInfo.CREATOR.createFromParcel(in);
+        checkConstructorArguments();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<ActivityHintEvent> CREATOR
+            = new Parcelable.Creator<ActivityHintEvent>() {
+        public ActivityHintEvent createFromParcel(Parcel in) {
+            return new ActivityHintEvent(in);
+        }
+
+        public ActivityHintEvent[] newArray(int size) {
+            return new ActivityHintEvent[size];
+        }
+    };
+    //</editor-fold>
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java
new file mode 100644
index 0000000..f47a42c
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java
@@ -0,0 +1,104 @@
+/*
+ * 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.google.android.startop.iorap;
+
+import java.util.Objects;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+/**
+ * Provide minimal information for launched activities to iorap.<br /><br />
+ *
+ * This uniquely identifies a system-wide activity by providing the {@link #packageName} and
+ * {@link #activityName}.
+ *
+ * @see ActivityHintEvent
+ * @see AppIntentEvent
+ *
+ * @hide
+ */
+public class ActivityInfo implements Parcelable {
+
+    /** The name of the package, for example {@code com.android.calculator}. */
+    public final String packageName;
+    /** The name of the activity, for example {@code .activities.activity.MainActivity} */
+    public final String activityName;
+
+    public ActivityInfo(String packageName, String activityName) {
+        this.packageName = packageName;
+        this.activityName = activityName;
+
+        checkConstructorArguments();
+    }
+
+    private void checkConstructorArguments() {
+        Objects.requireNonNull(packageName, "packageName");
+        Objects.requireNonNull(activityName, "activityName");
+    }
+
+    @Override
+    public String toString() {
+        return String.format("{packageName: %s, activityName: %s}", packageName, activityName);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof ActivityInfo) {
+            return equals((ActivityInfo) other);
+        }
+        return false;
+    }
+
+    private boolean equals(ActivityInfo other) {
+        return Objects.equals(packageName, other.packageName) &&
+                Objects.equals(activityName, other.activityName);
+    }
+
+    //<editor-fold desc="Binder boilerplate">
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(packageName);
+        out.writeString(activityName);
+    }
+
+    private ActivityInfo(Parcel in) {
+        packageName = in.readString();
+        activityName = in.readString();
+
+        checkConstructorArguments();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<ActivityInfo> CREATOR
+            = new Parcelable.Creator<ActivityInfo>() {
+        public ActivityInfo createFromParcel(Parcel in) {
+            return new ActivityInfo(in);
+        }
+
+        public ActivityInfo[] newArray(int size) {
+            return new ActivityInfo[size];
+        }
+    };
+    //</editor-fold>
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java
new file mode 100644
index 0000000..1cd37b5
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java
@@ -0,0 +1,138 @@
+/*
+ * 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.google.android.startop.iorap;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Notifications for iorapd specifying when a system-wide intent defaults change.<br /><br />
+ *
+ * Intent defaults provide a mechanism for an app to register itself as an automatic handler.
+ * For example the camera app might be registered as the default handler for
+ * {@link android.provider.MediaStore#INTENT_ACTION_STILL_IMAGE_CAMERA} intent. Subsequently,
+ * if an arbitrary other app requests for a still image camera photo to be taken, the system
+ * will launch the respective default camera app to be launched to handle that request.<br /><br />
+ *
+ * In some cases iorapd might need to know default intents, e.g. for boot-time pinning of
+ * applications that resolve from the default intent. If the application would now be resolved
+ * differently, iorapd would unpin the old application and pin the new application.<br /><br />
+ *
+ * @hide
+ */
+public class AppIntentEvent implements Parcelable {
+
+    /** @see android.content.Intent#CATEGORY_DEFAULT */
+    public static final int TYPE_DEFAULT_INTENT_CHANGED = 0;
+    private static final int TYPE_MAX = 0;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
+            TYPE_DEFAULT_INTENT_CHANGED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    @Type public final int type;
+
+    public final ActivityInfo oldActivityInfo;
+    public final ActivityInfo newActivityInfo;
+
+    // TODO: Probably need the corresponding action here as well.
+
+    public static AppIntentEvent createDefaultIntentChanged(ActivityInfo oldActivityInfo,
+            ActivityInfo newActivityInfo) {
+        return new AppIntentEvent(TYPE_DEFAULT_INTENT_CHANGED, oldActivityInfo,
+                newActivityInfo);
+    }
+
+    private AppIntentEvent(@Type int type, ActivityInfo oldActivityInfo,
+            ActivityInfo newActivityInfo) {
+        this.type = type;
+        this.oldActivityInfo = oldActivityInfo;
+        this.newActivityInfo = newActivityInfo;
+
+        checkConstructorArguments();
+    }
+
+    private void checkConstructorArguments() {
+        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
+        Objects.requireNonNull(oldActivityInfo, "oldActivityInfo");
+        Objects.requireNonNull(oldActivityInfo, "newActivityInfo");
+    }
+
+    @Override
+    public String toString() {
+        return String.format("{oldActivityInfo: %s, newActivityInfo: %s}", oldActivityInfo,
+                newActivityInfo);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof AppIntentEvent) {
+            return equals((AppIntentEvent) other);
+        }
+        return false;
+    }
+
+    private boolean equals(AppIntentEvent other) {
+        return type == other.type &&
+                Objects.equals(oldActivityInfo, other.oldActivityInfo) &&
+                Objects.equals(newActivityInfo, other.newActivityInfo);
+    }
+
+    //<editor-fold desc="Binder boilerplate">
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(type);
+        oldActivityInfo.writeToParcel(out, flags);
+        newActivityInfo.writeToParcel(out, flags);
+    }
+
+    private AppIntentEvent(Parcel in) {
+        this.type = in.readInt();
+        this.oldActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
+        this.newActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
+
+        checkConstructorArguments();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<AppIntentEvent> CREATOR
+            = new Parcelable.Creator<AppIntentEvent>() {
+        public AppIntentEvent createFromParcel(Parcel in) {
+            return new AppIntentEvent(in);
+        }
+
+        public AppIntentEvent[] newArray(int size) {
+            return new AppIntentEvent[size];
+        }
+    };
+    //</editor-fold>
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java b/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java
new file mode 100644
index 0000000..34aedd7
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.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.google.android.startop.iorap;
+
+/**
+ * Convenience short-hand to throw {@link IllegalAccessException} when the arguments
+ * are out-of-range.
+ */
+public class CheckHelpers {
+    /** @throws IllegalAccessException if {@param type} is not in {@code [0..maxValue]} */
+    public static void checkTypeInRange(int type, int maxValue) {
+        if (type < 0) {
+            throw new IllegalArgumentException(
+                    String.format("type must be non-negative (value=%d)", type));
+        }
+        if (type > maxValue) {
+            throw new IllegalArgumentException(
+                    String.format("type out of range (value=%d, max=%d)", type, maxValue));
+        }
+    }
+
+    /** @throws IllegalAccessException if {@param state} is not in {@code [0..maxValue]} */
+    public static void checkStateInRange(int state, int maxValue) {
+        if (state < 0) {
+            throw new IllegalArgumentException(
+                    String.format("state must be non-negative (value=%d)", state));
+        }
+        if (state > maxValue) {
+            throw new IllegalArgumentException(
+                    String.format("state out of range (value=%d, max=%d)", state, maxValue));
+        }
+    }
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java b/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java
new file mode 100644
index 0000000..aa4eea7
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java
@@ -0,0 +1,131 @@
+/*
+ * 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.google.android.startop.iorap;
+
+import android.annotation.NonNull;
+import android.os.Parcelable;
+import android.os.Parcel;
+import android.net.Uri;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Forward package manager events to iorapd. <br /><br />
+ *
+ * Knowing when packages are modified by the system are a useful tidbit to help with performance:
+ * for example when a package is replaced, it could be a hint used to invalidate any collected
+ * io profiles used for prefetching or pinning.
+ *
+ * @hide
+ */
+public class PackageEvent implements Parcelable {
+
+    /** @see android.content.Intent#ACTION_PACKAGE_REPLACED */
+    public static final int TYPE_REPLACED = 0;
+    private static final int TYPE_MAX = 0;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
+            TYPE_REPLACED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    @Type public final int type;
+
+    /** The path that a package is installed in, for example {@code /data/app/.../base.apk}. */
+    public final Uri packageUri;
+    /** The name of the package, for example {@code com.android.calculator}. */
+    public final String packageName;
+
+    @NonNull
+    public static PackageEvent createReplaced(Uri packageUri, String packageName) {
+        return new PackageEvent(TYPE_REPLACED, packageUri, packageName);
+    }
+
+    private PackageEvent(@Type int type, Uri packageUri, String packageName) {
+        this.type = type;
+        this.packageUri = packageUri;
+        this.packageName = packageName;
+
+        checkConstructorArguments();
+    }
+
+    private void checkConstructorArguments() {
+        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
+        Objects.requireNonNull(packageUri, "packageUri");
+        Objects.requireNonNull(packageName, "packageName");
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof PackageEvent) {
+            return equals((PackageEvent) other);
+        }
+        return false;
+    }
+
+    private boolean equals(PackageEvent other) {
+        return type == other.type &&
+                Objects.equals(packageUri, other.packageUri) &&
+                Objects.equals(packageName, other.packageName);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("{packageUri: %s, packageName: %s}", packageUri, packageName);
+    }
+
+    //<editor-fold desc="Binder boilerplate">
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(type);
+        packageUri.writeToParcel(out, flags);
+        out.writeString(packageName);
+    }
+
+    private PackageEvent(Parcel in) {
+        this.type = in.readInt();
+        this.packageUri = Uri.CREATOR.createFromParcel(in);
+        this.packageName = in.readString();
+
+        checkConstructorArguments();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<PackageEvent> CREATOR
+            = new Parcelable.Creator<PackageEvent>() {
+        public PackageEvent createFromParcel(Parcel in) {
+            return new PackageEvent(in);
+        }
+
+        public PackageEvent[] newArray(int size) {
+            return new PackageEvent[size];
+        }
+    };
+    //</editor-fold>
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java b/startop/iorap/src/com/google/android/startop/iorap/RequestId.java
new file mode 100644
index 0000000..2c79319
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/RequestId.java
@@ -0,0 +1,120 @@
+/*
+ * 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.google.android.startop.iorap;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import android.annotation.NonNull;
+
+/**
+ * Uniquely identify an {@link com.google.android.startop.iorap.IIorap} method invocation,
+ * used for asynchronous callbacks by the server. <br /><br />
+ *
+ * As all system server binder calls must be {@code oneway}, this means all invocations
+ * into {@link com.google.android.startop.iorap.IIorap} are non-blocking. The request ID
+ * exists to associate all calls with their respective callbacks in
+ * {@link com.google.android.startop.iorap.ITaskListener}.
+ *
+ * @see com.google.android.startop.iorap.IIorap
+ *
+ * @hide
+ */
+public class RequestId implements Parcelable {
+
+    public final long requestId;
+
+    private static Object mLock = new Object();
+    private static long mNextRequestId = 0;
+
+    /**
+     * Create a monotonically increasing request ID.<br /><br />
+     *
+     * It is invalid to re-use the same request ID for multiple method calls on
+     * {@link com.google.android.startop.iorap.IIorap}; a new request ID must be created
+     * each time.
+     */
+    @NonNull public static RequestId nextValueForSequence() {
+        long currentRequestId;
+        synchronized (mLock) {
+            currentRequestId = mNextRequestId;
+            ++mNextRequestId;
+        }
+        return new RequestId(currentRequestId);
+    }
+
+    private RequestId(long requestId) {
+        this.requestId = requestId;
+
+        checkConstructorArguments();
+    }
+
+    private void checkConstructorArguments() {
+        if (requestId < 0) {
+            throw new IllegalArgumentException("request id must be non-negative");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return String.format("{requestId: %ld}", requestId);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof RequestId) {
+            return equals((RequestId) other);
+        }
+        return false;
+    }
+
+    private boolean equals(RequestId other) {
+        return requestId == other.requestId;
+    }
+
+
+    //<editor-fold desc="Binder boilerplate">
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(requestId);
+    }
+
+    private RequestId(Parcel in) {
+        requestId = in.readLong();
+
+        checkConstructorArguments();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<RequestId> CREATOR
+            = new Parcelable.Creator<RequestId>() {
+        public RequestId createFromParcel(Parcel in) {
+            return new RequestId(in);
+        }
+
+        public RequestId[] newArray(int size) {
+            return new RequestId[size];
+        }
+    };
+    //</editor-fold>
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java
new file mode 100644
index 0000000..75d47f9
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java
@@ -0,0 +1,109 @@
+/*
+ * 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.google.android.startop.iorap;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Forward system service events to iorapd.
+ *
+ * @see com.android.server.SystemService
+ *
+ * @hide
+ */
+public class SystemServiceEvent implements Parcelable {
+
+    /** @see com.android.server.SystemService#onBootPhase */
+    public static final int TYPE_BOOT_PHASE = 0;
+    /** @see com.android.server.SystemService#onStart */
+    public static final int TYPE_START = 1;
+    private static final int TYPE_MAX = TYPE_START;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
+            TYPE_BOOT_PHASE,
+            TYPE_START,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    @Type public final int type;
+
+    // TODO: do we want to pass the exact build phase enum?
+
+    public SystemServiceEvent(@Type int type) {
+        this.type = type;
+        checkConstructorArguments();
+    }
+
+    private void checkConstructorArguments() {
+        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("{type: %d}", type);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof SystemServiceEvent) {
+            return equals((SystemServiceEvent) other);
+        }
+        return false;
+    }
+
+    private boolean equals(SystemServiceEvent other) {
+        return type == other.type;
+    }
+
+    //<editor-fold desc="Binder boilerplate">
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(type);
+    }
+
+    private SystemServiceEvent(Parcel in) {
+        this.type = in.readInt();
+        checkConstructorArguments();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<SystemServiceEvent> CREATOR
+            = new Parcelable.Creator<SystemServiceEvent>() {
+        public SystemServiceEvent createFromParcel(Parcel in) {
+            return new SystemServiceEvent(in);
+        }
+
+        public SystemServiceEvent[] newArray(int size) {
+            return new SystemServiceEvent[size];
+        }
+    };
+    //</editor-fold>
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java
new file mode 100644
index 0000000..b77c03c
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java
@@ -0,0 +1,127 @@
+/*
+ * 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.google.android.startop.iorap;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Forward user events to iorapd.<br /><br />
+ *
+ * Knowledge of the logged-in user is reserved to be used to set-up appropriate policies
+ * by iorapd (e.g. to handle user default pinned applications changing).
+ *
+ * @see com.android.server.SystemService
+ *
+ * @hide
+ */
+public class SystemServiceUserEvent implements Parcelable {
+
+    /** @see com.android.server.SystemService#onStartUser */
+    public static final int TYPE_START_USER = 0;
+    /** @see com.android.server.SystemService#onUnlockUser */
+    public static final int TYPE_UNLOCK_USER = 1;
+    /** @see com.android.server.SystemService#onSwitchUser*/
+    public static final int TYPE_SWITCH_USER = 2;
+    /** @see com.android.server.SystemService#onStopUser */
+    public static final int TYPE_STOP_USER = 3;
+    /** @see com.android.server.SystemService#onCleanupUser */
+    public static final int TYPE_CLEANUP_USER = 4;
+    private static final int TYPE_MAX = TYPE_CLEANUP_USER;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
+            TYPE_START_USER,
+            TYPE_UNLOCK_USER,
+            TYPE_SWITCH_USER,
+            TYPE_STOP_USER,
+            TYPE_CLEANUP_USER,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    @Type public final int type;
+    public final int userHandle;
+
+    public SystemServiceUserEvent(@Type int type, int userHandle) {
+        this.type = type;
+        this.userHandle = userHandle;
+        checkConstructorArguments();
+    }
+
+    private void checkConstructorArguments() {
+        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
+        if (userHandle < 0) {
+            throw new IllegalArgumentException("userHandle must be non-negative");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return String.format("{type: %d, userHandle: %d}", type, userHandle);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof SystemServiceUserEvent) {
+            return equals((SystemServiceUserEvent) other);
+        }
+        return false;
+    }
+
+    private boolean equals(SystemServiceUserEvent other) {
+        return type == other.type &&
+                userHandle == other.userHandle;
+    }
+
+    //<editor-fold desc="Binder boilerplate">
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(type);
+        out.writeInt(userHandle);
+    }
+
+    private SystemServiceUserEvent(Parcel in) {
+        this.type = in.readInt();
+        this.userHandle = in.readInt();
+        checkConstructorArguments();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<SystemServiceUserEvent> CREATOR
+            = new Parcelable.Creator<SystemServiceUserEvent>() {
+        public SystemServiceUserEvent createFromParcel(Parcel in) {
+            return new SystemServiceUserEvent(in);
+        }
+
+        public SystemServiceUserEvent[] newArray(int size) {
+            return new SystemServiceUserEvent[size];
+        }
+    };
+    //</editor-fold>
+}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java b/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java
new file mode 100644
index 0000000..b5fd6d8
--- /dev/null
+++ b/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java
@@ -0,0 +1,130 @@
+/*
+ * 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.google.android.startop.iorap;
+
+import android.os.Parcelable;
+import android.os.Parcel;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Result data accompanying a request for {@link com.google.android.startop.iorap.ITaskListener}
+ * callbacks.<br /><br />
+ *
+ * Following {@link com.google.android.startop.iorap.IIorap} method invocation,
+ * iorapd will issue in-order callbacks for that corresponding {@link RequestId}.<br /><br />
+ *
+ * State transitions are as follows: <br /><br />
+ *
+ * <pre>
+ *          ┌─────────────────────────────┐
+ *          │                             ▼
+ *        ┌───────┐     ┌─────────┐     ╔═══════════╗
+ *    ──▶ │ BEGAN │ ──▶ │ ONGOING │ ──▶ ║ COMPLETED ║
+ *        └───────┘     └─────────┘     ╚═══════════╝
+ *          │             │
+ *          │             │
+ *          ▼             │
+ *        ╔═══════╗       │
+ *    ──▶ ║ ERROR ║ ◀─────┘
+ *        ╚═══════╝
+ *
+ * </pre> <!-- system/iorap/docs/binder/TaskResult.dot -->
+ *
+ * @hide
+ */
+public class TaskResult implements Parcelable {
+
+    public static final int STATE_BEGAN = 0;
+    public static final int STATE_ONGOING = 1;
+    public static final int STATE_COMPLETED = 2;
+    public static final int STATE_ERROR = 3;
+    private static final int STATE_MAX = STATE_ERROR;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "STATE_" }, value = {
+            STATE_BEGAN,
+            STATE_ONGOING,
+            STATE_COMPLETED,
+            STATE_ERROR,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface State {}
+
+    @State public final int state;
+
+    @Override
+    public String toString() {
+        return String.format("{state: %d}", state);
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (other instanceof TaskResult) {
+            return equals((TaskResult) other);
+        }
+        return false;
+    }
+
+    private boolean equals(TaskResult other) {
+        return state == other.state;
+    }
+
+    public TaskResult(@State int state) {
+        this.state = state;
+
+        checkConstructorArguments();
+    }
+
+    private void checkConstructorArguments() {
+        CheckHelpers.checkStateInRange(state, STATE_MAX);
+    }
+
+    //<editor-fold desc="Binder boilerplate">
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(state);
+    }
+
+    private TaskResult(Parcel in) {
+        state = in.readInt();
+
+        checkConstructorArguments();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public static final Parcelable.Creator<TaskResult> CREATOR
+            = new Parcelable.Creator<TaskResult>() {
+        public TaskResult createFromParcel(Parcel in) {
+            return new TaskResult(in);
+        }
+
+        public TaskResult[] newArray(int size) {
+            return new TaskResult[size];
+        }
+    };
+    //</editor-fold>
+}
diff --git a/startop/iorap/tests/Android.bp b/startop/iorap/tests/Android.bp
new file mode 100644
index 0000000..7605784
--- /dev/null
+++ b/startop/iorap/tests/Android.bp
@@ -0,0 +1,40 @@
+// 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.
+
+// TODO: once b/80095087 is fixed, rewrite this back to android_test
+java_library {
+    name: "libiorap-java-test-lib",
+    srcs: ["src/**/*.kt"],
+
+    static_libs: [
+      // non-test dependencies
+      "libiorap-java",
+      // test android dependencies
+      "platform-test-annotations",
+      "android-support-test",
+      // test framework dependencies
+      "mockito-target-inline-minus-junit4",
+      // "mockito-target-minus-junit4",
+        // Mockito also requires JNI (see Android.mk)
+        // and android:debuggable=true (see AndroidManifest.xml)
+      "truth-prebuilt",
+    ],
+
+    // sdk_version: "current",
+    // certificate: "platform",
+
+    libs: ["android.test.base", "android.test.runner"],
+
+    // test_suites: ["device-tests"],
+}
diff --git a/startop/iorap/tests/Android.mk b/startop/iorap/tests/Android.mk
new file mode 100644
index 0000000..1b2aa46
--- /dev/null
+++ b/startop/iorap/tests/Android.mk
@@ -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.
+
+# android_test does not support JNI libraries
+# TODO: once b/80095087 is fixed, rewrite this back to android_test
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JACK_FLAGS := --multi-dex native
+LOCAL_DX_FLAGS := --multi-dex
+
+LOCAL_PACKAGE_NAME := libiorap-java-tests
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    libiorap-java-test-lib
+
+LOCAL_MULTILIB := both
+
+LOCAL_JNI_SHARED_LIBRARIES := \
+    libdexmakerjvmtiagent \
+    libstaticjvmtiagent \
+    libmultiplejvmtiagentsinterferenceagent
+
+LOCAL_JAVA_LIBRARIES := \
+    android.test.base \
+    android.test.runner
+
+# Use private APIs
+LOCAL_CERTIFICATE := platform
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
+include $(BUILD_PACKAGE)
diff --git a/startop/iorap/tests/AndroidManifest.xml b/startop/iorap/tests/AndroidManifest.xml
new file mode 100644
index 0000000..99f4add
--- /dev/null
+++ b/startop/iorap/tests/AndroidManifest.xml
@@ -0,0 +1,37 @@
+<?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.
+-->
+<!--suppress AndroidUnknownAttribute -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.google.android.startop.iorap.tests"
+    android:sharedUserId="com.google.android.startop.iorap.tests"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <!--suppress AndroidDomInspection -->
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.google.android.startop.iorap.tests" />
+
+      <!--
+       'debuggable=true' is required to properly load mockito jvmti dependencies,
+         otherwise it gives the following error at runtime:
+
+       Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
+       Plugin was loaded too late to change runtime state to DEBUGGABLE. -->
+    <application android:debuggable="true">
+        <uses-library android:name="android.test.runner" />
+    </application>
+</manifest>
diff --git a/startop/iorap/tests/AndroidTest.xml b/startop/iorap/tests/AndroidTest.xml
new file mode 100644
index 0000000..f83a16e
--- /dev/null
+++ b/startop/iorap/tests/AndroidTest.xml
@@ -0,0 +1,41 @@
+<?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 libiorap-java-tests.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-instrumentation" />
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="libiorap-java-tests.apk" />
+    </target_preparer>
+
+    <!--
+      Our IIorapIntegrationTest.kt requires setlinux to be disabled:
+      it connects to the iorapd binder service but this requires selinux permissions:
+
+      avc:  denied  { find } for service=iorapd pid=2738 uid=10050
+        scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:iorapd_service:s0
+        tclass=service_manager permissive=0
+    -->
+    <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer">
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.google.android.startop.iorap.tests" />
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+    </test>
+</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
new file mode 100644
index 0000000..16dcbe2
--- /dev/null
+++ b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
@@ -0,0 +1,121 @@
+/*
+ * 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.google.android.startop.iorap
+
+import android.net.Uri
+import android.os.ServiceManager
+import android.support.test.filters.MediumTest
+import org.junit.Test
+import org.junit.Ignore
+import org.mockito.Mockito.*
+
+// @Ignore("Test is disabled until iorapd is added to init and there's selinux policies for it")
+@MediumTest
+class IIorapIntegrationTest {
+    /**
+     * @throws ServiceManager.ServiceNotFoundException if iorapd service could not be found
+     */
+    private val iorapService : IIorap by lazy {
+        // TODO: connect to 'iorapd.stub' which doesn't actually do any work other than reply.
+        IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"))
+
+        // Use 'adb shell setenforce 0' otherwise this whole test fails,
+        // because the servicemanager is not allowed to hand out the binder token for iorapd.
+
+        // TODO: implement the selinux policies for iorapd.
+    }
+
+    // A dummy binder stub implementation is required to use with mockito#spy.
+    // Mockito overrides the methods at runtime and tracks how methods were invoked.
+    open class DummyTaskListener : ITaskListener.Stub()  {
+        // Note: make parameters nullable to avoid the kotlin IllegalStateExceptions
+        // from using the mockito matchers (eq, argThat, etc).
+        override fun onProgress(requestId: RequestId?, result: TaskResult?) {
+        }
+
+        override fun onComplete(requestId: RequestId?, result: TaskResult?) {
+        }
+    }
+
+    private fun testAnyMethod(func : (RequestId) -> Unit) {
+        val taskListener = spy(DummyTaskListener())!!
+
+        try {
+            iorapService.setTaskListener(taskListener)
+            // Note: Binder guarantees total order for oneway messages sent to the same binder
+            // interface, so we don't need any additional blocking here before sending later calls.
+
+            // Every new method call should have a unique request id.
+            val requestId = RequestId.nextValueForSequence()!!
+
+            // Apply the specific function under test.
+            func(requestId)
+
+            // Typical mockito behavior is to allow any-order callbacks, but we want to test order.
+            val inOrder = inOrder(taskListener)
+
+            // The "stub" behavior of iorapd is that every request immediately gets a response of
+            //   BEGAN,ONGOING,COMPLETED
+            inOrder.verify(taskListener, timeout(100)).
+                  onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN })
+            inOrder.verify(taskListener, timeout(100)).
+                  onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING })
+            inOrder.verify(taskListener, timeout(100)).
+                  onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED })
+            inOrder.verifyNoMoreInteractions()
+
+        } finally {
+            // iorapService.setTaskListener(null)
+            // FIXME: null is broken, C++ side sees a non-null object.
+        }
+    }
+
+    @Test
+    fun testOnPackageEvent() {
+        /*
+        testAnyMethod { requestId : RequestId ->
+            iorapService.onPackageEvent(requestId,
+                    PackageEvent.createReplaced(
+                            Uri.parse("https://www.google.com"), "com.fake.package"))
+        }
+        */
+        // FIXME: Broken for some reason. C++ side never sees this call.
+    }
+
+    @Test
+    fun testOnAppIntentEvent() {
+        testAnyMethod { requestId : RequestId ->
+            iorapService.onAppIntentEvent(requestId, AppIntentEvent.createDefaultIntentChanged(
+                    ActivityInfo("dont care", "dont care"),
+                    ActivityInfo("dont care 2", "dont care 2")))
+        }
+    }
+
+    @Test
+    fun testOnSystemServiceEvent() {
+        testAnyMethod { requestId : RequestId ->
+            iorapService.onSystemServiceEvent(requestId,
+                    SystemServiceEvent(SystemServiceEvent.TYPE_START))
+        }
+    }
+
+    @Test
+    fun testOnSystemServiceUserEvent() {
+        testAnyMethod { requestId : RequestId ->
+            iorapService.onSystemServiceUserEvent(requestId,
+                    SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER,0))
+        }
+    }
+}
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
new file mode 100644
index 0000000..4abbb3e
--- /dev/null
+++ b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
@@ -0,0 +1,140 @@
+/*
+ * 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.google.android.startop.iorap
+
+import android.net.Uri
+import android.os.Parcel
+import android.os.Parcelable
+import android.support.test.filters.SmallTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import com.google.common.truth.Truth.assertThat
+import org.junit.runners.Parameterized
+
+/**
+ * Basic unit tests to ensure that all of the [Parcelable]s in [com.google.android.startop.iorap]
+ * have a valid-conforming interface implementation.
+ */
+@SmallTest
+@RunWith(Parameterized::class)
+class ParcelablesTest<T : Parcelable>(private val inputData : InputData<T>) {
+    companion object {
+        private val initialRequestId = RequestId.nextValueForSequence()!!
+
+        @JvmStatic
+        @Parameterized.Parameters
+        fun data() = listOf(
+                InputData(
+                        newActivityInfo(),
+                        newActivityInfo(),
+                        ActivityInfo("some package", "some other activity")),
+                InputData(
+                        ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()),
+                        ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()),
+                        ActivityHintEvent(ActivityHintEvent.TYPE_POST_COMPLETED,
+                                newActivityInfo())),
+                InputData(
+                        AppIntentEvent.createDefaultIntentChanged(newActivityInfo(),
+                                newActivityInfoOther()),
+                        AppIntentEvent.createDefaultIntentChanged(newActivityInfo(),
+                                newActivityInfoOther()),
+                        AppIntentEvent.createDefaultIntentChanged(newActivityInfoOther(),
+                                newActivityInfo())),
+                InputData(
+                        PackageEvent.createReplaced(newUri(), "some package"),
+                        PackageEvent.createReplaced(newUri(), "some package"),
+                        PackageEvent.createReplaced(newUri(), "some other package")
+                ),
+                InputData(initialRequestId, cloneRequestId(initialRequestId),
+                        RequestId.nextValueForSequence()),
+                InputData(
+                        SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE),
+                        SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE),
+                        SystemServiceEvent(SystemServiceEvent.TYPE_START)),
+                InputData(
+                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345),
+                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345),
+                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_CLEANUP_USER, 12345)),
+                InputData(
+                        TaskResult(TaskResult.STATE_COMPLETED),
+                        TaskResult(TaskResult.STATE_COMPLETED),
+                        TaskResult(TaskResult.STATE_ONGOING))
+        )
+
+        private fun newActivityInfo() : ActivityInfo {
+            return ActivityInfo("some package", "some activity")
+        }
+
+        private fun newActivityInfoOther() : ActivityInfo {
+            return ActivityInfo("some package 2", "some activity 2")
+        }
+
+        private fun newUri() : Uri {
+            return Uri.parse("https://www.google.com")
+        }
+
+        private fun cloneRequestId(requestId: RequestId) : RequestId {
+            val constructor = requestId::class.java.declaredConstructors[0]
+            constructor.isAccessible = true
+            return constructor.newInstance(requestId.requestId) as RequestId
+        }
+    }
+
+    /**
+     * Test for [Object.equals] implementation.
+     */
+    @Test
+    fun testEquality() {
+        assertThat(inputData.valid).isEqualTo(inputData.valid)
+        assertThat(inputData.valid).isEqualTo(inputData.validCopy)
+        assertThat(inputData.valid).isNotEqualTo(inputData.validOther)
+    }
+
+    /**
+     * Test for [Parcelable] implementation.
+     */
+    @Test
+    fun testParcelRoundTrip() {
+        // calling writeToParcel and then T::CREATOR.createFromParcel would return the same data.
+        val assertParcels = { it : T, data : InputData<T> ->
+            val parcel = Parcel.obtain()
+            it.writeToParcel(parcel, 0)
+            parcel.setDataPosition(0) // future reads will see all previous writes.
+            assertThat(it).isEqualTo(data.createFromParcel(parcel))
+            parcel.recycle()
+        }
+
+        assertParcels(inputData.valid, inputData)
+        assertParcels(inputData.validCopy, inputData)
+        assertParcels(inputData.validOther, inputData)
+    }
+
+    data class InputData<T : Parcelable>(val valid : T, val validCopy : T, val validOther : T) {
+        val kls = valid.javaClass
+        init {
+            assertThat(valid).isNotSameAs(validCopy)
+            // Don't use isInstanceOf because of phantom warnings in intellij about Class!
+            assertThat(validCopy.javaClass).isEqualTo(valid.javaClass)
+            assertThat(validOther.javaClass).isEqualTo(valid.javaClass)
+        }
+
+        fun createFromParcel(parcel : Parcel) : T {
+            val field  = kls.getDeclaredField("CREATOR")
+            val creator = field.get(null) as Parcelable.Creator<T>
+
+            return creator.createFromParcel(parcel)
+        }
+    }
+}
diff --git a/startop/tools/view_compiler/Android.bp b/startop/tools/view_compiler/Android.bp
index c3e9184..3681529 100644
--- a/startop/tools/view_compiler/Android.bp
+++ b/startop/tools/view_compiler/Android.bp
@@ -14,19 +14,30 @@
 // limitations under the License.
 //
 
+cc_defaults {
+    name: "viewcompiler_defaults",
+    shared_libs: [
+        "libdexfile",
+        "slicer",
+    ],
+}
+
 cc_library_host_static {
     name: "libviewcompiler",
+    defaults: ["viewcompiler_defaults"],
     srcs: [
+        "dex_builder.cc",
         "java_lang_builder.cc",
         "util.cc",
     ],
     static_libs: [
-        "libbase"
-    ]
+        "libbase",
+    ],
 }
 
 cc_binary_host {
     name: "viewcompiler",
+    defaults: ["viewcompiler_defaults"],
     srcs: [
         "main.cc",
     ],
@@ -40,10 +51,12 @@
 
 cc_test_host {
     name: "view-compiler-tests",
+    defaults: ["viewcompiler_defaults"],
     srcs: [
+        "dex_builder_test.cc",
         "util_test.cc",
     ],
     static_libs: [
         "libviewcompiler",
-    ]
+    ],
 }
diff --git a/startop/tools/view_compiler/dex_builder.cc b/startop/tools/view_compiler/dex_builder.cc
new file mode 100644
index 0000000..7a9f41f
--- /dev/null
+++ b/startop/tools/view_compiler/dex_builder.cc
@@ -0,0 +1,214 @@
+/*
+ * 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 "dex_builder.h"
+
+#include "dex/descriptors_names.h"
+#include "dex/dex_instruction.h"
+
+#include <fstream>
+#include <memory>
+
+namespace startop {
+namespace dex {
+
+using std::shared_ptr;
+using std::string;
+
+using art::Instruction;
+using ::dex::kAccPublic;
+
+const TypeDescriptor TypeDescriptor::Int() { return TypeDescriptor{"I"}; };
+const TypeDescriptor TypeDescriptor::Void() { return TypeDescriptor{"V"}; };
+
+namespace {
+// From https://source.android.com/devices/tech/dalvik/dex-format#dex-file-magic
+constexpr uint8_t kDexFileMagic[]{0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x38, 0x00};
+
+// Strings lengths can be 32 bits long, but encoded as LEB128 this can take up to five bytes.
+constexpr size_t kMaxEncodedStringLength{5};
+
+}  // namespace
+
+void* TrackingAllocator::Allocate(size_t size) {
+  std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
+  void* raw_buffer = buffer.get();
+  allocations_[raw_buffer] = std::move(buffer);
+  return raw_buffer;
+}
+
+void TrackingAllocator::Free(void* ptr) { allocations_.erase(allocations_.find(ptr)); }
+
+// Write out a DEX file that is basically:
+//
+// package dextest;
+// public class DexTest {
+//     public static int foo() { return 5; }
+// }
+void WriteTestDexFile(const string& filename) {
+  DexBuilder dex_file;
+
+  ClassBuilder cbuilder{dex_file.MakeClass("dextest.DexTest")};
+  cbuilder.set_source_file("dextest.java");
+
+  MethodBuilder method{cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Int()})};
+
+  MethodBuilder::Register r = method.MakeRegister();
+  method.BuildConst4(r, 5);
+  method.BuildReturn(r);
+
+  method.Encode();
+
+  slicer::MemView image{dex_file.CreateImage()};
+
+  std::ofstream out_file(filename);
+  out_file.write(image.ptr<const char>(), image.size());
+}
+
+DexBuilder::DexBuilder() : dex_file_{std::make_shared<ir::DexFile>()} {
+  dex_file_->magic = slicer::MemView{kDexFileMagic, sizeof(kDexFileMagic)};
+}
+
+slicer::MemView DexBuilder::CreateImage() {
+  ::dex::Writer writer(dex_file_);
+  size_t image_size{0};
+  ::dex::u1* image = writer.CreateImage(&allocator_, &image_size);
+  return slicer::MemView{image, image_size};
+}
+
+ir::String* DexBuilder::GetOrAddString(const std::string& string) {
+  ir::String*& entry = strings_[string];
+
+  if (entry == nullptr) {
+    // Need to encode the length and then write out the bytes, including 1 byte for null terminator
+    auto buffer = std::make_unique<uint8_t[]>(string.size() + kMaxEncodedStringLength + 1);
+    uint8_t* string_data_start = ::dex::WriteULeb128(buffer.get(), string.size());
+
+    size_t header_length =
+        reinterpret_cast<uintptr_t>(string_data_start) - reinterpret_cast<uintptr_t>(buffer.get());
+
+    auto end = std::copy(string.begin(), string.end(), string_data_start);
+    *end = '\0';
+
+    entry = Alloc<ir::String>();
+    // +1 for null terminator
+    entry->data = slicer::MemView{buffer.get(), header_length + string.size() + 1};
+    string_data_.push_back(std::move(buffer));
+  }
+  return entry;
+}
+
+ClassBuilder DexBuilder::MakeClass(const std::string& name) {
+  auto* class_def = Alloc<ir::Class>();
+  ir::Type* type_def = GetOrAddType(art::DotToDescriptor(name.c_str()));
+  type_def->class_def = class_def;
+
+  class_def->type = type_def;
+  class_def->super_class = GetOrAddType(art::DotToDescriptor("java.lang.Object"));
+  class_def->access_flags = kAccPublic;
+  return ClassBuilder{this, class_def};
+}
+
+// TODO(eholk): we probably want GetOrAddString() also
+ir::Type* DexBuilder::GetOrAddType(const std::string& descriptor) {
+  if (types_by_descriptor_.find(descriptor) != types_by_descriptor_.end()) {
+    return types_by_descriptor_[descriptor];
+  }
+
+  ir::Type* type = Alloc<ir::Type>();
+  type->descriptor = GetOrAddString(descriptor);
+  types_by_descriptor_[descriptor] = type;
+  return type;
+}
+
+ir::Proto* Prototype::Encode(DexBuilder* dex) const {
+  auto* proto = dex->Alloc<ir::Proto>();
+  proto->shorty = dex->GetOrAddString(Shorty());
+  proto->return_type = dex->GetOrAddType(return_type_.descriptor());
+  if (param_types_.size() > 0) {
+    proto->param_types = dex->Alloc<ir::TypeList>();
+    for (const auto& param_type : param_types_) {
+      proto->param_types->types.push_back(dex->GetOrAddType(param_type.descriptor()));
+    }
+  } else {
+    proto->param_types = nullptr;
+  }
+  return proto;
+}
+
+std::string Prototype::Shorty() const {
+  std::string shorty;
+  shorty.append(return_type_.short_descriptor());
+  for (const auto& type_descriptor : param_types_) {
+    shorty.append(type_descriptor.short_descriptor());
+  }
+  return shorty;
+}
+
+ClassBuilder::ClassBuilder(DexBuilder* parent, ir::Class* class_def)
+    : parent_(parent), class_(class_def) {}
+
+MethodBuilder ClassBuilder::CreateMethod(const std::string& name, Prototype prototype) {
+  ir::String* dex_name{parent_->GetOrAddString(name)};
+
+  auto* decl = parent_->Alloc<ir::MethodDecl>();
+  decl->name = dex_name;
+  decl->parent = class_->type;
+  decl->prototype = prototype.Encode(parent_);
+
+  return MethodBuilder{parent_, class_, decl};
+}
+
+void ClassBuilder::set_source_file(const string& source) {
+  class_->source_file = parent_->GetOrAddString(source);
+}
+
+MethodBuilder::MethodBuilder(DexBuilder* dex, ir::Class* class_def, ir::MethodDecl* decl)
+    : dex_{dex}, class_{class_def}, decl_{decl} {}
+
+ir::EncodedMethod* MethodBuilder::Encode() {
+  auto* method = dex_->Alloc<ir::EncodedMethod>();
+  method->decl = decl_;
+
+  // TODO: make access flags configurable
+  method->access_flags = kAccPublic | ::dex::kAccStatic;
+
+  auto* code = dex_->Alloc<ir::Code>();
+  code->registers = num_registers_;
+  // TODO: support ins and outs
+  code->instructions = slicer::ArrayView<const ::dex::u2>(buffer_.data(), buffer_.size());
+  method->code = code;
+
+  class_->direct_methods.push_back(method);
+
+  return method;
+}
+
+MethodBuilder::Register MethodBuilder::MakeRegister() { return num_registers_++; }
+
+void MethodBuilder::BuildReturn() { buffer_.push_back(Instruction::RETURN_VOID); }
+
+void MethodBuilder::BuildReturn(Register src) { buffer_.push_back(Instruction::RETURN | src << 8); }
+
+void MethodBuilder::BuildConst4(Register target, int value) {
+  DCHECK_LT(value, 16);
+  // TODO: support more registers
+  DCHECK_LT(target, 16);
+  buffer_.push_back(Instruction::CONST_4 | (value << 12) | (target << 8));
+}
+
+}  // namespace dex
+}  // namespace startop
diff --git a/startop/tools/view_compiler/dex_builder.h b/startop/tools/view_compiler/dex_builder.h
new file mode 100644
index 0000000..d280abc
--- /dev/null
+++ b/startop/tools/view_compiler/dex_builder.h
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+#ifndef DEX_BUILDER_H_
+#define DEX_BUILDER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "slicer/dex_ir.h"
+#include "slicer/writer.h"
+
+namespace startop {
+namespace dex {
+
+// TODO: remove this once the dex generation code is complete.
+void WriteTestDexFile(const std::string& filename);
+
+//////////////////////////
+// Forward declarations //
+//////////////////////////
+class DexBuilder;
+
+// Our custom allocator for dex::Writer
+//
+// This keeps track of all allocations and ensures they are freed when
+// TrackingAllocator is destroyed. Pointers to memory allocated by this
+// allocator must not outlive the allocator.
+class TrackingAllocator : public ::dex::Writer::Allocator {
+ public:
+  virtual void* Allocate(size_t size);
+  virtual void Free(void* ptr);
+
+ private:
+  std::map<void*, std::unique_ptr<uint8_t[]>> allocations_;
+};
+
+// Represents a DEX type descriptor.
+//
+// TODO: add a way to create a descriptor for a reference of a class type.
+class TypeDescriptor {
+ public:
+  // Named constructors for base type descriptors.
+  static const TypeDescriptor Int();
+  static const TypeDescriptor Void();
+
+  // Return the full descriptor, such as I or Ljava/lang/Object
+  const std::string& descriptor() const { return descriptor_; }
+  // Return the shorty descriptor, such as I or L
+  std::string short_descriptor() const { return descriptor().substr(0, 1); }
+
+ private:
+  TypeDescriptor(std::string descriptor) : descriptor_{descriptor} {}
+
+  const std::string descriptor_;
+};
+
+// Defines a function signature. For example, Prototype{TypeDescriptor::VOID, TypeDescriptor::Int}
+// represents the function type (Int) -> Void.
+class Prototype {
+ public:
+  template <typename... TypeDescriptors>
+  Prototype(TypeDescriptor return_type, TypeDescriptors... param_types)
+      : return_type_{return_type}, param_types_{param_types...} {}
+
+  // Encode this prototype into the dex file.
+  ir::Proto* Encode(DexBuilder* dex) const;
+
+  // Get the shorty descriptor, such as VII for (Int, Int) -> Void
+  std::string Shorty() const;
+
+ private:
+  const TypeDescriptor return_type_;
+  const std::vector<TypeDescriptor> param_types_;
+};
+
+// Tools to help build methods and their bodies.
+class MethodBuilder {
+ public:
+  MethodBuilder(DexBuilder* dex, ir::Class* class_def, ir::MethodDecl* decl);
+
+  // Encode the method into DEX format.
+  ir::EncodedMethod* Encode();
+
+  // Registers are just represented by their number.
+  using Register = size_t;
+
+  // Create a new register to be used to storing values. Note that these are not SSA registers, like
+  // might be expected in similar code generators. This does no liveness tracking or anything, so
+  // it's up to the caller to reuse registers as appropriate.
+  Register MakeRegister();
+
+  /////////////////////////////////
+  // Instruction builder methods //
+  /////////////////////////////////
+
+  // return-void
+  void BuildReturn();
+  void BuildReturn(Register src);
+  // const/4
+  void BuildConst4(Register target, int value);
+
+  // TODO: add builders for more instructions
+
+ private:
+  DexBuilder* dex_;
+  ir::Class* class_;
+  ir::MethodDecl* decl_;
+
+  // A buffer to hold instructions we are generating.
+  std::vector<::dex::u2> buffer_;
+
+  // How many registers we've allocated
+  size_t num_registers_;
+};
+
+// A helper to build class definitions.
+class ClassBuilder {
+ public:
+  ClassBuilder(DexBuilder* parent, ir::Class* class_def);
+
+  void set_source_file(const std::string& source);
+
+  // Create a method with the given name and prototype. The returned MethodBuilder can be used to
+  // fill in the method body.
+  MethodBuilder CreateMethod(const std::string& name, Prototype prototype);
+
+ private:
+  DexBuilder* parent_;
+  ir::Class* class_;
+};
+
+// Builds Dex files from scratch.
+class DexBuilder {
+ public:
+  DexBuilder();
+
+  // Create an in-memory image of the DEX file that can either be loaded directly or written to a
+  // file.
+  slicer::MemView CreateImage();
+
+  template <typename T>
+  T* Alloc() {
+    return dex_file_->Alloc<T>();
+  }
+
+  // Find the ir::String that matches the given string, creating it if it does not exist.
+  ir::String* GetOrAddString(const std::string& string);
+  // Create a new class of the given name.
+  ClassBuilder MakeClass(const std::string& name);
+
+  // Add a type for the given descriptor, or return the existing one if it already exists.
+  // See the TypeDescriptor class for help generating these.
+  ir::Type* GetOrAddType(const std::string& descriptor);
+
+ private:
+  std::shared_ptr<ir::DexFile> dex_file_;
+
+  // allocator_ is needed to be able to encode the image.
+  TrackingAllocator allocator_;
+
+  // We'll need to allocate buffers for all of the encoded strings we create. This is where we store
+  // all of them.
+  std::vector<std::unique_ptr<uint8_t[]>> string_data_;
+
+  // Keep track of what types we've defined so we can look them up later.
+  std::map<std::string, ir::Type*> types_by_descriptor_;
+
+  // Keep track of what strings we've defined so we can look them up later.
+  std::map<std::string, ir::String*> strings_;
+};
+
+}  // namespace dex
+}  // namespace startop
+
+#endif  // DEX_BUILDER_H_
diff --git a/startop/tools/view_compiler/dex_builder_test.cc b/startop/tools/view_compiler/dex_builder_test.cc
new file mode 100644
index 0000000..0d8b854
--- /dev/null
+++ b/startop/tools/view_compiler/dex_builder_test.cc
@@ -0,0 +1,82 @@
+/*
+ * 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 "dex_builder.h"
+
+#include "dex/art_dex_file_loader.h"
+#include "dex/dex_file.h"
+#include "gtest/gtest.h"
+
+using namespace startop::dex;
+
+// Takes a DexBuilder, encodes it into an in-memory DEX file, verifies the resulting DEX file and
+// returns whether the verification was successful.
+bool EncodeAndVerify(DexBuilder* dex_file) {
+  slicer::MemView image{dex_file->CreateImage()};
+
+  art::ArtDexFileLoader loader;
+  std::string error_msg;
+  std::unique_ptr<const art::DexFile> loaded_dex_file{loader.Open(image.ptr<const uint8_t>(),
+                                                                  image.size(),
+                                                                  /*location=*/"",
+                                                                  /*location_checksum=*/0,
+                                                                  /*oat_dex_file=*/nullptr,
+                                                                  /*verify=*/true,
+                                                                  /*verify_checksum=*/false,
+                                                                  &error_msg)};
+  return loaded_dex_file != nullptr;
+}
+
+TEST(DexBuilderTest, VerifyDexWithClassMethod) {
+  DexBuilder dex_file;
+
+  auto cbuilder{dex_file.MakeClass("dextest.DexTest")};
+
+  auto method{cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Void()})};
+  method.BuildReturn();
+  method.Encode();
+
+  EXPECT_TRUE(EncodeAndVerify(&dex_file));
+}
+
+// Makes sure a bad DEX class fails to verify.
+TEST(DexBuilderTest, VerifyBadDexWithClassMethod) {
+  DexBuilder dex_file;
+
+  auto cbuilder{dex_file.MakeClass("dextest.DexTest")};
+
+  // This method has the error, because methods cannot take Void() as a parameter.
+  auto method{
+      cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Void(), TypeDescriptor::Void()})};
+  method.BuildReturn();
+  method.Encode();
+
+  EXPECT_FALSE(EncodeAndVerify(&dex_file));
+}
+
+TEST(DexBuilderTest, VerifyDexReturn5) {
+  DexBuilder dex_file;
+
+  auto cbuilder{dex_file.MakeClass("dextest.DexTest")};
+
+  auto method{cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Int()})};
+  auto r = method.MakeRegister();
+  method.BuildConst4(r, 5);
+  method.BuildReturn(r);
+  method.Encode();
+
+  EXPECT_TRUE(EncodeAndVerify(&dex_file));
+}
diff --git a/startop/tools/view_compiler/main.cc b/startop/tools/view_compiler/main.cc
index 0ad7e24..7d791c2 100644
--- a/startop/tools/view_compiler/main.cc
+++ b/startop/tools/view_compiler/main.cc
@@ -16,6 +16,7 @@
 
 #include "gflags/gflags.h"
 
+#include "dex_builder.h"
 #include "java_lang_builder.h"
 #include "util.h"
 
@@ -27,15 +28,17 @@
 #include <string>
 #include <vector>
 
+namespace {
+
 using namespace tinyxml2;
 using std::string;
 
 constexpr char kStdoutFilename[]{"stdout"};
 
-DEFINE_string(package, "", "The package name for the generated class (required)");
+DEFINE_bool(dex, false, "Generate a DEX file instead of Java");
 DEFINE_string(out, kStdoutFilename, "Where to write the generated class");
+DEFINE_string(package, "", "The package name for the generated class (required)");
 
-namespace {
 class ViewCompilerXmlVisitor : public XMLVisitor {
  public:
   ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
@@ -63,6 +66,7 @@
  private:
   JavaLangViewBuilder* builder_;
 };
+
 }  // end namespace
 
 int main(int argc, char** argv) {
@@ -82,6 +86,11 @@
     return 1;
   }
 
+  if (FLAGS_dex) {
+    startop::dex::WriteTestDexFile("test.dex");
+    return 0;
+  }
+
   const char* const filename = argv[kFileNameParam];
   const string layout_name = FindLayoutNameFromFilename(filename);
 
@@ -102,4 +111,4 @@
   xml.Accept(&visitor);
 
   return 0;
-}
\ No newline at end of file
+}
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 08bc9bc..daa09f5 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -397,7 +397,19 @@
         public static final int PROPERTY_WIFI = 0x00000008;
 
         /**
-         * Call is using high definition audio.
+         * When set, the UI should indicate to the user that a call is using high definition
+         * audio.
+         * <p>
+         * The underlying {@link ConnectionService} is responsible for reporting this
+         * property.  It is important to note that this property is not intended to report the
+         * actual audio codec being used for a Call, but whether the call should be indicated
+         * to the user as high definition.
+         * <p>
+         * The Android Telephony stack reports this property for calls based on a number
+         * of factors, including which audio codec is used and whether a call is using an HD
+         * codec end-to-end.  Some mobile operators choose to suppress display of an HD indication,
+         * and in these cases this property will not be set for a call even if the underlying audio
+         * codec is in fact "high definition".
          */
         public static final int PROPERTY_HIGH_DEF_AUDIO = 0x00000010;
 
diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java
index 61adcdd..4d5f5e1 100644
--- a/telecomm/java/android/telecom/ConnectionService.java
+++ b/telecomm/java/android/telecom/ConnectionService.java
@@ -71,7 +71,7 @@
  * See {@link PhoneAccount} and {@link TelecomManager#registerPhoneAccount} for more information.
  * <p>
  * System managed {@link ConnectionService}s must be enabled by the user in the phone app settings
- * before Telecom will bind to them.  Self-manged {@link ConnectionService}s must be granted the
+ * before Telecom will bind to them.  Self-managed {@link ConnectionService}s must be granted the
  * appropriate permission before Telecom will bind to them.
  * <p>
  * Once registered and enabled by the user in the phone app settings or granted permission, telecom
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 8c37a21..d33a537 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1905,6 +1905,22 @@
         return false;
     }
 
+    /**
+     * Handles {@link Intent#ACTION_CALL} intents trampolined from UserCallActivity.
+     * @param intent The {@link Intent#ACTION_CALL} intent to handle.
+     * @hide
+     */
+    public void handleCallIntent(Intent intent) {
+        try {
+            if (isServiceConnected()) {
+                getTelecomService().handleCallIntent(intent);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException handleCallIntent: " + e);
+        }
+
+    }
+
     private ITelecomService getTelecomService() {
         if (mTelecomServiceOverride != null) {
             return mTelecomServiceOverride;
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 38247bc..df7d683 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -284,4 +284,9 @@
      * @see TelecomServiceImpl#isInEmergencyCall
      */
     boolean isInEmergencyCall();
+
+    /**
+     * @see TelecomServiceImpl#handleCallIntent
+     */
+    void handleCallIntent(in Intent intent);
 }
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 4846092..d9e7167 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -18,6 +18,7 @@
 
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.job.JobService;
@@ -2889,100 +2890,131 @@
         public static final String SUBSCRIPTION_ID = "sub_id";
 
         /**
-         * The profile_id to which the APN saved in modem
+         * The profile_id to which the APN saved in modem.
          * <p>Type: INTEGER</p>
          *@hide
          */
         public static final String PROFILE_ID = "profile_id";
 
         /**
-         * Is the apn setting to be set in modem
-         * <P>Type: INTEGER (boolean)</P>
+         * If set to {@code true}, then the APN setting will persist to the modem.
+         * <p>Type: INTEGER (boolean)</p>
          *@hide
          */
+        @SystemApi
         public static final String MODEM_COGNITIVE = "modem_cognitive";
 
         /**
-         * The max connections of this apn
+         * The max connections of this APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String MAX_CONNS = "max_conns";
 
         /**
-         * The wait time for retry of the apn
+         * The wait time for retry of the APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String WAIT_TIME = "wait_time";
 
         /**
-         * The time to limit max connection for the apn
+         * The time to limit max connection for the APN.
          * <p>Type: INTEGER</p>
          *@hide
          */
+        @SystemApi
         public static final String MAX_CONNS_TIME = "max_conns_time";
 
         /**
-         * The MTU size of the mobile interface to  which the APN connected
+         * The MTU(Maxinum transmit unit) size of the mobile interface to which the APN connected.
          * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final String MTU = "mtu";
 
         /**
-         * Is this APN added/edited/deleted by a user or carrier?
+         * APN edit status. APN could be added/edited/deleted by a user or carrier.
          * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final String EDITED = "edited";
 
         /**
-         * Is this APN visible to the user?
-         * <p>Type: INTEGER (boolean) </p>
+         * {@code true} if this APN visible to the user, {@code false} otherwise.
+         * <p>Type: INTEGER (boolean)</p>
          * @hide
          */
+        @SystemApi
         public static final String USER_VISIBLE = "user_visible";
 
         /**
-         * Is the user allowed to edit this APN?
-         * <p>Type: INTEGER (boolean) </p>
+         * {@code true} if the user allowed to edit this APN, {@code false} otherwise.
+         * <p>Type: INTEGER (boolean)</p>
          * @hide
          */
+        @SystemApi
         public static final String USER_EDITABLE = "user_editable";
 
         /**
-         * Following are possible values for the EDITED field
+         * {@link #EDITED APN edit status} indicates that this APN has not been edited or fails to
+         * edit.
+         * <p>Type: INTEGER </p>
          * @hide
          */
+        @SystemApi
         public static final int UNEDITED = 0;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been edited by users.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int USER_EDITED = 1;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been deleted by users.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int USER_DELETED = 2;
+
         /**
-         * DELETED_BUT_PRESENT is an intermediate value used to indicate that an entry deleted
-         * by the user is still present in the new APN database and therefore must remain tagged
-         * as user deleted rather than completely removed from the database
+         * {@link #EDITED APN edit status} is an intermediate value used to indicate that an entry
+         * deleted by the user is still present in the new APN database and therefore must remain
+         * tagged as user deleted rather than completely removed from the database.
          * @hide
          */
         public static final int USER_DELETED_BUT_PRESENT_IN_XML = 3;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} indicates that this APN has been edited by carriers.
+         * <p>Type: INTEGER </p>
+         * @hide
          */
+        @SystemApi
         public static final int CARRIER_EDITED = 4;
+
         /**
-         * CARRIER_DELETED values are currently not used as there is no usecase. If they are used,
+         * {@link #EDITED APN edit status} indicates that this APN has been deleted by carriers.
+         * CARRIER_DELETED values are currently not used as there is no use case. If they are used,
          * delete() will have to change accordingly. Currently it is hardcoded to USER_DELETED.
+         * <p>Type: INTEGER </p>
          * @hide
          */
         public static final int CARRIER_DELETED = 5;
+
         /**
-         *  @hide
+         * {@link #EDITED APN edit status} is an intermediate value used to indicate that an entry
+         * deleted by the carrier is still present in the new APN database and therefore must remain
+         * tagged as user deleted rather than completely removed from the database.
+         * @hide
          */
         public static final int CARRIER_DELETED_BUT_PRESENT_IN_XML = 6;
 
@@ -3011,16 +3043,20 @@
          * The APN set id. When the user manually selects an APN or the framework sets an APN as
          * preferred, all APNs with the same set id as the selected APN should be prioritized over
          * APNs in other sets.
+         * <p>Type: INTEGER</p>
          * @hide
          */
+        @SystemApi
         public static final String APN_SET_ID = "apn_set_id";
 
         /**
-         * Possible value for the APN_SET_ID field. By default APNs will not belong to a set. If the
-         * user manually selects an APN with no set set, there is no need to prioritize any specific
-         * APN set ids.
+         * Possible value for the{@link #APN_SET_ID} field. By default APNs will not belong to a
+         * set. If the user manually selects an APN with no set set, there is no need to prioritize
+         * any specific APN set ids.
+         * <p>Type: INTEGER</p>
          * @hide
          */
+        @SystemApi
         public static final int NO_SET_SET = 0;
 
     }
@@ -3289,7 +3325,6 @@
             values.put(CDMA_ERI_ICON_INDEX, state.getCdmaEriIconIndex());
             values.put(CDMA_ERI_ICON_MODE, state.getCdmaEriIconMode());
             values.put(IS_EMERGENCY_ONLY, state.isEmergencyOnly());
-            values.put(IS_DATA_ROAMING_FROM_REGISTRATION, state.getDataRoamingFromRegistration());
             values.put(IS_USING_CARRIER_AGGREGATION, state.isUsingCarrierAggregation());
             return values;
         }
@@ -3525,6 +3560,18 @@
         public static final String CARRIER_ID = "carrier_id";
 
         /**
+         * A unique mno carrier id. mno carrier shares the same {@link All#MCCMNC} as carrier id
+         * and can be solely identified by {@link All#MCCMNC} only. If there is no such mno
+         * carrier, then mno carrier id equals to {@link #CARRIER_ID carrier id}.
+         *
+         * <p>mno carrier id can be used as fallback id. When the exact carrier id configurations
+         * are not found, usually fall back to its mno carrier id.
+         * <P>Type: INTEGER </P>
+         * @hide
+         */
+        public static final String MNO_CARRIER_ID = "mno_carrier_id";
+
+        /**
          * Contains mappings between matching rules with carrier id for all carriers.
          * @hide
          */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 57b652e..b0997f1 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1202,6 +1202,20 @@
             "always_show_data_rat_icon_bool";
 
     /**
+     * Boolean indicating if default data account should show LTE or 4G icon
+     * @hide
+     */
+    public static final String KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL =
+            "show_4g_for_lte_data_icon_bool";
+
+    /**
+     * Boolean indicating if lte+ icon should be shown if available
+     * @hide
+     */
+    public static final String KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL =
+            "hide_lte_plus_data_icon_bool";
+
+    /**
      * Boolean to decide whether to show precise call failed cause to user
      * @hide
      */
@@ -1633,11 +1647,21 @@
      * When {@code false}, use default title for Enhanced 4G LTE Mode settings.
      * When {@code true}, use the variant.
      * @hide
+     * @deprecated use {@link #KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT}.
      */
+    @Deprecated
     public static final String KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL =
             "enhanced_4g_lte_title_variant_bool";
 
     /**
+     * The index indicates the carrier specified title string of Enahnce 4G LTE Mode settings.
+     * Default value is 0, which indicates the default title string.
+     * @hide
+     */
+    public static final String KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT =
+            "enhanced_4g_lte_title_variant_int";
+
+    /**
      * Indicates whether the carrier wants to notify the user when handover of an LTE video call to
      * WIFI fails.
      * <p>
@@ -1955,6 +1979,31 @@
     public static final String KEY_RTT_SUPPORTED_BOOL = "rtt_supported_bool";
 
     /**
+     * Indicates if the carrier supports auto-upgrading a call to RTT when receiving a call from a
+     * RTT-supported device.
+     * @hide
+     */
+    public static final String KEY_RTT_AUTO_UPGRADE_BOOL = "rtt_auto_upgrade_bool";
+
+    /**
+     * Indicates if the carrier supports RTT during a video call.
+     * @hide
+     */
+    public static final String KEY_RTT_SUPPORTED_FOR_VT_BOOL = "rtt_supported_for_vt_bool";
+
+    /**
+     * Indicates if the carrier supports upgrading a voice call to an RTT call during the call.
+     * @hide
+     */
+    public static final String KEY_RTT_UPGRADE_SUPPORTED_BOOL = "rtt_upgrade_supported_bool";
+
+    /**
+     * Indicates if the carrier supports downgrading a RTT call to a voice call during the call.
+     * @hide
+     */
+    public static final String KEY_RTT_DOWNGRADE_SUPPORTED_BOOL = "rtt_downgrade_supported_bool";
+
+    /**
      * The flag to disable the popup dialog which warns the user of data charges.
      * @hide
      */
@@ -2133,6 +2182,46 @@
     public static final String KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL =
             "show_call_blocking_disabled_notification_always_bool";
 
+    /**
+     * Some carriers only support SS over UT via INTERNET PDN.
+     * When mobile data is OFF or data roaming OFF during roaming,
+     * UI should block the call forwarding operation and notify the user
+     * that the function only works if data is available.
+     * @hide
+     */
+    public static final String KEY_CALL_FORWARDING_OVER_UT_WARNING_BOOL =
+            "call_forwarding_over_ut_warning_bool";
+
+    /**
+     * Some carriers only support SS over UT via INTERNET PDN.
+     * When mobile data is OFF or data roaming OFF during roaming,
+     * UI should block the call barring operation and notify the user
+     * that the function only works if data is available.
+     * @hide
+     */
+    public static final String KEY_CALL_BARRING_OVER_UT_WARNING_BOOL =
+            "call_barring_over_ut_warning_bool";
+
+    /**
+     * Some carriers only support SS over UT via INTERNET PDN.
+     * When mobile data is OFF or data roaming OFF during roaming,
+     * UI should block the caller id operation and notify the user
+     * that the function only works if data is available.
+     * @hide
+     */
+    public static final String KEY_CALLER_ID_OVER_UT_WARNING_BOOL =
+            "caller_id_over_ut_warning_bool";
+
+    /**
+     * Some carriers only support SS over UT via INTERNET PDN.
+     * When mobile data is OFF or data roaming OFF during roaming,
+     * UI should block the call waiting operation and notify the user
+     * that the function only works if data is available.
+     * @hide
+     */
+    public static final String KEY_CALL_WAITING_OVER_UT_WARNING_BOOL =
+            "call_waiting_over_ut_warning_bool";
+
     /** The default value for every variable. */
     private final static PersistableBundle sDefaults;
 
@@ -2419,6 +2508,7 @@
 
         sDefaults.putStringArray(KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_BOOL, false);
+        sDefaults.putInt(KEY_ENHANCED_4G_LTE_TITLE_VARIANT_INT, 0);
         sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false);
         sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null);
         sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
@@ -2454,6 +2544,8 @@
         sDefaults.putBoolean(KEY_SHOW_PRECISE_FAILED_CAUSE_BOOL, false);
         sDefaults.putBoolean(KEY_SPN_DISPLAY_RULE_USE_ROAMING_FROM_SERVICE_STATE_BOOL, false);
         sDefaults.putBoolean(KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL, false);
+        sDefaults.putBoolean(KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, true);
+        sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, false);
         sDefaults.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
         sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false);
         sDefaults.putIntArray(KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
@@ -2473,6 +2565,10 @@
         sDefaults.putString(KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING, "");
         sDefaults.putBoolean(KEY_CONFIG_SHOW_ORIG_DIAL_STRING_FOR_CDMA_BOOL, false);
         sDefaults.putBoolean(KEY_SHOW_CALL_BLOCKING_DISABLED_NOTIFICATION_ALWAYS_BOOL, false);
+        sDefaults.putBoolean(KEY_CALL_FORWARDING_OVER_UT_WARNING_BOOL, false);
+        sDefaults.putBoolean(KEY_CALL_BARRING_OVER_UT_WARNING_BOOL, false);
+        sDefaults.putBoolean(KEY_CALLER_ID_OVER_UT_WARNING_BOOL, false);
+        sDefaults.putBoolean(KEY_CALL_WAITING_OVER_UT_WARNING_BOOL, false);
     }
 
     /**
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index ee5cdc2..d7169b2 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -319,6 +319,29 @@
      */
     public static final int IMS_SIP_ALTERNATE_EMERGENCY_CALL = 71;
 
+    /**
+     * Indicates that a new outgoing call cannot be placed because there is already an outgoing
+     * call dialing out.
+     */
+    public static final int ALREADY_DIALING = 72;
+
+    /**
+     * Indicates that a new outgoing call cannot be placed while there is a ringing call.
+     */
+    public static final int CANT_CALL_WHILE_RINGING = 73;
+
+    /**
+     * Indicates that a new outgoing call cannot be placed because calling has been disabled using
+     * the ro.telephony.disable-call system property.
+     */
+    public static final int CALLING_DISABLED = 74;
+
+    /**
+     * Indicates that a new outgoing call cannot be placed because there is currently an ongoing
+     * foreground and background call.
+     */
+    public static final int TOO_MANY_ONGOING_CALLS = 75;
+
     //*********************************************************************************************
     // When adding a disconnect type:
     // 1) Update toString() with the newly added disconnect type.
@@ -474,6 +497,14 @@
             return "NORMAL_UNSPECIFIED";
         case IMS_SIP_ALTERNATE_EMERGENCY_CALL:
             return "IMS_SIP_ALTERNATE_EMERGENCY_CALL";
+        case ALREADY_DIALING:
+            return "ALREADY_DIALING";
+        case CANT_CALL_WHILE_RINGING:
+            return "CANT_CALL_WHILE_RINGING";
+        case CALLING_DISABLED:
+            return "CALLING_DISABLED";
+        case TOO_MANY_ONGOING_CALLS:
+            return "TOO_MANY_ONGOING_CALLS";
         default:
             return "INVALID: " + cause;
         }
diff --git a/telephony/java/android/telephony/NeighboringCellInfo.java b/telephony/java/android/telephony/NeighboringCellInfo.java
index 5e4518f..ac38efb 100644
--- a/telephony/java/android/telephony/NeighboringCellInfo.java
+++ b/telephony/java/android/telephony/NeighboringCellInfo.java
@@ -33,8 +33,9 @@
  * Represents the neighboring cell information, including
  * Received Signal Strength and Cell ID location.
  *
- * @deprecated This class should not be used by anyone targeting SDK level 29 (Q) or higher.
- *      Instead callers should use {@Link android.telephony.CellInfo}.
+ * @deprecated This class should not be used by any app targeting
+ *     {@link android.os.Build.VERSION_CODES#Q Android Q} or higher. Instead callers should use
+ *     {@link android.telephony.CellInfo CellInfo}.
  */
 @Deprecated
 public class NeighboringCellInfo implements Parcelable
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index c393155..b312f84 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -95,6 +95,13 @@
     @RegState
     private final int mRegState;
 
+    /**
+     * Save the {@link ServiceState.RoamingType roaming type}. it can be overridden roaming type
+     * from resource overlay or carrier config.
+     */
+    @ServiceState.RoamingType
+    private int mRoamingType;
+
     private final int mAccessNetworkTechnology;
 
     private final int mRejectCause;
@@ -140,6 +147,8 @@
         mDomain = domain;
         mTransportType = transportType;
         mRegState = regState;
+        mRoamingType = (regState == REG_STATE_ROAMING)
+                ? ServiceState.ROAMING_TYPE_UNKNOWN : ServiceState.ROAMING_TYPE_NOT_ROAMING;
         mAccessNetworkTechnology = accessNetworkTechnology;
         mRejectCause = rejectCause;
         mAvailableServices = availableServices;
@@ -182,6 +191,7 @@
         mDomain = source.readInt();
         mTransportType = source.readInt();
         mRegState = source.readInt();
+        mRoamingType = source.readInt();
         mAccessNetworkTechnology = source.readInt();
         mRejectCause = source.readInt();
         mEmergencyOnly = source.readBoolean();
@@ -211,6 +221,31 @@
     }
 
     /**
+     * @return {@code true} if registered on roaming network, {@code false} otherwise.
+     */
+    public boolean isRoaming() {
+        return mRoamingType != ServiceState.ROAMING_TYPE_NOT_ROAMING;
+    }
+
+    /**
+     * Set {@link ServiceState.RoamingType roaming type}. This could override
+     * roaming type based on resource overlay or carrier config.
+     * @hide
+     */
+    public void setRoamingType(@ServiceState.RoamingType int roamingType) {
+        mRoamingType = roamingType;
+    }
+
+    /**
+     * @return {@link ServiceState.RoamingType roaming type}. This could return
+     * overridden roaming type based on resource overlay or carrier config.
+     * @hide
+     */
+    public @ServiceState.RoamingType int getRoamingType() {
+        return mRoamingType;
+    }
+
+    /**
      * @return Whether emergency is enabled.
      */
     public boolean isEmergencyEnabled() { return mEmergencyOnly; }
@@ -280,6 +315,7 @@
                 .append(" domain=").append((mDomain == DOMAIN_CS) ? "CS" : "PS")
                 .append("transportType=").append(mTransportType)
                 .append(" regState=").append(regStateToString(mRegState))
+                .append(" roamingType=").append(mRoamingType)
                 .append(" accessNetworkTechnology=")
                 .append(TelephonyManager.getNetworkTypeName(mAccessNetworkTechnology))
                 .append(" rejectCause=").append(mRejectCause)
@@ -293,9 +329,9 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mDomain, mTransportType, mRegState, mAccessNetworkTechnology,
-                mRejectCause, mEmergencyOnly, mAvailableServices, mCellIdentity,
-                mVoiceSpecificStates, mDataSpecificStates);
+        return Objects.hash(mDomain, mTransportType, mRegState, mRoamingType,
+                mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
+                mCellIdentity, mVoiceSpecificStates, mDataSpecificStates);
     }
 
     @Override
@@ -310,6 +346,7 @@
         return mDomain == other.mDomain
                 && mTransportType == other.mTransportType
                 && mRegState == other.mRegState
+                && mRoamingType == other.mRoamingType
                 && mAccessNetworkTechnology == other.mAccessNetworkTechnology
                 && mRejectCause == other.mRejectCause
                 && mEmergencyOnly == other.mEmergencyOnly
@@ -325,6 +362,7 @@
         dest.writeInt(mDomain);
         dest.writeInt(mTransportType);
         dest.writeInt(mRegState);
+        dest.writeInt(mRoamingType);
         dest.writeInt(mAccessNetworkTechnology);
         dest.writeInt(mRejectCause);
         dest.writeBoolean(mEmergencyOnly);
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 3ea018a..c83d6aa 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -17,6 +17,7 @@
 package android.telephony;
 
 import android.annotation.NonNull;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.os.Handler;
@@ -291,6 +292,15 @@
      */
     public static final int LISTEN_PREFERRED_DATA_SUBID_CHANGE              = 0x00400000;
 
+    /**
+     *  Listen for changes to the radio power state.
+     *
+     *  @see #onRadioPowerStateChanged
+     *  @hide
+     */
+    @SystemApi
+    public static final int LISTEN_RADIO_POWER_STATE_CHANGED               = 0x00800000;
+
     /*
      * Subscription used to listen to the phone state changes
      * @hide
@@ -420,6 +430,9 @@
                     case LISTEN_PREFERRED_DATA_SUBID_CHANGE:
                         PhoneStateListener.this.onPreferredDataSubIdChanged((int) msg.obj);
                         break;
+                    case LISTEN_RADIO_POWER_STATE_CHANGED:
+                        PhoneStateListener.this.onRadioPowerStateChanged((int) msg.obj);
+                        break;
                 }
             }
         };
@@ -672,6 +685,17 @@
     }
 
     /**
+     * Callback invoked when modem radio power state changes. Requires
+     * the READ_PRIVILEGED_PHONE_STATE permission.
+     * @param state the modem radio power state
+     * @hide
+     */
+    @SystemApi
+    public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) {
+        // default implementation empty
+    }
+
+    /**
      * Callback invoked when telephony has received notice from a carrier
      * app that a network action that could result in connectivity loss
      * has been requested by an app using
@@ -807,6 +831,10 @@
             send(LISTEN_PREFERRED_DATA_SUBID_CHANGE, 0, 0, subId);
         }
 
+        public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) {
+            send(LISTEN_RADIO_POWER_STATE_CHANGED, 0, 0, state);
+        }
+
     }
 
     /**
diff --git a/telephony/java/android/telephony/RcsManager.java b/telephony/java/android/telephony/RcsManager.java
new file mode 100644
index 0000000..00ce03a
--- /dev/null
+++ b/telephony/java/android/telephony/RcsManager.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+import com.android.internal.telephony.IRcs;
+
+/**
+ * RcsManager is the application interface to RcsProvider and provides access methods to
+ * RCS related database tables.
+ * @hide - TODO make this public
+ */
+public class RcsManager {
+    private static final String TAG = "RcsManager";
+    private static final boolean VDBG = false;
+
+    /**
+     * Delete the RcsThread identified by the given threadId.
+     * @param threadId threadId of the thread to be deleted.
+     */
+    public void deleteThread(int threadId) {
+        if (VDBG) logd("deleteThread: threadId: " + threadId);
+        try {
+            IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs"));
+            if (iRcs != null) {
+                iRcs.deleteThread(threadId);
+            }
+        } catch (RemoteException re) {
+
+        }
+    }
+
+    private static void logd(String msg) {
+        Rlog.d(TAG, msg);
+    }
+}
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index f2b73dc..e0ec2c5 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -20,10 +20,12 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.NetworkRegistrationState.Domain;
 import android.text.TextUtils;
 
 import java.lang.annotation.Retention;
@@ -56,7 +58,7 @@
      * Normal operation condition, the phone is registered
      * with an operator either in home network or in roaming.
      */
-    public static final int STATE_IN_SERVICE = 0;
+    public static final int STATE_IN_SERVICE = TelephonyProtoEnums.SERVICE_STATE_IN_SERVICE; // 0
 
     /**
      * Phone is not registered with any operator, the phone
@@ -64,17 +66,19 @@
      * searching to registration at all, or registration is denied, or radio
      * signal is not available.
      */
-    public static final int STATE_OUT_OF_SERVICE = 1;
+    public static final int STATE_OUT_OF_SERVICE =
+            TelephonyProtoEnums.SERVICE_STATE_OUT_OF_SERVICE;  // 1
 
     /**
      * The phone is registered and locked.  Only emergency numbers are allowed. {@more}
      */
-    public static final int STATE_EMERGENCY_ONLY = 2;
+    public static final int STATE_EMERGENCY_ONLY =
+            TelephonyProtoEnums.SERVICE_STATE_EMERGENCY_ONLY;  // 2
 
     /**
      * Radio of telephony is explicitly powered off.
      */
-    public static final int STATE_POWER_OFF = 3;
+    public static final int STATE_POWER_OFF = TelephonyProtoEnums.SERVICE_STATE_POWER_OFF;  // 3
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
@@ -197,6 +201,15 @@
     private int mVoiceRegState = STATE_OUT_OF_SERVICE;
     private int mDataRegState = STATE_OUT_OF_SERVICE;
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = { "ROAMING_TYPE_" }, value = {
+            ROAMING_TYPE_NOT_ROAMING,
+            ROAMING_TYPE_UNKNOWN,
+            ROAMING_TYPE_DOMESTIC,
+            ROAMING_TYPE_INTERNATIONAL
+    })
+    public @interface RoamingType {}
     /**
      * Roaming type
      * HOME : in home network
@@ -227,8 +240,6 @@
      */
     public static final int UNKNOWN_ID = -1;
 
-    private int mVoiceRoamingType;
-    private int mDataRoamingType;
     private String mVoiceOperatorAlphaLong;
     private String mVoiceOperatorAlphaShort;
     private String mVoiceOperatorNumeric;
@@ -258,8 +269,6 @@
     @UnsupportedAppUsage
     private int mCdmaEriIconMode;
 
-    private boolean mIsDataRoamingFromRegistration;
-
     @UnsupportedAppUsage
     private boolean mIsUsingCarrierAggregation;
 
@@ -331,8 +340,6 @@
     protected void copyFrom(ServiceState s) {
         mVoiceRegState = s.mVoiceRegState;
         mDataRegState = s.mDataRegState;
-        mVoiceRoamingType = s.mVoiceRoamingType;
-        mDataRoamingType = s.mDataRoamingType;
         mVoiceOperatorAlphaLong = s.mVoiceOperatorAlphaLong;
         mVoiceOperatorAlphaShort = s.mVoiceOperatorAlphaShort;
         mVoiceOperatorNumeric = s.mVoiceOperatorNumeric;
@@ -350,7 +357,6 @@
         mCdmaEriIconIndex = s.mCdmaEriIconIndex;
         mCdmaEriIconMode = s.mCdmaEriIconMode;
         mIsEmergencyOnly = s.mIsEmergencyOnly;
-        mIsDataRoamingFromRegistration = s.mIsDataRoamingFromRegistration;
         mIsUsingCarrierAggregation = s.mIsUsingCarrierAggregation;
         mChannelNumber = s.mChannelNumber;
         mCellBandwidths = s.mCellBandwidths == null ? null :
@@ -366,8 +372,6 @@
     public ServiceState(Parcel in) {
         mVoiceRegState = in.readInt();
         mDataRegState = in.readInt();
-        mVoiceRoamingType = in.readInt();
-        mDataRoamingType = in.readInt();
         mVoiceOperatorAlphaLong = in.readString();
         mVoiceOperatorAlphaShort = in.readString();
         mVoiceOperatorNumeric = in.readString();
@@ -385,7 +389,6 @@
         mCdmaEriIconIndex = in.readInt();
         mCdmaEriIconMode = in.readInt();
         mIsEmergencyOnly = in.readInt() != 0;
-        mIsDataRoamingFromRegistration = in.readInt() != 0;
         mIsUsingCarrierAggregation = in.readInt() != 0;
         mLteEarfcnRsrpBoost = in.readInt();
         mNetworkRegistrationStates = new ArrayList<>();
@@ -397,8 +400,6 @@
     public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mVoiceRegState);
         out.writeInt(mDataRegState);
-        out.writeInt(mVoiceRoamingType);
-        out.writeInt(mDataRoamingType);
         out.writeString(mVoiceOperatorAlphaLong);
         out.writeString(mVoiceOperatorAlphaShort);
         out.writeString(mVoiceOperatorNumeric);
@@ -416,7 +417,6 @@
         out.writeInt(mCdmaEriIconIndex);
         out.writeInt(mCdmaEriIconMode);
         out.writeInt(mIsEmergencyOnly ? 1 : 0);
-        out.writeInt(mIsDataRoamingFromRegistration ? 1 : 0);
         out.writeInt(mIsUsingCarrierAggregation ? 1 : 0);
         out.writeInt(mLteEarfcnRsrpBoost);
         out.writeList(mNetworkRegistrationStates);
@@ -534,17 +534,21 @@
      */
     @UnsupportedAppUsage
     public boolean getVoiceRoaming() {
-        return mVoiceRoamingType != ROAMING_TYPE_NOT_ROAMING;
+        return getVoiceRoamingType() != ROAMING_TYPE_NOT_ROAMING;
     }
-
     /**
      * Get current voice network roaming type
      * @return roaming type
      * @hide
      */
     @UnsupportedAppUsage
-    public int getVoiceRoamingType() {
-        return mVoiceRoamingType;
+    public @RoamingType int getVoiceRoamingType() {
+        final NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState != null) {
+            return regState.getRoamingType();
+        }
+        return ROAMING_TYPE_NOT_ROAMING;
     }
 
     /**
@@ -554,19 +558,7 @@
      */
     @UnsupportedAppUsage
     public boolean getDataRoaming() {
-        return mDataRoamingType != ROAMING_TYPE_NOT_ROAMING;
-    }
-
-    /**
-     * Set whether data network registration state is roaming
-     *
-     * This should only be set to the roaming value received
-     * once the data registration phase has completed.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public void setDataRoamingFromRegistration(boolean dataRoaming) {
-        mIsDataRoamingFromRegistration = dataRoaming;
+        return getDataRoamingType() != ROAMING_TYPE_NOT_ROAMING;
     }
 
     /**
@@ -575,7 +567,12 @@
      * @hide
      */
     public boolean getDataRoamingFromRegistration() {
-        return mIsDataRoamingFromRegistration;
+        final NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState != null) {
+            return (regState.getRegState() == NetworkRegistrationState.REG_STATE_ROAMING);
+        }
+        return false;
     }
 
     /**
@@ -584,8 +581,13 @@
      * @hide
      */
     @UnsupportedAppUsage
-    public int getDataRoamingType() {
-        return mDataRoamingType;
+    public @RoamingType int getDataRoamingType() {
+        final NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState != null) {
+            return regState.getRoamingType();
+        }
+        return ROAMING_TYPE_NOT_ROAMING;
     }
 
     /**
@@ -758,8 +760,6 @@
         return Objects.hash(
                 mVoiceRegState,
                 mDataRegState,
-                mVoiceRoamingType,
-                mDataRoamingType,
                 mChannelNumber,
                 mCellBandwidths,
                 mVoiceOperatorAlphaLong,
@@ -779,7 +779,6 @@
                 mCdmaEriIconIndex,
                 mCdmaEriIconMode,
                 mIsEmergencyOnly,
-                mIsDataRoamingFromRegistration,
                 mIsUsingCarrierAggregation,
                 mLteEarfcnRsrpBoost,
                 mNetworkRegistrationStates);
@@ -793,8 +792,6 @@
         return (mVoiceRegState == s.mVoiceRegState
                 && mDataRegState == s.mDataRegState
                 && mIsManualNetworkSelection == s.mIsManualNetworkSelection
-                && mVoiceRoamingType == s.mVoiceRoamingType
-                && mDataRoamingType == s.mDataRoamingType
                 && mChannelNumber == s.mChannelNumber
                 && Arrays.equals(mCellBandwidths, s.mCellBandwidths)
                 && equalsHandlesNulls(mVoiceOperatorAlphaLong, s.mVoiceOperatorAlphaLong)
@@ -812,7 +809,6 @@
                 && equalsHandlesNulls(mCdmaDefaultRoamingIndicator,
                         s.mCdmaDefaultRoamingIndicator)
                 && mIsEmergencyOnly == s.mIsEmergencyOnly
-                && mIsDataRoamingFromRegistration == s.mIsDataRoamingFromRegistration
                 && mIsUsingCarrierAggregation == s.mIsUsingCarrierAggregation)
                 && (mNetworkRegistrationStates == null ? s.mNetworkRegistrationStates == null :
                         s.mNetworkRegistrationStates != null &&
@@ -932,8 +928,6 @@
             .append(", mChannelNumber=").append(mChannelNumber)
             .append(", duplexMode()=").append(getDuplexMode())
             .append(", mCellBandwidths=").append(Arrays.toString(mCellBandwidths))
-            .append(", mVoiceRoamingType=").append(getRoamingLogString(mVoiceRoamingType))
-            .append(", mDataRoamingType=").append(getRoamingLogString(mDataRoamingType))
             .append(", mVoiceOperatorAlphaLong=").append(mVoiceOperatorAlphaLong)
             .append(", mVoiceOperatorAlphaShort=").append(mVoiceOperatorAlphaShort)
             .append(", mDataOperatorAlphaLong=").append(mDataOperatorAlphaLong)
@@ -950,7 +944,6 @@
             .append(", mCdmaRoamingIndicator=").append(mCdmaRoamingIndicator)
             .append(", mCdmaDefaultRoamingIndicator=").append(mCdmaDefaultRoamingIndicator)
             .append(", mIsEmergencyOnly=").append(mIsEmergencyOnly)
-            .append(", mIsDataRoamingFromRegistration=").append(mIsDataRoamingFromRegistration)
             .append(", mIsUsingCarrierAggregation=").append(mIsUsingCarrierAggregation)
             .append(", mLteEarfcnRsrpBoost=").append(mLteEarfcnRsrpBoost)
             .append(", mNetworkRegistrationStates=").append(mNetworkRegistrationStates)
@@ -961,8 +954,6 @@
         if (DBG) Rlog.d(LOG_TAG, "[ServiceState] setNullState=" + state);
         mVoiceRegState = state;
         mDataRegState = state;
-        mVoiceRoamingType = ROAMING_TYPE_NOT_ROAMING;
-        mDataRoamingType = ROAMING_TYPE_NOT_ROAMING;
         mChannelNumber = -1;
         mCellBandwidths = new int[0];
         mVoiceOperatorAlphaLong = null;
@@ -982,7 +973,6 @@
         mCdmaEriIconIndex = -1;
         mCdmaEriIconMode = -1;
         mIsEmergencyOnly = false;
-        mIsDataRoamingFromRegistration = false;
         mIsUsingCarrierAggregation = false;
         mLteEarfcnRsrpBoost = 0;
         mNetworkRegistrationStates = new ArrayList<>();
@@ -1028,32 +1018,50 @@
     }
 
     public void setRoaming(boolean roaming) {
-        mVoiceRoamingType = (roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
-        mDataRoamingType = mVoiceRoamingType;
+        setVoiceRoaming(roaming);
+        setDataRoaming(roaming);
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public void setVoiceRoaming(boolean roaming) {
-        mVoiceRoamingType = (roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
+        setVoiceRoamingType(roaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
     }
 
     /** @hide */
     @UnsupportedAppUsage
-    public void setVoiceRoamingType(int type) {
-        mVoiceRoamingType = type;
+    public void setVoiceRoamingType(@RoamingType int type) {
+        NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState == null) {
+            regState = new NetworkRegistrationState(
+                    NetworkRegistrationState.DOMAIN_CS, AccessNetworkConstants.TransportType.WWAN,
+                    ServiceState.ROAMING_TYPE_NOT_ROAMING, TelephonyManager.NETWORK_TYPE_UNKNOWN, 0,
+                    false, null, null);
+            addNetworkRegistrationState(regState);
+        }
+        regState.setRoamingType(type);
     }
 
     /** @hide */
     @UnsupportedAppUsage
     public void setDataRoaming(boolean dataRoaming) {
-        mDataRoamingType = (dataRoaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
+        setDataRoamingType(dataRoaming ? ROAMING_TYPE_UNKNOWN : ROAMING_TYPE_NOT_ROAMING);
     }
 
     /** @hide */
     @UnsupportedAppUsage
-    public void setDataRoamingType(int type) {
-        mDataRoamingType = type;
+    public void setDataRoamingType(@RoamingType int type) {
+        NetworkRegistrationState regState = getNetworkRegistrationState(
+                NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN);
+        if (regState == null) {
+            regState = new NetworkRegistrationState(
+                    NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN,
+                    ServiceState.ROAMING_TYPE_NOT_ROAMING, TelephonyManager.NETWORK_TYPE_UNKNOWN, 0,
+                    false, null, null);
+            addNetworkRegistrationState(regState);
+        }
+        regState.setRoamingType(type);
     }
 
     /**
@@ -1165,30 +1173,10 @@
      */
     @UnsupportedAppUsage
     private void setFromNotifierBundle(Bundle m) {
-        mVoiceRegState = m.getInt("voiceRegState");
-        mDataRegState = m.getInt("dataRegState");
-        mVoiceRoamingType = m.getInt("voiceRoamingType");
-        mDataRoamingType = m.getInt("dataRoamingType");
-        mVoiceOperatorAlphaLong = m.getString("operator-alpha-long");
-        mVoiceOperatorAlphaShort = m.getString("operator-alpha-short");
-        mVoiceOperatorNumeric = m.getString("operator-numeric");
-        mDataOperatorAlphaLong = m.getString("data-operator-alpha-long");
-        mDataOperatorAlphaShort = m.getString("data-operator-alpha-short");
-        mDataOperatorNumeric = m.getString("data-operator-numeric");
-        mIsManualNetworkSelection = m.getBoolean("manual");
-        mRilVoiceRadioTechnology = m.getInt("radioTechnology");
-        mRilDataRadioTechnology = m.getInt("dataRadioTechnology");
-        mCssIndicator = m.getBoolean("cssIndicator");
-        mNetworkId = m.getInt("networkId");
-        mSystemId = m.getInt("systemId");
-        mCdmaRoamingIndicator = m.getInt("cdmaRoamingIndicator");
-        mCdmaDefaultRoamingIndicator = m.getInt("cdmaDefaultRoamingIndicator");
-        mIsEmergencyOnly = m.getBoolean("emergencyOnly");
-        mIsDataRoamingFromRegistration = m.getBoolean("isDataRoamingFromRegistration");
-        mIsUsingCarrierAggregation = m.getBoolean("isUsingCarrierAggregation");
-        mLteEarfcnRsrpBoost = m.getInt("LteEarfcnRsrpBoost");
-        mChannelNumber = m.getInt("ChannelNumber");
-        mCellBandwidths = m.getIntArray("CellBandwidths");
+        ServiceState ssFromBundle = m.getParcelable(Intent.EXTRA_SERVICE_STATE);
+        if (ssFromBundle != null) {
+            copyFrom(ssFromBundle);
+        }
     }
 
     /**
@@ -1199,10 +1187,13 @@
      */
     @UnsupportedAppUsage
     public void fillInNotifierBundle(Bundle m) {
+        m.putParcelable(Intent.EXTRA_SERVICE_STATE, this);
+        // serviceState already consists of below entries.
+        // for backward compatibility, we continue fill in below entries.
         m.putInt("voiceRegState", mVoiceRegState);
         m.putInt("dataRegState", mDataRegState);
-        m.putInt("voiceRoamingType", mVoiceRoamingType);
-        m.putInt("dataRoamingType", mDataRoamingType);
+        m.putInt("dataRoamingType", getDataRoamingType());
+        m.putInt("voiceRoamingType", getVoiceRoamingType());
         m.putString("operator-alpha-long", mVoiceOperatorAlphaLong);
         m.putString("operator-alpha-short", mVoiceOperatorAlphaShort);
         m.putString("operator-numeric", mVoiceOperatorNumeric);
@@ -1218,7 +1209,7 @@
         m.putInt("cdmaRoamingIndicator", mCdmaRoamingIndicator);
         m.putInt("cdmaDefaultRoamingIndicator", mCdmaDefaultRoamingIndicator);
         m.putBoolean("emergencyOnly", mIsEmergencyOnly);
-        m.putBoolean("isDataRoamingFromRegistration", mIsDataRoamingFromRegistration);
+        m.putBoolean("isDataRoamingFromRegistration", getDataRoamingFromRegistration());
         m.putBoolean("isUsingCarrierAggregation", mIsUsingCarrierAggregation);
         m.putInt("LteEarfcnRsrpBoost", mLteEarfcnRsrpBoost);
         m.putInt("ChannelNumber", mChannelNumber);
@@ -1595,7 +1586,7 @@
     /**
      * Get all of the available network registration states.
      *
-     * @return List of registration states
+     * @return List of {@link NetworkRegistrationState}
      * @hide
      */
     @SystemApi
@@ -1606,14 +1597,30 @@
     }
 
     /**
-     * Get the network registration states with given transport type.
+     * Get the network registration states for the transport type.
      *
-     * @param transportType The transport type. See {@link AccessNetworkConstants.TransportType}
-     * @return List of registration states.
+     * @param transportType The {@link AccessNetworkConstants.TransportType transport type}
+     * @return List of {@link NetworkRegistrationState}
+     * @hide
+     *
+     * @deprecated Use {@link #getNetworkRegistrationStatesFromTransportType(int)}
+     */
+    @Deprecated
+    @SystemApi
+    public List<NetworkRegistrationState> getNetworkRegistrationStates(int transportType) {
+        return getNetworkRegistrationStatesForTransportType(transportType);
+    }
+
+    /**
+     * Get the network registration states for the transport type.
+     *
+     * @param transportType The {@link AccessNetworkConstants.TransportType transport type}
+     * @return List of {@link NetworkRegistrationState}
      * @hide
      */
     @SystemApi
-    public List<NetworkRegistrationState> getNetworkRegistrationStates(int transportType) {
+    public List<NetworkRegistrationState> getNetworkRegistrationStatesForTransportType(
+            int transportType) {
         List<NetworkRegistrationState> list = new ArrayList<>();
 
         synchronized (mNetworkRegistrationStates) {
@@ -1628,16 +1635,57 @@
     }
 
     /**
-     * Get the network registration states with given transport type and domain.
+     * Get the network registration states for the network domain.
      *
-     * @param domain The network domain. Must be {@link NetworkRegistrationState#DOMAIN_CS} or
-     * {@link NetworkRegistrationState#DOMAIN_PS}.
-     * @param transportType The transport type. See {@link AccessNetworkConstants.TransportType}
-     * @return The matching NetworkRegistrationState.
+     * @param domain The network {@link NetworkRegistrationState.Domain domain}
+     * @return List of {@link NetworkRegistrationState}
      * @hide
      */
     @SystemApi
-    public NetworkRegistrationState getNetworkRegistrationStates(int domain, int transportType) {
+    public List<NetworkRegistrationState> getNetworkRegistrationStatesForDomain(
+            @Domain int domain) {
+        List<NetworkRegistrationState> list = new ArrayList<>();
+
+        synchronized (mNetworkRegistrationStates) {
+            for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) {
+                if (networkRegistrationState.getDomain() == domain) {
+                    list.add(networkRegistrationState);
+                }
+            }
+        }
+
+        return list;
+    }
+
+    /**
+     * Get the network registration state for the transport type and network domain.
+     *
+     * @param domain The network {@link NetworkRegistrationState.Domain domain}
+     * @param transportType The {@link AccessNetworkConstants.TransportType transport type}
+     * @return The matching {@link NetworkRegistrationState}
+     * @hide
+     *
+     * @deprecated Use {@link #getNetworkRegistrationState(int, int)}
+     */
+    @Deprecated
+    @SystemApi
+    public NetworkRegistrationState getNetworkRegistrationStates(@Domain int domain,
+                                                                 int transportType) {
+        return getNetworkRegistrationState(domain, transportType);
+    }
+
+    /**
+     * Get the network registration state for the transport type and network domain.
+     *
+     * @param domain The network {@link NetworkRegistrationState.Domain domain}
+     * @param transportType The {@link AccessNetworkConstants.TransportType transport type}
+     * @return The matching {@link NetworkRegistrationState}
+     * @hide
+     *
+     */
+    @SystemApi
+    public NetworkRegistrationState getNetworkRegistrationState(@Domain int domain,
+                                                                int transportType) {
         synchronized (mNetworkRegistrationStates) {
             for (NetworkRegistrationState networkRegistrationState : mNetworkRegistrationStates) {
                 if (networkRegistrationState.getTransportType() == transportType
@@ -1669,5 +1717,4 @@
             mNetworkRegistrationStates.add(regState);
         }
     }
-
 }
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index cc143d6..7f87c4d 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -32,12 +32,14 @@
 import android.annotation.UnsupportedAppUsage;
 import android.app.BroadcastOptions;
 import android.app.PendingIntent;
+import android.app.job.JobService;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.database.ContentObserver;
 import android.net.INetworkPolicyManager;
 import android.net.NetworkCapabilities;
 import android.net.Uri;
@@ -87,11 +89,9 @@
     public static final int INVALID_PHONE_INDEX = -1;
 
     /** Indicates invalid sim slot. This can be returned by {@link #getSlotIndex(int)}. */
-    public static final int INVALID_SIM_SLOT_INDEX = -2;
+    public static final int INVALID_SIM_SLOT_INDEX = -1;
 
-    /** Indicates the caller wants the default sub id. */
-    /** @hide */
-    @UnsupportedAppUsage
+    /** Indicates the default subscription ID in Telephony. */
     public static final int DEFAULT_SUBSCRIPTION_ID = Integer.MAX_VALUE;
 
     /**
@@ -117,6 +117,52 @@
     @UnsupportedAppUsage
     public static final Uri CONTENT_URI = Uri.parse("content://telephony/siminfo");
 
+
+    /**
+     * Generates a content {@link Uri} used to receive updates on simInfo change
+     * on the given subscriptionId
+     * @param subscriptionId the subscriptionId to receive updates on
+     * @return the Uri used to observe carrier identity changes
+     * @hide
+     */
+    public static Uri getUriForSubscriptionId(int subscriptionId) {
+        return Uri.withAppendedPath(CONTENT_URI, String.valueOf(subscriptionId));
+    }
+
+    /**
+     * A content {@link Uri} used to receive updates on wfc enabled user setting.
+     * <p>
+     * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
+     * subscription wfc enabled {@link SubscriptionManager#WFC_IMS_ENABLED}
+     * while your app is running. You can also use a {@link JobService} to ensure your app
+     * is notified of changes to the {@link Uri} even when it is not running.
+     * Note, however, that using a {@link JobService} does not guarantee timely delivery of
+     * updates to the {@link Uri}.
+     * To be notified of changes to a specific subId, append subId to the URI
+     * {@link Uri#withAppendedPath(Uri, String)}.
+     * @hide
+     */
+    @SystemApi
+    public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc");
+
+    /**
+     * A content {@link Uri} used to receive updates on enhanced 4g user setting.
+     * <p>
+     * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
+     * subscription enhanced 4G enabled {@link SubscriptionManager#ENHANCED_4G_MODE_ENABLED}
+     * while your app is running. You can also use a {@link JobService} to ensure your app
+     * is notified of changes to the {@link Uri} even when it is not running.
+     * Note, however, that using a {@link JobService} does not guarantee timely delivery of
+     * updates to the {@link Uri}.
+     * To be notified of changes to a specific subId, append subId to the URI
+     * {@link Uri#withAppendedPath(Uri, String)}.
+     * @hide
+     */
+    @SystemApi
+    public static final Uri ENHANCED_4G_ENABLED_CONTENT_URI = Uri.withAppendedPath(
+            CONTENT_URI, "enhanced_4g");
+
+
     /**
      * TelephonyProvider unique key column name is the subscription id.
      * <P>Type: TEXT (String)</P>
@@ -138,8 +184,9 @@
     /** @hide */
     public static final String SIM_SLOT_INDEX = "sim_id";
 
-    /** Indicates SIM is not inserted. This can be returned by {@link #getSlotIndex(int)}. */
-    public static final int SIM_NOT_INSERTED = -3;
+    /** SIM is not inserted */
+    /** @hide */
+    public static final int SIM_NOT_INSERTED = -1;
 
     /**
      * TelephonyProvider column name for user displayed name.
@@ -1264,20 +1311,14 @@
      * Get slotIndex associated with the subscription.
      *
      * @param subscriptionId the unique SubscriptionInfo index in database
-     * @return slotIndex as a positive integer or a negative value,
-     * <ol>
-     * <li>{@link #INVALID_SUBSCRIPTION_ID} if the supplied subscriptionId is invalid </li>
-     * <li>{@link #SIM_NOT_INSERTED} if sim is not inserted </li>
-     * <li>{@link #INVALID_SIM_SLOT_INDEX} if the supplied subscriptionId doesn't have an
-     *     associated slot index </li>
-     * </ol>
+     * @return slotIndex as a positive integer or {@link #INVALID_SIM_SLOT_INDEX} if the supplied
+     * subscriptionId doesn't have an associated slot index.
      */
     public static int getSlotIndex(int subscriptionId) {
         if (!isValidSubscriptionId(subscriptionId)) {
             if (DBG) {
-                logd("[getSlotIndex]- supplied subscriptionId is invalid. ");
+                logd("[getSlotIndex]- supplied subscriptionId is invalid.");
             }
-            return INVALID_SUBSCRIPTION_ID;
         }
 
         int result = INVALID_SIM_SLOT_INDEX;
@@ -1606,6 +1647,19 @@
     }
 
     /**
+     * Check if the subscription ID is usable.
+     *
+     * A usable subscription ID has a valid value except some special values such as
+     * {@link #DEFAULT_SUBSCRIPTION_ID}. It can be used for subscription functions.
+     *
+     * @param subscriptionId the subscription ID
+     * @return {@code true} if the subscription ID is usable; {@code false} otherwise.
+     */
+    public static boolean isUsableSubscriptionId(int subscriptionId) {
+        return isUsableSubIdValue(subscriptionId);
+    }
+
+    /**
      * @return true if subId is an usable subId value else false. A
      * usable subId means its neither a INVALID_SUBSCRIPTION_ID nor a DEFAULT_SUB_ID.
      * @hide
@@ -2152,24 +2206,25 @@
     }
 
     /**
-     * Set preferred default data.
-     * Set on which slot most cellular data will be on.
-     * It's also usually what we set up internet connection on.
+     * Set which subscription is preferred for cellular data.
+     * It's also usually the subscription we set up internet connection on.
      *
      * PreferredData overwrites user setting of default data subscription. And it's used
-     * by AlternativeNetworkAccessService or carrier apps to switch primary and CBRS
+     * by AlternativeNetworkService or carrier apps to switch primary and CBRS
      * subscription dynamically in multi-SIM devices.
      *
-     * @param slotId which slot is preferred to for cellular data. If it's INVALID, it means
-     *               it's unset and defaultDataSubId is used to determine which modem is preferred.
+     * @param subId which subscription is preferred to for cellular data. If it's
+     *              {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}, it means
+     *              it's unset and {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     *              is used to determine which modem is preferred.
      * @hide
      *
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-    public void setPreferredData(int slotId) {
-        if (VDBG) logd("[setPreferredData]+ slotId:" + slotId);
+    public void setPreferredData(int subId) {
+        if (VDBG) logd("[setPreferredData]+ subId:" + subId);
         setSubscriptionPropertyHelper(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                "setPreferredData", (iSub)-> iSub.setPreferredData(slotId));
+                "setPreferredData", (iSub)-> iSub.setPreferredData(subId));
     }
 
     /**
@@ -2178,9 +2233,10 @@
      *  Provide all available user downloaded profiles on phone which are used only for
      *  opportunistic data.
      *  @param slotIndex slot on which the profiles are queried from.
+     *  @return the list of opportunistic subscription info. If none exists, an empty list. 
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public List<SubscriptionInfo> getOpportunisticSubscriptions(int slotIndex) {
+    public @NonNull List<SubscriptionInfo> getOpportunisticSubscriptions(int slotIndex) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         List<SubscriptionInfo> subInfoList = null;
 
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index ea9ac39..69901d2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -60,14 +60,16 @@
 import android.telephony.ims.aidl.IImsMmTelFeature;
 import android.telephony.ims.aidl.IImsRcsFeature;
 import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telecom.ITelecomService;
 import com.android.internal.telephony.CellNetworkScanResult;
-import com.android.internal.telephony.IAnas;
+import com.android.internal.telephony.IAns;
 import com.android.internal.telephony.IPhoneSubInfo;
 import com.android.internal.telephony.ITelephony;
 import com.android.internal.telephony.ITelephonyRegistry;
@@ -168,7 +170,6 @@
     /** @hide */
     static public final int OTASP_SIM_UNPROVISIONED = 5;
 
-
     /** @hide */
     static public final int KEY_TYPE_EPDG = 1;
 
@@ -706,7 +707,7 @@
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @Deprecated
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    @UnsupportedAppUsage
     public static final String ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED =
             "android.intent.action.PRECISE_DATA_CONNECTION_STATE_CHANGED";
 
@@ -1163,6 +1164,16 @@
     public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID";
 
     /**
+     * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates
+     * the updated mno carrier id of the current subscription.
+     * <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or
+     * the carrier cannot be identified.
+     *
+     *@hide
+     */
+    public static final String EXTRA_MNO_CARRIER_ID = "android.telephony.extra.MNO_CARRIER_ID";
+
+    /**
      * An string extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which
      * indicates the updated carrier name of the current subscription.
      * {@see TelephonyManager#getSimCarrierIdName()}
@@ -1221,6 +1232,38 @@
      */
     public static final String EXTRA_RECOVERY_ACTION = "recoveryAction";
 
+     /**
+     * Broadcast intent action indicating that the telephony provider DB got lost.
+     *
+     * <p>
+     * The {@link #EXTRA_IS_CORRUPTED} extra indicates whether the database is lost
+     * due to corruption or not
+     *
+     * <p class="note">
+     * Requires the MODIFY_PHONE_STATE permission.
+     *
+     * <p class="note">
+     * This is a protected intent that can only be sent by the system.
+     *
+     * @see #EXTRA_IS_CORRUPTED
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public static final String ACTION_MMSSMS_DATABASE_LOST =
+            "android.intent.action.MMSSMS_DATABASE_LOST";
+
+    /**
+     * A boolean extra used with {@link #ACTION_MMSSMS_DATABASE_LOST} to indicate
+     * whether the database is lost due to corruption or not.
+     *
+     * @see #ACTION_MMSSMS_DATABASE_LOST
+     *
+     * @hide
+     */
+    public static final String EXTRA_IS_CORRUPTED = "isCorrupted";
+
     //
     //
     // Device Info
@@ -1268,15 +1311,18 @@
      * Returns the unique device ID, for example, the IMEI for GSM and the MEID
      * or ESN for CDMA phones. Return null if device ID is not available.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. 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.
      *
      * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
      * MEID for CDMA.
      */
     @Deprecated
-    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner.
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getDeviceId() {
         try {
             ITelephony telephony = getITelephony();
@@ -1294,8 +1340,11 @@
      * Returns the unique device ID of a subscription, for example, the IMEI for
      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. 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.
      *
      * @param slotIndex of which deviceID is returned
      *
@@ -1303,8 +1352,8 @@
      * MEID for CDMA.
      */
     @Deprecated
-    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner.
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getDeviceId(int slotIndex) {
         // FIXME this assumes phoneId == slotIndex
         try {
@@ -1323,11 +1372,14 @@
      * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
      * available.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. 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.
      */
-    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner.
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getImei() {
         return getImei(getSlotIndex());
     }
@@ -1336,13 +1388,16 @@
      * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
      * available.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. 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.
      *
      * @param slotIndex of which IMEI is returned
      */
-    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner.
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getImei(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -1386,11 +1441,14 @@
     /**
      * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. 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.
      */
-    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner.
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getMeid() {
         return getMeid(getSlotIndex());
     }
@@ -1398,13 +1456,16 @@
     /**
      * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
+     * device or profile owner and have the READ_PHONE_STATE permission. 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.
      *
      * @param slotIndex of which MEID is returned
      */
-    @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @SuppressAutoDoc // No support for device / profile owner.
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getMeid(int slotIndex) {
         ITelephony telephony = getITelephony();
         if (telephony == null) return null;
@@ -1601,8 +1662,7 @@
             ITelephony telephony = getITelephony();
             if (telephony == null)
                 return null;
-            return telephony.getNeighboringCellInfo(mContext.getOpPackageName(),
-                    mContext.getApplicationInfo().targetSdkVersion);
+            return telephony.getNeighboringCellInfo(mContext.getOpPackageName());
         } catch (RemoteException ex) {
             return null;
         } catch (NullPointerException ex) {
@@ -1705,7 +1765,7 @@
     }
 
     /** {@hide} */
-    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    @UnsupportedAppUsage
     private int getPhoneTypeFromProperty(int phoneId) {
         String type = getTelephonyProperty(phoneId,
                 TelephonyProperties.CURRENT_ACTIVE_PHONE, null);
@@ -2430,39 +2490,46 @@
      *
      * These are the ordinal value of IccCardConstants.State.
      */
-    public static final int SIM_STATE_UNKNOWN = 0;
+
+    public static final int SIM_STATE_UNKNOWN = TelephonyProtoEnums.SIM_STATE_UNKNOWN;  // 0
     /** SIM card state: no SIM card is available in the device */
-    public static final int SIM_STATE_ABSENT = 1;
+    public static final int SIM_STATE_ABSENT = TelephonyProtoEnums.SIM_STATE_ABSENT;  // 1
     /** SIM card state: Locked: requires the user's SIM PIN to unlock */
-    public static final int SIM_STATE_PIN_REQUIRED = 2;
+    public static final int SIM_STATE_PIN_REQUIRED =
+            TelephonyProtoEnums.SIM_STATE_PIN_REQUIRED;  // 2
     /** SIM card state: Locked: requires the user's SIM PUK to unlock */
-    public static final int SIM_STATE_PUK_REQUIRED = 3;
+    public static final int SIM_STATE_PUK_REQUIRED =
+            TelephonyProtoEnums.SIM_STATE_PUK_REQUIRED;  // 3
     /** SIM card state: Locked: requires a network PIN to unlock */
-    public static final int SIM_STATE_NETWORK_LOCKED = 4;
+    public static final int SIM_STATE_NETWORK_LOCKED =
+            TelephonyProtoEnums.SIM_STATE_NETWORK_LOCKED;  // 4
     /** SIM card state: Ready */
-    public static final int SIM_STATE_READY = 5;
+    public static final int SIM_STATE_READY = TelephonyProtoEnums.SIM_STATE_READY;  // 5
     /** SIM card state: SIM Card is NOT READY */
-    public static final int SIM_STATE_NOT_READY = 6;
+    public static final int SIM_STATE_NOT_READY = TelephonyProtoEnums.SIM_STATE_NOT_READY;  // 6
     /** SIM card state: SIM Card Error, permanently disabled */
-    public static final int SIM_STATE_PERM_DISABLED = 7;
+    public static final int SIM_STATE_PERM_DISABLED =
+            TelephonyProtoEnums.SIM_STATE_PERM_DISABLED;  // 7
     /** SIM card state: SIM Card Error, present but faulty */
-    public static final int SIM_STATE_CARD_IO_ERROR = 8;
+    public static final int SIM_STATE_CARD_IO_ERROR =
+            TelephonyProtoEnums.SIM_STATE_CARD_IO_ERROR;  // 8
     /** SIM card state: SIM Card restricted, present but not usable due to
      * carrier restrictions.
      */
-    public static final int SIM_STATE_CARD_RESTRICTED = 9;
+    public static final int SIM_STATE_CARD_RESTRICTED =
+            TelephonyProtoEnums.SIM_STATE_CARD_RESTRICTED;  // 9
     /**
      * SIM card state: Loaded: SIM card applications have been loaded
      * @hide
      */
     @SystemApi
-    public static final int SIM_STATE_LOADED = 10;
+    public static final int SIM_STATE_LOADED = TelephonyProtoEnums.SIM_STATE_LOADED;  // 10
     /**
      * SIM card state: SIM Card is present
      * @hide
      */
     @SystemApi
-    public static final int SIM_STATE_PRESENT = 11;
+    public static final int SIM_STATE_PRESENT = TelephonyProtoEnums.SIM_STATE_PRESENT;  // 11
 
     /**
      * Extra included in {@link #ACTION_SIM_CARD_STATE_CHANGED} and
@@ -2888,11 +2955,15 @@
      * Returns the serial number of the SIM, if applicable. Return null if it is
      * unavailable.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <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.
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getSimSerialNumber() {
          return getSimSerialNumber(getSubId());
     }
@@ -2900,11 +2971,18 @@
     /**
      * Returns the serial number for the given subscription, if applicable. Return null if it is
      * unavailable.
-     * <p>
+     *
+     * <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.
+     *
      * @param subId for which Sim Serial number is returned
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @UnsupportedAppUsage
     public String getSimSerialNumber(int subId) {
         try {
@@ -2925,7 +3003,7 @@
      * of time the mode may be unknown.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * @return {@link PhoneConstants#LTE_ON_CDMA_UNKNOWN}, {@link PhoneConstants#LTE_ON_CDMA_FALSE}
      * or {@link PhoneConstants#LTE_ON_CDMA_TRUE}
@@ -3039,11 +3117,15 @@
      * Returns the unique subscriber ID, for example, the IMSI for a GSM phone.
      * Return null if it is unavailable.
      *
-     * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
-     * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     * <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.
      */
     @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     public String getSubscriberId() {
         return getSubscriberId(getSubId());
     }
@@ -3053,10 +3135,17 @@
      * for a subscription.
      * Return null if it is unavailable.
      *
+     * <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.
+     *
      * @param subId whose subscriber id is returned
      * @hide
      */
-    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
     @UnsupportedAppUsage
     public String getSubscriberId(int subId) {
         try {
@@ -4391,8 +4480,8 @@
         return ITelephonyRegistry.Stub.asInterface(ServiceManager.getService("telephony.registry"));
     }
 
-    private IAnas getIAnas() {
-        return IAnas.Stub.asInterface(ServiceManager.getService("ianas"));
+    private IAns getIAns() {
+        return IAns.Stub.asInterface(ServiceManager.getService("ians"));
     }
 
     //
@@ -5357,7 +5446,7 @@
     @UnsupportedAppUsage
     public static String getTelephonyProperty(String property, String defaultVal) {
         String propVal = SystemProperties.get(property);
-        return propVal == null ? defaultVal : propVal;
+        return TextUtils.isEmpty(propVal) ? defaultVal : propVal;
     }
 
     /** @hide */
@@ -5930,7 +6019,7 @@
      * Sets the network selection mode to automatic.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -5955,7 +6044,7 @@
      * Perform a radio scan and return the list of available networks.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p> Note that this scan can take a long time (sometimes minutes) to happen.
      *
@@ -6034,7 +6123,7 @@
      * Ask the radio to connect to the input network and change selection mode to manual.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -6059,7 +6148,7 @@
      * Ask the radio to connect to the input network and change selection mode to manual.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p>Requires Permission:
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
@@ -6092,7 +6181,7 @@
      * Get the network selection mode.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
 
      * @return the network selection mode.
      *
@@ -6824,6 +6913,60 @@
     }
 
     /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"RADIO_POWER_"},
+            value = {RADIO_POWER_OFF,
+                    RADIO_POWER_ON,
+                    RADIO_POWER_UNAVAILABLE,
+            })
+    public @interface RadioPowerState {}
+
+    /**
+     * Radio explicitly powered off (e.g, airplane mode).
+     * @hide
+     */
+    @SystemApi
+    public static final int RADIO_POWER_OFF = 0;
+
+    /**
+     * Radio power is on.
+     * @hide
+     */
+    @SystemApi
+    public static final int RADIO_POWER_ON = 1;
+
+    /**
+     * Radio power unavailable (eg, modem resetting or not booted).
+     * @hide
+     */
+    @SystemApi
+    public static final int RADIO_POWER_UNAVAILABLE = 2;
+
+    /**
+     * @return current modem radio state.
+     *
+     * <p>Requires permission: {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or
+     * {@link android.Manifest.permission#READ_PHONE_STATE} or that the calling
+     * app has carrier privileges (see {@link #hasCarrierPrivileges}).
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+            android.Manifest.permission.READ_PHONE_STATE})
+    public @RadioPowerState int getRadioPowerState() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.getRadioPowerState(getSlotIndex(), mContext.getOpPackageName());
+            }
+        } catch (RemoteException ex) {
+            // This could happen if binder process crashes.
+        }
+        return RADIO_POWER_UNAVAILABLE;
+    }
+
+    /** @hide */
     @SystemApi
     @SuppressLint("Doclava125")
     public void updateServiceLocation() {
@@ -6982,7 +7125,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                isDataRoamingEnabled = telephony.isDataRoamingEnabled(getSubId());
+                isDataRoamingEnabled = telephony.isDataRoamingEnabled(
+                        getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#isDataRoamingEnabled", e);
@@ -6994,7 +7138,7 @@
      * Gets the roaming mode for CDMA phone.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * @return one of {@link #CDMA_ROAMING_MODE_RADIO_DEFAULT}, {@link #CDMA_ROAMING_MODE_HOME},
      * {@link #CDMA_ROAMING_MODE_AFFILIATED}, {@link #CDMA_ROAMING_MODE_ANY}.
@@ -7019,7 +7163,7 @@
      * Sets the roaming mode for CDMA phone to the given mode {@code mode}.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * @param mode should be one of {@link #CDMA_ROAMING_MODE_RADIO_DEFAULT},
      * {@link #CDMA_ROAMING_MODE_HOME}, {@link #CDMA_ROAMING_MODE_AFFILIATED},
@@ -7088,7 +7232,8 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                telephony.setDataRoamingEnabled(getSubId(), isEnabled);
+                telephony.setDataRoamingEnabled(
+                        getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), isEnabled);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelephony#setDataRoamingEnabled", e);
@@ -7292,7 +7437,9 @@
     @UnsupportedAppUsage
     public boolean isVolteAvailable() {
         try {
-            return getITelephony().isVolteAvailable(getSubId());
+            return getITelephony().isAvailable(getSubId(),
+                    MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE,
+                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE, getOpPackageName());
         } catch (RemoteException | NullPointerException ex) {
             return false;
         }
@@ -7881,7 +8028,7 @@
      * Returns the current {@link ServiceState} information.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      * or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
@@ -8231,20 +8378,31 @@
     }
 
     /**
-     * Action set from carrier signalling broadcast receivers to enable/disable metered apns
-     * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required
-     * @param subId the subscription ID that this action applies to.
-     * @param enabled control enable or disable metered apns.
+     * Used to enable or disable carrier data by the system based on carrier signalling or
+     * carrier privileged apps. Different from {@link #setDataEnabled(boolean)} which is linked to
+     * user settings, carrier data on/off won't affect user settings but will bypass the
+     * settings and turns off data internally if set to {@code false}.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     *
+     * <p>Requires Permission:
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}.
+     *
+     * @param enabled control enable or disable carrier data.
      * @hide
      */
-    public void carrierActionSetMeteredApnsEnabled(int subId, boolean enabled) {
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public void setCarrierDataEnabled(boolean enabled) {
         try {
             ITelephony service = getITelephony();
             if (service != null) {
-                service.carrierActionSetMeteredApnsEnabled(subId, enabled);
+                service.carrierActionSetMeteredApnsEnabled(
+                        getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enabled);
             }
         } catch (RemoteException e) {
-            Log.e(TAG, "Error calling ITelephony#carrierActionSetMeteredApnsEnabled", e);
+            Log.e(TAG, "Error calling ITelephony#setCarrierDataEnabled", e);
         }
     }
 
@@ -8350,7 +8508,7 @@
      * Checks if phone is in emergency callback mode.
      *
      * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
-     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}
      *
      * @return true if phone is in emergency callback mode.
      * @hide
@@ -8381,6 +8539,29 @@
     }
 
     /**
+     * Checks if manual network selection is allowed.
+     *
+     * <p>If this object has been created with {@link #createForSubscriptionId}, applies to the
+     * given subId. Otherwise, applies to {@link SubscriptionManager#getDefaultSubscriptionId()}.
+     *
+     * @return {@code true} if manual network selection is allowed, otherwise return {@code false}.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public boolean isManualNetworkSelectionAllowed() {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.isManualNetworkSelectionAllowed(getSubId());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error calling ITelephony#isManualNetworkSelectionAllowed", e);
+        }
+        return true;
+    }
+
+    /**
      * Get the most recently available signal strength information.
      *
      * Get the most recent SignalStrength information reported by the modem. Due
@@ -8579,10 +8760,10 @@
     }
 
     /**
-     * Enable or disable AlternativeNetworkAccessService.
+     * Enable or disable AlternativeNetworkService.
      *
      * This method should be called to enable or disable
-     * AlternativeNetworkAccess service on the device.
+     * AlternativeNetwork service on the device.
      *
      * <p>
      * Requires Permission:
@@ -8593,25 +8774,25 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-    public boolean setAlternativeNetworkAccessState(boolean enable) {
+    public boolean setAlternativeNetworkState(boolean enable) {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         boolean ret = false;
         try {
-            IAnas iAlternativeAccessService = getIAnas();
-            if (iAlternativeAccessService != null) {
-                ret = iAlternativeAccessService.setEnable(enable, pkgForDebug);
+            IAns iAlternativeNetworkService = getIAns();
+            if (iAlternativeNetworkService != null) {
+                ret = iAlternativeNetworkService.setEnable(enable, pkgForDebug);
             }
         } catch (RemoteException ex) {
-            Rlog.e(TAG, "enableAlternativeNetworkAccess RemoteException", ex);
+            Rlog.e(TAG, "enableAlternativeNetwork RemoteException", ex);
         }
 
         return ret;
     }
 
     /**
-     * is AlternativeNetworkAccessService enabled
+     * is AlternativeNetworkService enabled
      *
-     * This method should be called to determine if the AlternativeNetworkAccessService is
+     * This method should be called to determine if the AlternativeNetworkService is
      * enabled
      *
      * <p>
@@ -8620,17 +8801,17 @@
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
-    public boolean isAlternativeNetworkAccessEnabled() {
+    public boolean isAlternativeNetworkEnabled() {
         String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
         boolean isEnabled = false;
 
         try {
-            IAnas iAlternativeAccessService = getIAnas();
-            if (iAlternativeAccessService != null) {
-                isEnabled = iAlternativeAccessService.isEnabled(pkgForDebug);
+            IAns iAlternativeNetworkService = getIAns();
+            if (iAlternativeNetworkService != null) {
+                isEnabled = iAlternativeNetworkService.isEnabled(pkgForDebug);
             }
         } catch (RemoteException ex) {
-            Rlog.e(TAG, "enableAlternativeNetworkAccess RemoteException", ex);
+            Rlog.e(TAG, "enableAlternativeNetwork RemoteException", ex);
         }
 
         return isEnabled;
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index c2c93da..aabefe3 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -80,7 +80,7 @@
      */
     public static final int TYPE_ALL = ApnTypes.ALL;
     /** APN type for default data traffic. */
-    public static final int TYPE_DEFAULT = ApnTypes.DEFAULT;
+    public static final int TYPE_DEFAULT = ApnTypes.DEFAULT | ApnTypes.HIPRI;
     /** APN type for MMS traffic. */
     public static final int TYPE_MMS = ApnTypes.MMS;
     /** APN type for SUPL assisted GPS. */
@@ -257,7 +257,7 @@
 
     private final int mProfileId;
 
-    private final boolean mModemCognitive;
+    private final boolean mPersistent;
     private final int mMaxConns;
     private final int mWaitTime;
     private final int mMaxConnsTime;
@@ -290,13 +290,13 @@
     }
 
     /**
-     * Returns if the APN setting is to be set in modem.
+     * Returns if the APN setting is persistent on the modem.
      *
      * @return is the APN setting to be set in modem
      * @hide
      */
-    public boolean getModemCognitive() {
-        return mModemCognitive;
+    public boolean isPersistent() {
+        return mPersistent;
     }
 
     /**
@@ -616,7 +616,7 @@
         this.mCarrierEnabled = builder.mCarrierEnabled;
         this.mNetworkTypeBitmask = builder.mNetworkTypeBitmask;
         this.mProfileId = builder.mProfileId;
-        this.mModemCognitive = builder.mModemCognitive;
+        this.mPersistent = builder.mModemCognitive;
         this.mMaxConns = builder.mMaxConns;
         this.mWaitTime = builder.mWaitTime;
         this.mMaxConnsTime = builder.mMaxConnsTime;
@@ -740,7 +740,7 @@
                 apn.mProxyAddress, apn.mProxyPort, apn.mMmsc, apn.mMmsProxyAddress,
                 apn.mMmsProxyPort, apn.mUser, apn.mPassword, apn.mAuthType, apn.mApnTypeBitmask,
                 apn.mProtocol, apn.mRoamingProtocol, apn.mCarrierEnabled, apn.mNetworkTypeBitmask,
-                apn.mProfileId, apn.mModemCognitive, apn.mMaxConns, apn.mWaitTime,
+                apn.mProfileId, apn.mPersistent, apn.mMaxConns, apn.mWaitTime,
                 apn.mMaxConnsTime, apn.mMtu, apn.mMvnoType, apn.mMvnoMatchData, apn.mApnSetId);
     }
 
@@ -947,7 +947,7 @@
         sb.append(", ").append(PROTOCOL_INT_MAP.get(mRoamingProtocol));
         sb.append(", ").append(mCarrierEnabled);
         sb.append(", ").append(mProfileId);
-        sb.append(", ").append(mModemCognitive);
+        sb.append(", ").append(mPersistent);
         sb.append(", ").append(mMaxConns);
         sb.append(", ").append(mWaitTime);
         sb.append(", ").append(mMaxConnsTime);
@@ -979,7 +979,7 @@
             return false;
         }
         // DEFAULT can handle HIPRI.
-        if (hasApnType(type) || (type == TYPE_HIPRI && hasApnType(TYPE_DEFAULT))) {
+        if (hasApnType(type)) {
             return true;
         }
         return false;
@@ -1029,7 +1029,7 @@
                 && Objects.equals(mMmsc, other.mMmsc)
                 && Objects.equals(mMmsProxyAddress, other.mMmsProxyAddress)
                 && Objects.equals(mMmsProxyPort, other.mMmsProxyPort)
-                && Objects.equals(mProxyPort,other.mProxyPort)
+                && Objects.equals(mProxyPort, other.mProxyPort)
                 && Objects.equals(mUser, other.mUser)
                 && Objects.equals(mPassword, other.mPassword)
                 && Objects.equals(mAuthType, other.mAuthType)
@@ -1038,7 +1038,7 @@
                 && Objects.equals(mRoamingProtocol, other.mRoamingProtocol)
                 && Objects.equals(mCarrierEnabled, other.mCarrierEnabled)
                 && Objects.equals(mProfileId, other.mProfileId)
-                && Objects.equals(mModemCognitive, other.mModemCognitive)
+                && Objects.equals(mPersistent, other.mPersistent)
                 && Objects.equals(mMaxConns, other.mMaxConns)
                 && Objects.equals(mWaitTime, other.mWaitTime)
                 && Objects.equals(mMaxConnsTime, other.mMaxConnsTime)
@@ -1080,11 +1080,11 @@
                 && Objects.equals(mPassword, other.mPassword)
                 && Objects.equals(mAuthType, other.mAuthType)
                 && Objects.equals(mApnTypeBitmask, other.mApnTypeBitmask)
-                && (isDataRoaming || Objects.equals(mProtocol,other.mProtocol))
+                && (isDataRoaming || Objects.equals(mProtocol, other.mProtocol))
                 && (!isDataRoaming || Objects.equals(mRoamingProtocol, other.mRoamingProtocol))
                 && Objects.equals(mCarrierEnabled, other.mCarrierEnabled)
                 && Objects.equals(mProfileId, other.mProfileId)
-                && Objects.equals(mModemCognitive, other.mModemCognitive)
+                && Objects.equals(mPersistent, other.mPersistent)
                 && Objects.equals(mMaxConns, other.mMaxConns)
                 && Objects.equals(mWaitTime, other.mWaitTime)
                 && Objects.equals(mMaxConnsTime, other.mMaxConnsTime)
@@ -1206,7 +1206,8 @@
 
     /** @hide */
     public static int getMvnoTypeIntFromString(String mvnoType) {
-        Integer mvnoTypeInt = MVNO_TYPE_STRING_MAP.get(mvnoType);
+        String mvnoTypeString = TextUtils.isEmpty(mvnoType) ? mvnoType : mvnoType.toLowerCase();
+        Integer mvnoTypeInt = MVNO_TYPE_STRING_MAP.get(mvnoTypeString);
         return  mvnoTypeInt == null ? UNSPECIFIED_INT : mvnoTypeInt;
     }
 
diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java
index e8597b2..da4822c 100644
--- a/telephony/java/android/telephony/data/DataProfile.java
+++ b/telephony/java/android/telephony/data/DataProfile.java
@@ -68,17 +68,15 @@
 
     private final int mMtu;
 
-    private final String mMvnoType;
+    private final boolean mPersistent;
 
-    private final String mMvnoMatchData;
+    private final boolean mPreferred;
 
-    private final boolean mModemCognitive;
-
-    public DataProfile(int profileId, String apn, String protocol, int authType,
-                String userName, String password, int type, int maxConnsTime, int maxConns,
-                int waitTime, boolean enabled, int supportedApnTypesBitmap, String roamingProtocol,
-                int bearerBitmap, int mtu, String mvnoType, String mvnoMatchData,
-                boolean modemCognitive) {
+    /** @hide */
+    public DataProfile(int profileId, String apn, String protocol, int authType, String userName,
+                       String password, int type, int maxConnsTime, int maxConns, int waitTime,
+                       boolean enabled, int supportedApnTypesBitmap, String roamingProtocol,
+                       int bearerBitmap, int mtu, boolean persistent, boolean preferred) {
 
         this.mProfileId = profileId;
         this.mApn = apn;
@@ -100,11 +98,11 @@
         this.mRoamingProtocol = roamingProtocol;
         this.mBearerBitmap = bearerBitmap;
         this.mMtu = mtu;
-        this.mMvnoType = mvnoType;
-        this.mMvnoMatchData = mvnoMatchData;
-        this.mModemCognitive = modemCognitive;
+        this.mPersistent = persistent;
+        this.mPreferred = preferred;
     }
 
+    /** @hide */
     public DataProfile(Parcel source) {
         mProfileId = source.readInt();
         mApn = source.readString();
@@ -121,9 +119,8 @@
         mRoamingProtocol = source.readString();
         mBearerBitmap = source.readInt();
         mMtu = source.readInt();
-        mMvnoType = source.readString();
-        mMvnoMatchData = source.readString();
-        mModemCognitive = source.readBoolean();
+        mPersistent = source.readBoolean();
+        mPreferred = source.readBoolean();
     }
 
     /**
@@ -207,23 +204,17 @@
     public int getMtu() { return mMtu; }
 
     /**
-     * @return The MVNO type: possible values are "imsi", "gid", "spn".
+     * @return {@code true} if modem must persist this data profile.
      */
-    public String getMvnoType() { return mMvnoType; }
+    public boolean isPersistent() { return mPersistent; }
 
     /**
-     * @return The MVNO match data. For example,
-     * SPN: A MOBILE, BEN NL, ...
-     * IMSI: 302720x94, 2060188, ...
-     * GID: 4E, 33, ...
+     * @return {@code true} if this data profile was used to bring up the last default
+     * (i.e internet) data connection successfully.
      */
-    public String getMvnoMatchData() { return mMvnoMatchData; }
+    public boolean isPreferred() { return  mPreferred; }
 
-    /**
-     * @return True if the data profile was sent to the modem through setDataProfile earlier.
-     */
-    public boolean isModemCognitive() { return mModemCognitive; }
-
+    /** @hide */
     @Override
     public int describeContents() {
         return 0;
@@ -233,11 +224,11 @@
     public String toString() {
         return "DataProfile=" + mProfileId + "/" + mProtocol + "/" + mAuthType
                 + "/" + (Build.IS_USER ? "***/***/***" :
-                         (mApn + "/" + mUserName + "/" + mPassword))
-                + "/" + mType + "/" + mMaxConnsTime
-                + "/" + mMaxConns + "/" + mWaitTime + "/" + mEnabled + "/"
-                + mSupportedApnTypesBitmap + "/" + mRoamingProtocol + "/" + mBearerBitmap + "/"
-                + mMtu + "/" + mMvnoType + "/" + mMvnoMatchData + "/" + mModemCognitive;
+                         (mApn + "/" + mUserName + "/" + mPassword)) + "/" + mType + "/"
+                + mMaxConnsTime + "/" + mMaxConns + "/"
+                + mWaitTime + "/" + mEnabled + "/" + mSupportedApnTypesBitmap + "/"
+                + mRoamingProtocol + "/" + mBearerBitmap + "/" + mMtu + "/" + mPersistent + "/"
+                + mPreferred;
     }
 
     @Override
@@ -246,6 +237,7 @@
         return (o == this || toString().equals(o.toString()));
     }
 
+    /** @hide */
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mProfileId);
@@ -263,11 +255,11 @@
         dest.writeString(mRoamingProtocol);
         dest.writeInt(mBearerBitmap);
         dest.writeInt(mMtu);
-        dest.writeString(mMvnoType);
-        dest.writeString(mMvnoMatchData);
-        dest.writeBoolean(mModemCognitive);
+        dest.writeBoolean(mPersistent);
+        dest.writeBoolean(mPreferred);
     }
 
+    /** @hide */
     public static final Parcelable.Creator<DataProfile> CREATOR =
             new Parcelable.Creator<DataProfile>() {
         @Override
diff --git a/proto/src/stats_enums.proto b/telephony/java/android/telephony/emergency/EmergencyNumber.aidl
similarity index 63%
copy from proto/src/stats_enums.proto
copy to telephony/java/android/telephony/emergency/EmergencyNumber.aidl
index 6c892cf..bfb0a59 100644
--- a/proto/src/stats_enums.proto
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (c) 2018, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * 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,
@@ -14,13 +14,6 @@
  * limitations under the License.
  */
 
-syntax = "proto2";
+package android.telephony.emergency;
 
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "StatsEnums";
-
-enum EventType {
-  // Unknown.
-  TYPE_UNKNOWN = 0;
-}
+parcelable EmergencyNumber;
diff --git a/telephony/java/android/telephony/emergency/EmergencyNumber.java b/telephony/java/android/telephony/emergency/EmergencyNumber.java
new file mode 100644
index 0000000..bdba8c8
--- /dev/null
+++ b/telephony/java/android/telephony/emergency/EmergencyNumber.java
@@ -0,0 +1,434 @@
+/*
+ * 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.emergency;
+
+import android.annotation.IntDef;
+import android.hardware.radio.V1_3.EmergencyNumberSource;
+import android.hardware.radio.V1_3.EmergencyServiceCategory;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A parcelable class that wraps and retrieves the information of number, service category(s) and
+ * country code for a specific emergency number.
+ */
+public final class EmergencyNumber implements Parcelable, Comparable<EmergencyNumber> {
+
+    private static final String LOG_TAG = "EmergencyNumber";
+
+    /**
+     * Defining Emergency Service Category as follows:
+     *  - General emergency call, all categories;
+     *  - Police;
+     *  - Ambulance;
+     *  - Fire Brigade;
+     *  - Marine Guard;
+     *  - Mountain Rescue;
+     *  - Manually Initiated eCall (MIeC);
+     *  - Automatically Initiated eCall (AIeC);
+     *
+     * Category UNSPECIFIED (General emergency call, all categories) indicates that no specific
+     * services are associated with this emergency number; if the emergency number is specified,
+     * it has one or more defined emergency service categories.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     *
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "EMERGENCY_SERVICE_CATEGORY_" }, value = {
+            EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+            EMERGENCY_SERVICE_CATEGORY_POLICE,
+            EMERGENCY_SERVICE_CATEGORY_AMBULANCE,
+            EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE,
+            EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD,
+            EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE,
+            EMERGENCY_SERVICE_CATEGORY_MIEC,
+            EMERGENCY_SERVICE_CATEGORY_AIEC
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EmergencyServiceCategories {}
+
+    /**
+     * Emergency Service Category UNSPECIFIED (General emergency call, all categories) bit-field
+     * indicates that no specific services are associated with this emergency number; if the
+     * emergency number is specified, it has one or more defined emergency service categories.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED =
+            EmergencyServiceCategory.UNSPECIFIED;
+    /**
+     * Bit-field that indicates Emergency Service Category for Police.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_POLICE = EmergencyServiceCategory.POLICE;
+    /**
+     * Bit-field that indicates Emergency Service Category for Ambulance.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_AMBULANCE =
+            EmergencyServiceCategory.AMBULANCE;
+    /**
+     * Bit-field that indicates Emergency Service Category for Fire Brigade.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE =
+            EmergencyServiceCategory.FIRE_BRIGADE;
+    /**
+     * Bit-field that indicates Emergency Service Category for Marine Guard.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD =
+            EmergencyServiceCategory.MARINE_GUARD;
+    /**
+     * Bit-field that indicates Emergency Service Category for Mountain Rescue.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE =
+            EmergencyServiceCategory.MOUNTAIN_RESCUE;
+    /**
+     * Bit-field that indicates Emergency Service Category for Manually Initiated eCall (MIeC)
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_MIEC = EmergencyServiceCategory.MIEC;
+    /**
+     * Bit-field that indicates Emergency Service Category for Automatically Initiated eCall (AIeC)
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_SERVICE_CATEGORY_AIEC = EmergencyServiceCategory.AIEC;
+
+    private static final Set<Integer> EMERGENCY_SERVICE_CATEGORY_SET;
+    static {
+        EMERGENCY_SERVICE_CATEGORY_SET = new HashSet<Integer>();
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_POLICE);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_AMBULANCE);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_FIRE_BRIGADE);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MARINE_GUARD);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MOUNTAIN_RESCUE);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_MIEC);
+        EMERGENCY_SERVICE_CATEGORY_SET.add(EMERGENCY_SERVICE_CATEGORY_AIEC);
+    }
+
+    /**
+     * The source to tell where the corresponding @1.3::EmergencyNumber comes from.
+     *
+     * The emergency number has one or more defined emergency number sources.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     *
+     * @hide
+     */
+    @IntDef(flag = true, prefix = { "EMERGENCY_NUMBER_SOURCE_" }, value = {
+            EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING,
+            EMERGENCY_NUMBER_SOURCE_SIM,
+            EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG,
+            EMERGENCY_NUMBER_SOURCE_DEFAULT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EmergencyNumberSources {}
+
+    /**
+     * Bit-field which indicates the number is from the network signaling.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING =
+            EmergencyNumberSource.NETWORK_SIGNALING;
+    /**
+     * Bit-field which indicates the number is from the sim.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_NUMBER_SOURCE_SIM = EmergencyNumberSource.SIM;
+    /** Bit-field which indicates the number is from the modem config. */
+    public static final int EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG =
+            EmergencyNumberSource.MODEM_CONFIG;
+    /**
+     * Bit-field which indicates the number is available as default.
+     *
+     * 112, 911 must always be available; additionally, 000, 08, 110, 999, 118 and 119 must be
+     * available when sim is not present.
+     *
+     * Reference: 3gpp 22.101, Section 10 - Emergency Calls
+     */
+    public static final int EMERGENCY_NUMBER_SOURCE_DEFAULT = EmergencyNumberSource.DEFAULT;
+
+    private static final Set<Integer> EMERGENCY_NUMBER_SOURCE_SET;
+    static {
+        EMERGENCY_NUMBER_SOURCE_SET = new HashSet<Integer>();
+        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING);
+        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_SIM);
+        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG);
+        EMERGENCY_NUMBER_SOURCE_SET.add(EMERGENCY_NUMBER_SOURCE_DEFAULT);
+    }
+
+    private final String mNumber;
+    private final String mCountryIso;
+    private final int mEmergencyServiceCategoryBitmask;
+    private final int mEmergencyNumberSourceBitmask;
+
+    /** @hide */
+    public EmergencyNumber(String number, String countryIso,
+                           int emergencyServiceCategories,
+                           int emergencyNumberSources) {
+        this.mNumber = number;
+        this.mCountryIso = countryIso;
+        this.mEmergencyServiceCategoryBitmask = emergencyServiceCategories;
+        this.mEmergencyNumberSourceBitmask = emergencyNumberSources;
+    }
+
+    /** @hide */
+    public EmergencyNumber(Parcel source) {
+        mNumber = source.readString();
+        mCountryIso = source.readString();
+        mEmergencyServiceCategoryBitmask = source.readInt();
+        mEmergencyNumberSourceBitmask = source.readInt();
+    }
+
+    /**
+     * Get the dialing number of the emergency number.
+     *
+     * The character in the number string is only the dial pad
+     * character('0'-'9', '*', or '#'). For example: 911.
+     *
+     * @return the dialing number.
+     */
+    public String getNumber() {
+        return mNumber;
+    }
+
+    /**
+     * Get the country code string (lowercase character) in ISO 3166 format of the emergency number.
+     *
+     * @return the country code string (lowercase character) in ISO 3166 format.
+     */
+    public String getCountryIso() {
+        return mCountryIso;
+    }
+
+    /**
+     * Returns the bitmask of emergency service categories of the emergency number.
+     *
+     * @return bitmask of the emergency service categories
+     */
+    public @EmergencyServiceCategories int getEmergencyServiceCategoryBitmask() {
+        return mEmergencyServiceCategoryBitmask;
+    }
+
+    /**
+     * Returns the emergency service categories of the emergency number.
+     *
+     * Note: if the emergency number is in {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}, only
+     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED} is returned and it means the number is in
+     * all categories.
+     *
+     * @return a list of the emergency service categories
+     */
+    public List<Integer> getEmergencyServiceCategories() {
+        List<Integer> categories = new ArrayList<>();
+        if (serviceUnspecified()) {
+            categories.add(EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED);
+            return categories;
+        }
+        for (Integer category : EMERGENCY_SERVICE_CATEGORY_SET) {
+            if (isInEmergencyServiceCategories(category)) {
+                categories.add(category);
+            }
+        }
+        return categories;
+    }
+
+    /**
+     * Checks if the emergency service category is unspecified for the emergency number
+     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}.
+     *
+     * @return {@code true} if the emergency service category is unspecified for the emergency
+     * number {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}; {@code false} otherwise.
+     */
+    private boolean serviceUnspecified() {
+        return mEmergencyServiceCategoryBitmask == EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED;
+    }
+
+    /**
+     * Checks if the emergency number is in the supplied emergency service category(s).
+     *
+     * @param categories - the supplied emergency service categories
+     *
+     * @return {@code true} if the emergency number is in the specified emergency service
+     * category(s) or if its emergency service category is
+     * {@link #EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED}; {@code false} otherwise.
+     */
+    public boolean isInEmergencyServiceCategories(@EmergencyServiceCategories int categories) {
+        if (categories == EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED) {
+            return serviceUnspecified();
+        }
+        if (serviceUnspecified()) {
+            return true;
+        }
+        return (mEmergencyServiceCategoryBitmask & categories) == categories;
+    }
+
+    /**
+     * Returns the bitmask of the sources of the emergency number.
+     *
+     * @return bitmask of the emergency number sources
+     */
+    public @EmergencyNumberSources int getEmergencyNumberSourceBitmask() {
+        return mEmergencyNumberSourceBitmask;
+    }
+
+    /**
+     * Returns a list of sources of the emergency number.
+     *
+     * @return a list of emergency number sources
+     */
+    public List<Integer> getEmergencyNumberSources() {
+        List<Integer> sources = new ArrayList<>();
+        for (Integer source : EMERGENCY_NUMBER_SOURCE_SET) {
+            if ((mEmergencyNumberSourceBitmask & source) == source) {
+                sources.add(source);
+            }
+        }
+        return sources;
+    }
+
+    /**
+     * Checks if the emergency number is from the specified emergency number source(s).
+     *
+     * @return {@code true} if the emergency number is from the specified emergency number
+     * source(s); {@code false} otherwise.
+     *
+     * @param sources - the supplied emergency number sources
+     */
+    public boolean isFromSources(@EmergencyNumberSources int sources) {
+        return (mEmergencyNumberSourceBitmask & sources) == sources;
+    }
+
+    @Override
+    /** @hide */
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mNumber);
+        dest.writeString(mCountryIso);
+        dest.writeInt(mEmergencyServiceCategoryBitmask);
+        dest.writeInt(mEmergencyNumberSourceBitmask);
+    }
+
+    @Override
+    /** @hide */
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "EmergencyNumber = " + "[Number]" + mNumber + " / [CountryIso]" + mCountryIso
+                + " / [ServiceCategories]"
+                + Integer.toBinaryString(mEmergencyServiceCategoryBitmask)
+                + " / [Sources]" + Integer.toBinaryString(mEmergencyNumberSourceBitmask);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!EmergencyNumber.class.isInstance(o)) {
+            return false;
+        }
+        return (o == this || toString().equals(o.toString()));
+    }
+
+    /**
+     * Calculate the score for display priority.
+     *
+     * A higher display priority score means the emergency number has a higher display priority.
+     * The score is higher if the source is defined for a higher display priority.
+     *
+     * The priority of sources are defined as follows:
+     *     EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING >
+     *     EMERGENCY_NUMBER_SOURCE_SIM >
+     *     EMERGENCY_NUMBER_SOURCE_DEFAULT >
+     *     EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG
+     *
+     */
+    private int getDisplayPriorityScore() {
+        int score = 0;
+        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_NETWORK_SIGNALING)) {
+            score += 1 << 4;
+        }
+        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_SIM)) {
+            score += 1 << 3;
+        }
+        // TODO add a score if the number comes from Google's emergency number database
+        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_DEFAULT)) {
+            score += 1 << 1;
+        }
+        if (this.isFromSources(EMERGENCY_NUMBER_SOURCE_MODEM_CONFIG)) {
+            score += 1 << 0;
+        }
+        return score;
+    }
+
+    /**
+     * Compare the display priority for this emergency number and the supplied emergency number.
+     *
+     * @param emergencyNumber the supplied emergency number
+     * @return a negative value if the supplied emergency number has a lower display priority;
+     *         a positive value if the supplied emergency number has a higher display priority;
+     *         0 if both have equal display priority.
+     */
+    @Override
+    public int compareTo(EmergencyNumber emergencyNumber) {
+        if (this.getDisplayPriorityScore()
+                > emergencyNumber.getDisplayPriorityScore()) {
+            return -1;
+        } else if (this.getDisplayPriorityScore()
+                < emergencyNumber.getDisplayPriorityScore()) {
+            return 1;
+        } else {
+            /**
+             * TODO if both numbers have the same display priority score, the number matches the
+             * Google's emergency number database has a higher display priority.
+             */
+            return 0;
+        }
+    }
+
+    public static final Parcelable.Creator<EmergencyNumber> CREATOR =
+            new Parcelable.Creator<EmergencyNumber>() {
+        @Override
+        public EmergencyNumber createFromParcel(Parcel in) {
+            return new EmergencyNumber(in);
+        }
+
+        @Override
+        public EmergencyNumber[] newArray(int size) {
+            return new EmergencyNumber[size];
+        }
+    };
+}
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 5d6a8c1..89ef339 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -117,12 +117,14 @@
      * @hide
      */
     public static final String EXTRA_CONFERENCE = "conference";
+
     /**
      * Boolean extra property set on an {@link ImsCallProfile} to indicate that this call is an
      * emergency call.  The {@link ImsService} sets this on a call to indicate that the network has
      * identified the call as an emergency call.
      */
-    public static final String EXTRA_E_CALL = "e_call";
+    public static final String EXTRA_EMERGENCY_CALL = "e_call";
+
     /**
      * @hide
      */
diff --git a/telephony/java/android/telephony/ims/ImsCallSession.java b/telephony/java/android/telephony/ims/ImsCallSession.java
index a20d4f5..df903cc2 100644
--- a/telephony/java/android/telephony/ims/ImsCallSession.java
+++ b/telephony/java/android/telephony/ims/ImsCallSession.java
@@ -16,22 +16,16 @@
 
 package android.telephony.ims;
 
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
 import android.os.Message;
 import android.os.RemoteException;
 import android.telephony.ims.aidl.IImsCallSessionListener;
-
-import java.util.Objects;
-import java.util.concurrent.Executor;
-
-import android.telephony.ims.stub.ImsCallSessionImplBase;
 import android.util.Log;
 
 import com.android.ims.internal.IImsCallSession;
 import com.android.ims.internal.IImsVideoCallProvider;
 
+import java.util.Objects;
+
 /**
  * Provides the call initiation/termination, and media exchange between two IMS endpoints.
  * It directly communicates with IMS service which implements the IMS protocol behavior.
@@ -42,7 +36,8 @@
     private static final String TAG = "ImsCallSession";
 
     /**
-     * Defines IMS call session state. Please use {@link ImsCallSessionImplBase.State} definition.
+     * Defines IMS call session state. Please use
+     * {@link android.telephony.ims.stub.ImsCallSessionImplBase.State} definition.
      * This is kept around for capability reasons.
      */
     public static class State {
@@ -1027,9 +1022,9 @@
     }
 
     /**
-     * Sends RTT Upgrade request
+     * Sends RTT Upgrade or downgrade request
      *
-     * @param to   : expected profile
+     * @param to Profile with the RTT flag set to the desired value
      */
     public void sendRttModifyRequest(ImsCallProfile to) {
         if (mClosed) {
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index 8d18ae8..f2d0cbf 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -16,22 +16,19 @@
 
 package android.telephony.ims;
 
+import android.annotation.IntDef;
 import android.annotation.SystemApi;
-import android.annotation.UnsupportedAppUsage;
 import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.telecom.Log;
 import android.telephony.Rlog;
 
-/*
- * This file contains all the api's through which
- * information received in Dialog Event Package can be
- * queried
- */
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 
 /**
- * Parcelable object to handle MultiEndpoint Dialog Information
+ * Parcelable object to handle MultiEndpoint Dialog Event Package Information.
  * @hide
  */
 @SystemApi
@@ -40,8 +37,39 @@
     private static final String TAG = "ImsExternalCallState";
 
     // Dialog States
+    /**
+     * The external call is in the confirmed dialog state.
+     */
     public static final int CALL_STATE_CONFIRMED = 1;
+    /**
+     * The external call is in the terminated dialog state.
+     */
     public static final int CALL_STATE_TERMINATED = 2;
+
+    /**@hide*/
+    @IntDef(flag = true,
+            value = {
+                    CALL_STATE_CONFIRMED,
+                    CALL_STATE_TERMINATED
+            },
+            prefix = "CALL_STATE_")
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ExternalCallState {}
+
+    /**@hide*/
+    @IntDef(flag = true,
+            value = {
+                    ImsCallProfile.CALL_TYPE_VOICE,
+                    ImsCallProfile.CALL_TYPE_VT_TX,
+                    ImsCallProfile.CALL_TYPE_VT_RX,
+                    ImsCallProfile.CALL_TYPE_VT
+            },
+            prefix = "CALL_TYPE_")
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ExternalCallType {}
+
+
+
     // Dialog Id
     private int mCallId;
     // Number
@@ -58,10 +86,9 @@
     public ImsExternalCallState() {
     }
 
-    /** @hide */
-    @UnsupportedAppUsage
-    public ImsExternalCallState(int callId, Uri address, boolean isPullable, int callState,
-            int callType, boolean isCallheld) {
+    /**@hide*/
+    public ImsExternalCallState(int callId, Uri address, boolean isPullable,
+            @ExternalCallState int callState, int callType, boolean isCallheld) {
         mCallId = callId;
         mAddress = address;
         mIsPullable = isPullable;
@@ -71,9 +98,10 @@
         Rlog.d(TAG, "ImsExternalCallState = " + this);
     }
 
-    /** @hide */
+    /**@hide*/
     public ImsExternalCallState(int callId, Uri address, Uri localAddress,
-            boolean isPullable, int callState, int callType, boolean isCallheld) {
+            boolean isPullable, @ExternalCallState int callState, int callType,
+            boolean isCallheld) {
         mCallId = callId;
         mAddress = address;
         mLocalAddress = localAddress;
@@ -84,6 +112,31 @@
         Rlog.d(TAG, "ImsExternalCallState = " + this);
     }
 
+    /**
+     * Create a new ImsExternalCallState instance to contain Multiendpoint Dialog information.
+     * @param callId The unique ID of the call, which will be used to identify this external
+     *               connection.
+     * @param address A {@link Uri} containing the remote address of this external connection.
+     * @param localAddress A {@link Uri} containing the local address information.
+     * @param isPullable A flag determining if this external connection can be pulled to the current
+     *         device.
+     * @param callState The state of the external call.
+     * @param callType The type of external call.
+     * @param isCallheld A flag determining if the external connection is currently held.
+     */
+    public ImsExternalCallState(String callId, Uri address, Uri localAddress,
+            boolean isPullable, @ExternalCallState int callState, @ExternalCallType int callType,
+            boolean isCallheld) {
+        mCallId = getIdForString(callId);
+        mAddress = address;
+        mLocalAddress = localAddress;
+        mIsPullable = isPullable;
+        mCallState = callState;
+        mCallType = callType;
+        mIsHeld = isCallheld;
+        Rlog.d(TAG, "ImsExternalCallState = " + this);
+    }
+
     /** @hide */
     public ImsExternalCallState(Parcel in) {
         mCallId = in.readInt();
@@ -135,7 +188,9 @@
         return mAddress;
     }
 
-    /** @hide */
+    /**
+     * @return A {@link Uri} containing the local address from the Multiendpoint Dialog Information.
+     */
     public Uri getLocalAddress() {
         return mLocalAddress;
     }
@@ -144,11 +199,11 @@
         return mIsPullable;
     }
 
-    public int getCallState() {
+    public @ExternalCallState int getCallState() {
         return mCallState;
     }
 
-    public int getCallType() {
+    public @ExternalCallType int getCallType() {
         return mCallType;
     }
 
@@ -166,4 +221,15 @@
                 ", mCallType = " + mCallType +
                 ", mIsHeld = " + mIsHeld + "}";
     }
+
+    private int getIdForString(String idString) {
+        try {
+            return Integer.parseInt(idString);
+        } catch (NumberFormatException e) {
+            // In the case that there are alphanumeric characters, we will create a hash of the
+            // String value as a backup.
+            // TODO: Modify call IDs to use Strings as keys instead of integers in telephony/telecom
+            return idString.hashCode();
+        }
+    }
 }
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
new file mode 100644
index 0000000..c9cf473
--- /dev/null
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -0,0 +1,760 @@
+/*
+ * 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;
+
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
+import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.feature.MmTelFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+
+import com.android.internal.telephony.ITelephony;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * A manager for the MmTel (Multimedia Telephony) feature of an IMS network, given an associated
+ * subscription.
+ *
+ * Allows a user to query the IMS MmTel feature information for a subscription, register for
+ * registration and MmTel capability status callbacks, as well as query/modify user settings for the
+ * associated subscription.
+ *
+ * @see #createForSubscriptionId(Context, int)
+ * @hide
+ */
+public class ImsMmTelManager {
+
+    private static final String TAG = "ImsMmTelManager";
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "WIFI_MODE_", value = {
+            WIFI_MODE_WIFI_ONLY,
+            WIFI_MODE_CELLULAR_PREFERRED,
+            WIFI_MODE_WIFI_PREFERRED
+            })
+    public @interface WiFiCallingMode {}
+
+    /**
+     * Register for IMS over IWLAN if WiFi signal quality is high enough. Do not hand over to LTE
+     * registration if signal quality degrades.
+     * @hide
+     */
+    @SystemApi
+    public static final int WIFI_MODE_WIFI_ONLY = 0;
+
+    /**
+     * Prefer registering for IMS over LTE if LTE signal quality is high enough.
+     * @hide
+     */
+    @SystemApi
+    public static final int WIFI_MODE_CELLULAR_PREFERRED = 1;
+
+    /**
+     * Prefer registering for IMS over IWLAN if possible if WiFi signal quality is high enough.
+     * @hide
+     */
+    @SystemApi
+    public static final int WIFI_MODE_WIFI_PREFERRED = 2;
+
+    /**
+     * Callback class for receiving Registration callback events.
+     * @see #addImsRegistrationCallback(Executor, RegistrationCallback) (RegistrationCallback)
+     * @see #removeImsRegistrationCallback(RegistrationCallback)
+     */
+    public static class RegistrationCallback {
+
+        private static class RegistrationBinder extends IImsRegistrationCallback.Stub {
+
+            private final RegistrationCallback mLocalCallback;
+            private Executor mExecutor;
+
+            RegistrationBinder(RegistrationCallback localCallback) {
+                mLocalCallback = localCallback;
+            }
+
+            @Override
+            public void onRegistered(int imsRadioTech) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() -> mLocalCallback.onRegistered(imsRadioTech)));
+            }
+
+            @Override
+            public void onRegistering(int imsRadioTech) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() -> mLocalCallback.onRegistering(imsRadioTech)));
+            }
+
+            @Override
+            public void onDeregistered(ImsReasonInfo info) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() -> mLocalCallback.onDeregistered(info)));
+            }
+
+            @Override
+            public void onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() ->
+                                mLocalCallback.onTechnologyChangeFailed(imsRadioTech, info)));
+            }
+
+            @Override
+            public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() ->
+                                mLocalCallback.onSubscriberAssociatedUriChanged(uris)));
+            }
+
+            private void setExecutor(Executor executor) {
+                mExecutor = executor;
+            }
+        }
+
+        private final RegistrationBinder mBinder = new RegistrationBinder(this);
+
+        /**
+         * Notifies the framework when the IMS Provider is registered to the IMS network.
+         *
+         * @param imsRadioTech the radio access technology. Valid values are defined in
+         * {@link ImsRegistrationImplBase.ImsRegistrationTech}.
+         */
+        public void onRegistered(@ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
+        }
+
+        /**
+         * Notifies the framework when the IMS Provider is trying to register the IMS network.
+         *
+         * @param imsRadioTech the radio access technology. Valid values are defined in
+         * {@link ImsRegistrationImplBase.ImsRegistrationTech}.
+         */
+        public void onRegistering(@ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech) {
+        }
+
+        /**
+         * Notifies the framework when the IMS Provider is deregistered from the IMS network.
+         *
+         * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
+         */
+        public void onDeregistered(ImsReasonInfo info) {
+        }
+
+        /**
+         * A failure has occurred when trying to handover registration to another technology type,
+         * defined in {@link ImsRegistrationImplBase.ImsRegistrationTech}
+         *
+         * @param imsRadioTech The {@link ImsRegistrationImplBase.ImsRegistrationTech} type that has
+         *         failed
+         * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
+         */
+        public void onTechnologyChangeFailed(
+                @ImsRegistrationImplBase.ImsRegistrationTech int imsRadioTech, ImsReasonInfo info) {
+        }
+
+        /**
+         * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
+         * it changes. Per RFC3455, an associated URI is a URI that the service provider has
+         * allocated to a user for their own usage. A user's phone number is typically one of the
+         * associated URIs.
+         * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
+         *         subscription.
+         * @hide
+         */
+        public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+        }
+
+        /**@hide*/
+        public final IImsRegistrationCallback getBinder() {
+            return mBinder;
+        }
+
+        /**@hide*/
+        //Only exposed as public for compatibility with deprecated ImsManager APIs.
+        public void setExecutor(Executor executor) {
+            mBinder.setExecutor(executor);
+        }
+    }
+
+    /**
+     * Receives IMS capability status updates from the ImsService.
+     *
+     * @see #addMmTelCapabilityCallback(Executor, CapabilityCallback) (CapabilityCallback)
+     * @see #removeMmTelCapabilityCallback(CapabilityCallback)
+     */
+    public static class CapabilityCallback {
+
+        private static class CapabilityBinder extends IImsCapabilityCallback.Stub {
+
+            private final CapabilityCallback mLocalCallback;
+            private Executor mExecutor;
+
+            CapabilityBinder(CapabilityCallback c) {
+                mLocalCallback = c;
+            }
+
+            @Override
+            public void onCapabilitiesStatusChanged(int config) {
+                if (mLocalCallback == null) return;
+
+                Binder.withCleanCallingIdentity(() ->
+                        mExecutor.execute(() -> mLocalCallback.onCapabilitiesStatusChanged(
+                                new MmTelFeature.MmTelCapabilities(config))));
+            }
+
+            @Override
+            public void onQueryCapabilityConfiguration(int capability, int radioTech,
+                    boolean isEnabled) {
+                // This is not used for public interfaces.
+            }
+
+            @Override
+            public void onChangeCapabilityConfigurationError(int capability, int radioTech,
+                    @ImsFeature.ImsCapabilityError int reason) {
+                // This is not used for public interfaces
+            }
+
+            private void setExecutor(Executor executor) {
+                mExecutor = executor;
+            }
+        }
+
+        private final CapabilityBinder mBinder = new CapabilityBinder(this);
+
+        /**
+         * The status of the feature's capabilities has changed to either available or unavailable.
+         * If unavailable, the feature is not able to support the unavailable capability at this
+         * time.
+         *
+         * @param capabilities The new availability of the capabilities.
+         */
+        public void onCapabilitiesStatusChanged(
+                MmTelFeature.MmTelCapabilities capabilities) {
+        }
+
+        /**@hide*/
+        public final IImsCapabilityCallback getBinder() {
+            return mBinder;
+        }
+
+        /**@hide*/
+        // Only exposed as public method for compatibility with deprecated ImsManager APIs.
+        // TODO: clean up dependencies and change back to private visibility.
+        public void setExecutor(Executor executor) {
+            mBinder.setExecutor(executor);
+        }
+    }
+
+    private Context mContext;
+    private int mSubId;
+
+    /**
+     * Create an instance of ImsManager for the subscription id specified.
+     *
+     * @param context
+     * @param subId The ID of the subscription that this ImsManager will use.
+     * @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
+     * @throws IllegalArgumentException if the subscription is invalid or
+     *         the subscription ID is not an active subscription.
+     */
+    public static ImsMmTelManager createForSubscriptionId(Context context, int subId) {
+        if (!SubscriptionManager.isValidSubscriptionId(subId)
+                || !getSubscriptionManager(context).isActiveSubscriptionId(subId)) {
+            throw new IllegalArgumentException("Invalid subscription ID");
+        }
+
+        return new ImsMmTelManager(context, subId);
+    }
+
+    private ImsMmTelManager(Context context, int subId) {
+        mContext = context;
+        mSubId = subId;
+    }
+
+    /**
+     * Registers a {@link RegistrationCallback} with the system, which will provide registration
+     * updates for the subscription specified in {@link #createForSubscriptionId(Context, int)}. Use
+     * {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed
+     * events and call {@link #removeImsRegistrationCallback(RegistrationCallback)} to clean up
+     * after a subscription is removed.
+     * @param executor The executor the callback events should be run on.
+     * @param c The {@link RegistrationCallback} to be added.
+     * @see #removeImsRegistrationCallback(RegistrationCallback)
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public void addImsRegistrationCallback(@CallbackExecutor Executor executor,
+            @NonNull RegistrationCallback c) {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        c.setExecutor(executor);
+        try {
+            getITelephony().addImsRegistrationCallback(mSubId, c.getBinder(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Removes an existing {@link RegistrationCallback}. Ensure to call this method when cleaning
+     * up to avoid memory leaks or when the subscription is removed.
+     * @param c The {@link RegistrationCallback} to be removed.
+     * @see SubscriptionManager.OnSubscriptionsChangedListener
+     * @see #addImsRegistrationCallback(Executor, RegistrationCallback)
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public void removeImsRegistrationCallback(@NonNull RegistrationCallback c) {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+        }
+        try {
+            getITelephony().removeImsRegistrationCallback(mSubId, c.getBinder(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Registers a {@link CapabilityCallback} with the system, which will provide MmTel capability
+     * updates for the subscription specified in {@link #createForSubscriptionId(Context, int)}.
+     * Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to
+     * subscription changed events and call
+     * {@link #removeImsRegistrationCallback(RegistrationCallback)} to clean up after a subscription
+     * is removed.
+     * @param executor The executor the callback events should be run on.
+     * @param c The MmTel {@link CapabilityCallback} to be registered.
+     * @see #removeMmTelCapabilityCallback(CapabilityCallback)
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public void addMmTelCapabilityCallback(@CallbackExecutor Executor executor,
+            @NonNull CapabilityCallback c) {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Must include a non-null Executor.");
+        }
+        c.setExecutor(executor);
+        try {
+            getITelephony().addMmTelCapabilityCallback(mSubId, c.getBinder(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Removes an existing MmTel {@link CapabilityCallback}. Be sure to call this when cleaning
+     * up to avoid memory leaks.
+     * @param c The MmTel {@link CapabilityCallback} to be removed.
+     * @see #addMmTelCapabilityCallback(Executor, CapabilityCallback)
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public void removeMmTelCapabilityCallback(@NonNull CapabilityCallback c) {
+        if (c == null) {
+            throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+        }
+        try {
+            getITelephony().removeMmTelCapabilityCallback(mSubId, c.getBinder(),
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Query the user's setting for whether or not to use MmTel capabilities over IMS,
+     * such as voice and video, depending on carrier configuration for the current subscription.
+     * @see #setAdvancedCallingSetting(boolean)
+     * @return true if the user’s setting for advanced calling is enabled and false otherwise.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isAdvancedCallingSettingEnabled() {
+        try {
+            return getITelephony().isAdvancedCallingSettingEnabled(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Modify the user’s setting for “Advanced Calling” or "Enhanced 4G LTE", which is used to
+     * enable MmTel IMS features, such as voice and video calling, depending on the carrier
+     * configuration for the current subscription. Modifying this value may also trigger an IMS
+     * registration or deregistration, depending on the new value.
+     * @see #isAdvancedCallingEnabled()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setAdvancedCallingSetting(boolean isEnabled) {
+        try {
+            getITelephony().setAdvancedCallingSetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Query the IMS MmTel capability for a given registration technology. This does not
+     * necessarily mean that we are registered and the capability is available, but rather the
+     * subscription is capable of this service over IMS.
+     *
+     * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
+     * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VT_AVAILABLE_BOOL
+     * @see android.telephony.CarrierConfigManager#KEY_CARRIER_IMS_GBA_REQUIRED_BOOL
+     * @see #isAvailable(int, int)
+     *
+     * @param imsRegTech The IMS registration technology, can be one of the following:
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE},
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+     * @param capability The IMS MmTel capability to query, can be one of the following:
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO,
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT},
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
+     * @return {@code true} if the MmTel IMS capability is capable for this subscription, false
+     *         otherwise.
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public boolean isCapable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
+        try {
+            return getITelephony().isCapable(mSubId, capability, imsRegTech,
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Query the availability of an IMS MmTel capability for a given registration technology. If
+     * a capability is available, IMS is registered and the service is currently available over IMS.
+     *
+     * @see #isCapable(int, int)
+     *
+     * @param imsRegTech The IMS registration technology, can be one of the following:
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_LTE},
+     *         {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN}
+     * @param capability The IMS MmTel capability to query, can be one of the following:
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VOICE},
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_VIDEO,
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_UT},
+     *         {@link MmTelFeature.MmTelCapabilities#CAPABILITY_TYPE_SMS}
+     * @return {@code true} if the MmTel IMS capability is available for this subscription, false
+     *         otherwise.
+     */
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public boolean isAvailable(@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
+            @ImsRegistrationImplBase.ImsRegistrationTech int imsRegTech) {
+        try {
+            return getITelephony().isAvailable(mSubId, capability, imsRegTech,
+                    mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * The user's setting for whether or not they have enabled the "Video Calling" setting.
+     * @return true if the user’s “Video Calling” setting is currently enabled.
+     * @see #setVtSetting(boolean)
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+    public boolean isVtSettingEnabled() {
+        try {
+            return getITelephony().isVtSettingEnabled(mSubId, mContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Change the user's setting for Video Telephony and enable the Video Telephony capability.
+     * @see #isVtSettingEnabled()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVtSetting(boolean isEnabled) {
+        try {
+            getITelephony().setVtSetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @return true if the user's setting for Voice over WiFi is enabled and false if it is not.
+     * @see #setVoWiFiSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isVoWiFiSettingEnabled() {
+        try {
+            return getITelephony().isVoWiFiSettingEnabled(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Sets the user's setting for whether or not Voice over WiFi is enabled.
+     * @param isEnabled true if the user's setting for Voice over WiFi is enabled, false otherwise=
+     * @see #isVoWiFiSettingEnabled()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiSetting(boolean isEnabled) {
+        try {
+            getITelephony().setVoWiFiSetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @return true if the user's setting for Voice over WiFi while roaming is enabled, false
+     * if disabled.
+     * @see #setVoWiFiRoamingSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public boolean isVoWiFiRoamingSettingEnabled() {
+        try {
+            return getITelephony().isVoWiFiRoamingSettingEnabled(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Change the user's setting for Voice over WiFi while roaming.
+     * @param isEnabled true if the user's setting for Voice over WiFi while roaming is enabled,
+     *     false otherwise.
+     * @see #isVoWiFiRoamingSettingEnabled()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiRoamingSetting(boolean isEnabled) {
+        try {
+            getITelephony().setVoWiFiRoamingSetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Overrides the Voice over WiFi capability to true for IMS, but do not persist the setting.
+     * Typically used during the Voice over WiFi registration process for some carriers.
+     *
+     * @param isCapable true if the IMS stack should try to register for IMS over IWLAN, false
+     *     otherwise.
+     * @param mode the Voice over WiFi mode preference to set, which can be one of the following:
+     * - {@link #WIFI_MODE_WIFI_ONLY}
+     * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     * - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #setVoWiFiSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiNonPersistent(boolean isCapable, int mode) {
+        try {
+            getITelephony().setVoWiFiNonPersistent(mSubId, isCapable, mode);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @return The Voice over WiFi Mode preference set by the user, which can be one of the
+     * following:
+     * - {@link #WIFI_MODE_WIFI_ONLY}
+     * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     * - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #setVoWiFiSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    public @WiFiCallingMode int getVoWiFiModeSetting() {
+        try {
+            return getITelephony().getVoWiFiModeSetting(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Set the user's preference for Voice over WiFi calling mode.
+     * @param mode The user's preference for the technology to register for IMS over, can be one of
+     *    the following:
+     * - {@link #WIFI_MODE_WIFI_ONLY}
+     * - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     * - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #getVoWiFiModeSetting()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiModeSetting(@WiFiCallingMode int mode) {
+        try {
+            getITelephony().setVoWiFiModeSetting(mSubId, mode);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Set the user's preference for Voice over WiFi calling mode while the device is roaming on
+     * another network.
+     *
+     * @return The user's preference for the technology to register for IMS over when roaming on
+     *     another network, can be one of the following:
+     *     - {@link #WIFI_MODE_WIFI_ONLY}
+     *     - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     *     - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #setVoWiFiRoamingSetting(boolean)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
+        try {
+            return getITelephony().getVoWiFiRoamingModeSetting(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Set the user's preference for Voice over WiFi mode while the device is roaming on another
+     * network.
+     *
+     * @param mode The user's preference for the technology to register for IMS over when roaming on
+     *     another network, can be one of the following:
+     *     - {@link #WIFI_MODE_WIFI_ONLY}
+     *     - {@link #WIFI_MODE_CELLULAR_PREFERRED}
+     *     - {@link #WIFI_MODE_WIFI_PREFERRED}
+     * @see #getVoWiFiRoamingModeSetting()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setVoWiFiRoamingModeSetting(@WiFiCallingMode int mode) {
+        try {
+            getITelephony().setVoWiFiRoamingModeSetting(mSubId, mode);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * Change the user's setting for RTT capability of this device.
+     * @param isEnabled if true RTT will be enabled during calls.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+    public void setRttCapabilitySetting(boolean isEnabled) {
+        try {
+            getITelephony().setRttCapabilitySetting(mSubId, isEnabled);
+            return;
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    /**
+     * @return true if TTY over VoLTE is supported
+     * @see android.telecom.TelecomManager#getCurrentTtyMode
+     * @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+    boolean isTtyOverVolteEnabled() {
+        try {
+            return getITelephony().isTtyOverVolteEnabled(mSubId);
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+    }
+
+    private static SubscriptionManager getSubscriptionManager(Context context) {
+        SubscriptionManager manager = context.getSystemService(SubscriptionManager.class);
+        if (manager == null) {
+            throw new RuntimeException("Could not find SubscriptionManager.");
+        }
+        return manager;
+    }
+
+    private static ITelephony getITelephony() {
+        ITelephony binder = ITelephony.Stub.asInterface(
+                ServiceManager.getService(Context.TELEPHONY_SERVICE));
+        if (binder == null) {
+            throw new RuntimeException("Could not find Telephony Service.");
+        }
+        return binder;
+    }
+}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
index 4f37caa..749b191 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsRegistrationCallback.aidl
@@ -23,7 +23,7 @@
 import android.telephony.ims.ImsReasonInfo;
 
 /**
- * See ImsRegistrationImplBase.Callback for more information.
+ * See {@link ImsManager#RegistrationCallback} for more information.
  *
  * {@hide}
  */
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index b77881e..7f69f43 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -167,59 +167,6 @@
      */
     public static final int CAPABILITY_SUCCESS = 0;
 
-
-    /**
-     * The framework implements this callback in order to register for Feature Capability status
-     * updates, via {@link #onCapabilitiesStatusChanged(Capabilities)}, query Capability
-     * configurations, via {@link #onQueryCapabilityConfiguration}, as well as to receive error
-     * callbacks when the ImsService can not change the capability as requested, via
-     * {@link #onChangeCapabilityConfigurationError}.
-     *
-     * @hide
-     */
-    public static class CapabilityCallback extends IImsCapabilityCallback.Stub {
-
-        @Override
-        public final void onCapabilitiesStatusChanged(int config) throws RemoteException {
-            onCapabilitiesStatusChanged(new Capabilities(config));
-        }
-
-        /**
-         * Returns the result of a query for the capability configuration of a requested capability.
-         *
-         * @param capability The capability that was requested.
-         * @param radioTech The IMS radio technology associated with the capability.
-         * @param isEnabled true if the capability is enabled, false otherwise.
-         */
-        @Override
-        public void onQueryCapabilityConfiguration(int capability, int radioTech,
-                boolean isEnabled) {
-
-        }
-
-        /**
-         * Called when a change to the capability configuration has returned an error.
-         *
-         * @param capability The capability that was requested to be changed.
-         * @param radioTech The IMS radio technology associated with the capability.
-         * @param reason error associated with the failure to change configuration.
-         */
-        @Override
-        public void onChangeCapabilityConfigurationError(int capability, int radioTech,
-                @ImsCapabilityError int reason) {
-        }
-
-        /**
-         * The status of the feature's capabilities has changed to either available or unavailable.
-         * If unavailable, the feature is not able to support the unavailable capability at this
-         * time.
-         *
-         * @param config The new availability of the capabilities.
-         */
-        public void onCapabilitiesStatusChanged(Capabilities config) {
-        }
-    }
-
     /**
      * Used by the ImsFeature to call back to the CapabilityCallback that the framework has
      * provided.
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index 7681aef..9699594 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -17,6 +17,8 @@
 package android.telephony.ims.feature;
 
 import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Bundle;
 import android.os.Message;
@@ -222,21 +224,31 @@
      * This MmTelFeature can then return the status of each of these capabilities (enabled or not)
      * by sending a {@link #notifyCapabilitiesStatusChanged} callback to the framework. The current
      * status can also be queried using {@link #queryCapabilityStatus()}.
+     * @see #isCapable(int)
      */
     public static class MmTelCapabilities extends Capabilities {
 
         /**
-         * @hide
+         * Create a new empty {@link MmTelCapabilities} instance.
+         * @see #addCapabilities(int)
+         * @see #removeCapabilities(int)
          */
         @VisibleForTesting
         public MmTelCapabilities() {
             super();
         }
 
+        /**@deprecated Use {@link MmTelCapabilities} to construct a new instance instead.*/
+        @Deprecated
         public MmTelCapabilities(Capabilities c) {
             mCapabilities = c.mCapabilities;
         }
 
+        /**
+         * Create a new {link @MmTelCapabilities} instance with the provided capabilities.
+         * @param capabilities The capabilities that are supported for MmTel in the form of a
+         *                     bitfield.
+         */
         public MmTelCapabilities(int capabilities) {
             mCapabilities = capabilities;
         }
@@ -406,7 +418,10 @@
      * support the capability that is enabled. A capability that is disabled by the framework (via
      * {@link #changeEnabledCapabilities}) should also show the status as disabled.
      */
-    public final void notifyCapabilitiesStatusChanged(MmTelCapabilities c) {
+    public final void notifyCapabilitiesStatusChanged(@NonNull MmTelCapabilities c) {
+        if (c == null) {
+            throw new IllegalArgumentException("MmTelCapabilities must be non-null!");
+        }
         super.notifyCapabilitiesStatusChanged(c);
     }
 
@@ -414,7 +429,12 @@
      * Notify the framework of an incoming call.
      * @param c The {@link ImsCallSessionImplBase} of the new incoming call.
      */
-    public final void notifyIncomingCall(ImsCallSessionImplBase c, Bundle extras) {
+    public final void notifyIncomingCall(@NonNull ImsCallSessionImplBase c,
+            @NonNull Bundle extras) {
+        if (c == null || extras == null) {
+            throw new IllegalArgumentException("ImsCallSessionImplBase and Bundle can not be "
+                    + "null.");
+        }
         synchronized (mLock) {
             if (mListener == null) {
                 throw new IllegalStateException("Session is not available.");
@@ -434,7 +454,12 @@
      *        This can be null if no call information is available for the rejected call.
      * @param reason The {@link ImsReasonInfo} call rejection reason.
      */
-    public final void notifyRejectedCall(ImsCallProfile callProfile, ImsReasonInfo reason) {
+    public final void notifyRejectedCall(@NonNull ImsCallProfile callProfile,
+            @NonNull ImsReasonInfo reason) {
+        if (callProfile == null || reason == null) {
+            throw new IllegalArgumentException("ImsCallProfile and ImsReasonInfo must not be "
+                    + "null.");
+        }
         synchronized (mLock) {
             if (mListener == null) {
                 throw new IllegalStateException("Session is not available.");
@@ -508,8 +533,8 @@
      * the framework.
      */
     @Override
-    public void changeEnabledCapabilities(CapabilityChangeRequest request,
-            CapabilityCallbackProxy c) {
+    public void changeEnabledCapabilities(@NonNull CapabilityChangeRequest request,
+            @NonNull CapabilityCallbackProxy c) {
         // Base implementation, no-op
     }
 
@@ -531,7 +556,7 @@
      *        {@link ImsCallProfile#CALL_TYPE_VS_RX}
      * @return a {@link ImsCallProfile} object
      */
-    public ImsCallProfile createCallProfile(int callSessionType, int callType) {
+    public @Nullable ImsCallProfile createCallProfile(int callSessionType, int callType) {
         // Base Implementation - Should be overridden
         return null;
     }
@@ -552,7 +577,7 @@
      *
      * @param profile a call profile to make the call
      */
-    public ImsCallSessionImplBase createCallSession(ImsCallProfile profile) {
+    public @Nullable ImsCallSessionImplBase createCallSession(@NonNull ImsCallProfile profile) {
         // Base Implementation - Should be overridden
         return null;
     }
@@ -569,7 +594,7 @@
      * @return a {@link ProcessCallResult} to the framework, which will be used to determine if the
      *        call will be placed over IMS or via CSFB.
      */
-    public @ProcessCallResult int shouldProcessCall(String[] numbers) {
+    public @ProcessCallResult int shouldProcessCall(@NonNull String[] numbers) {
         return PROCESS_CALL_IMS;
     }
 
@@ -602,7 +627,7 @@
      * @return The {@link ImsUtImplBase} Ut interface implementation for the supplementary service
      * configuration.
      */
-    public ImsUtImplBase getUt() {
+    public @NonNull ImsUtImplBase getUt() {
         // Base Implementation - Should be overridden
         return new ImsUtImplBase();
     }
@@ -611,7 +636,7 @@
      * @return The {@link ImsEcbmImplBase} Emergency call-back mode interface for emergency VoLTE
      * calls that support it.
      */
-    public ImsEcbmImplBase getEcbm() {
+    public @NonNull ImsEcbmImplBase getEcbm() {
         // Base Implementation - Should be overridden
         return new ImsEcbmImplBase();
     }
@@ -620,7 +645,7 @@
      * @return The {@link ImsMultiEndpointImplBase} implementation for implementing Dialog event
      * package processing for multi-endpoint.
      */
-    public ImsMultiEndpointImplBase getMultiEndpoint() {
+    public @NonNull ImsMultiEndpointImplBase getMultiEndpoint() {
         // Base Implementation - Should be overridden
         return new ImsMultiEndpointImplBase();
     }
@@ -646,7 +671,7 @@
      *     }
      * }
      */
-    public void setUiTtyMode(int mode, Message onCompleteMessage) {
+    public void setUiTtyMode(int mode, @Nullable Message onCompleteMessage) {
         // Base Implementation - Should be overridden
     }
 
@@ -680,7 +705,7 @@
      * @return an instance of {@link ImsSmsImplBase} which should be implemented by the IMS
      * Provider.
      */
-    public ImsSmsImplBase getSmsImplementation() {
+    public @NonNull ImsSmsImplBase getSmsImplementation() {
         return new ImsSmsImplBase();
     }
 
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index 3138180..a08e031 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -21,12 +21,11 @@
 import android.net.Uri;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.aidl.IImsRegistration;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.util.Log;
 
-import android.telephony.ims.ImsReasonInfo;
-
 import com.android.internal.annotations.VisibleForTesting;
 
 import java.lang.annotation.Retention;
@@ -77,59 +76,6 @@
     private static final int REGISTRATION_STATE_REGISTERING = 1;
     private static final int REGISTRATION_STATE_REGISTERED = 2;
 
-    /**
-     * Callback class for receiving Registration callback events.
-     * @hide
-     */
-    public static class Callback {
-        /**
-         * Notifies the framework when the IMS Provider is connected to the IMS network.
-         *
-         * @param imsRadioTech the radio access technology. Valid values are defined in
-         * {@link ImsRegistrationTech}.
-         */
-        public void onRegistered(@ImsRegistrationTech int imsRadioTech) {
-        }
-
-        /**
-         * Notifies the framework when the IMS Provider is trying to connect the IMS network.
-         *
-         * @param imsRadioTech the radio access technology. Valid values are defined in
-         * {@link ImsRegistrationTech}.
-         */
-        public void onRegistering(@ImsRegistrationTech int imsRadioTech) {
-        }
-
-        /**
-         * Notifies the framework when the IMS Provider is disconnected from the IMS network.
-         *
-         * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
-         */
-        public void onDeregistered(ImsReasonInfo info) {
-        }
-
-        /**
-         * A failure has occurred when trying to handover registration to another technology type,
-         * defined in {@link ImsRegistrationTech}
-         *
-         * @param imsRadioTech The {@link ImsRegistrationTech} type that has failed
-         * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
-         */
-        public void onTechnologyChangeFailed(@ImsRegistrationTech int imsRadioTech,
-                ImsReasonInfo info) {
-        }
-
-        /**
-         * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
-         * it changes.
-         * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
-         *         subscription.
-         */
-        public void onSubscriberAssociatedUriChanged(Uri[] uris) {
-
-        }
-    }
-
     private final IImsRegistration mBinder = new IImsRegistration.Stub() {
 
         @Override
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index 86cb1b7..b0c875e 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -100,6 +100,7 @@
     public static final int EVENT_DATA_RECONNECT = BASE + 47;
     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_PROVISIONING_DATA_SETTING_CHANGE = BASE + 50;
 
     /***** Constants *****/
 
diff --git a/telephony/java/com/android/internal/telephony/IAnas.aidl b/telephony/java/com/android/internal/telephony/IAns.aidl
similarity index 87%
rename from telephony/java/com/android/internal/telephony/IAnas.aidl
rename to telephony/java/com/android/internal/telephony/IAns.aidl
index 88d681a..6eb8d66 100755
--- a/telephony/java/com/android/internal/telephony/IAnas.aidl
+++ b/telephony/java/com/android/internal/telephony/IAns.aidl
@@ -17,13 +17,13 @@
 package com.android.internal.telephony;
 
 
-interface IAnas {
+interface IAns {
 
     /**
-    * Enable or disable Alternative Network Access service.
+    * Enable or disable Alternative Network service.
     *
     * This method should be called to enable or disable
-    * AlternativeNetworkAccess service on the device.
+    * AlternativeNetwork service on the device.
     *
     * <p>
     * Requires Permission:
@@ -37,9 +37,9 @@
     boolean setEnable(boolean enable, String callingPackage);
 
     /**
-     * is Alternative Network Access service enabled
+     * is Alternative Network service enabled
      *
-     * This method should be called to determine if the Alternative Network Access service is enabled
+     * This method should be called to determine if the Alternative Network service is enabled
     *
     * <p>
     * Requires Permission:
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 38a1bc7..9e42f12 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -53,5 +53,6 @@
     void onUserMobileDataStateChanged(in boolean enabled);
     void onPhoneCapabilityChanged(in PhoneCapability capability);
     void onPreferredDataSubIdChanged(in int subId);
+    void onRadioPowerStateChanged(in int state);
 }
 
diff --git a/proto/src/stats_enums.proto b/telephony/java/com/android/internal/telephony/IRcs.aidl
similarity index 76%
copy from proto/src/stats_enums.proto
copy to telephony/java/com/android/internal/telephony/IRcs.aidl
index 6c892cf..ede8695 100644
--- a/proto/src/stats_enums.proto
+++ b/telephony/java/com/android/internal/telephony/IRcs.aidl
@@ -14,13 +14,8 @@
  * limitations under the License.
  */
 
-syntax = "proto2";
+package com.android.internal.telephony;
 
-package android.os.statsd;
-option java_package = "com.android.os";
-option java_outer_classname = "StatsEnums";
-
-enum EventType {
-  // Unknown.
-  TYPE_UNKNOWN = 0;
-}
+interface IRcs {
+    void deleteThread(int threadId);
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index 0ccd748..85b4941 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony;
 
-import android.app.PendingIntent;
 import android.telephony.SubscriptionInfo;
 
 interface ISub {
@@ -175,14 +174,14 @@
     int setParentSubId(int parentSubId, int subId);
 
     /**
-     * Set preferred default data.
-     * Set on which slot default data will be on.
+     * Set which subscription is preferred for cellular data. It's
+     * designed to overwrite default data subscription temporarily.
      *
-     * @param slotId which slot is preferred to for cellular data.
+     * @param subId which subscription is preferred to for cellular data.
      * @hide
      *
      */
-    int setPreferredData(int slotId);
+    int setPreferredData(int subId);
 
     /**
      * Get User downloaded Profiles.
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index ca2bcff..dc23358 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -38,10 +38,12 @@
 import android.telephony.SignalStrength;
 import android.telephony.TelephonyHistogram;
 import android.telephony.VisualVoicemailSmsFilterSettings;
+import android.telephony.ims.aidl.IImsCapabilityCallback;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsMmTelFeature;
 import android.telephony.ims.aidl.IImsRcsFeature;
 import android.telephony.ims.aidl.IImsRegistration;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.OperatorInfo;
@@ -280,7 +282,7 @@
     /**
      * Returns the neighboring cell information of the device.
      */
-    List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg, int targetSdk);
+    List<NeighboringCellInfo> getNeighboringCellInfo(String callingPkg);
 
      int getCallState();
 
@@ -808,6 +810,13 @@
      */
     boolean isDataEnabled(int subId);
 
+     /**
+     * Checks if manual network selection is allowed.
+     *
+     * @return {@code true} if manual network selection is allowed, otherwise return {@code false}.
+     */
+     boolean isManualNetworkSelectionAllowed(int subId);
+
     /**
      * Get P-CSCF address from PCO after data connection is established or modified.
      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
@@ -1050,11 +1059,6 @@
      */
     boolean isWifiCallingAvailable(int subId);
 
-    /**
-     * Returns the Status of VoLTE for the subscription ID specified.
-     */
-    boolean isVolteAvailable(int subId);
-
      /**
      * Returns the Status of VT (video telephony) for the subscription ID specified.
      */
@@ -1492,4 +1496,123 @@
      * Set the default SMS app to a given package on a given user.
      */
     void setDefaultSmsApp(int userId, String packageName);
+
+    /**
+     * Return the modem radio power state for slot index.
+     *
+     */
+    int getRadioPowerState(int slotIndex, String callingPackage);
+
+    // IMS specific AIDL commands, see ImsMmTelManager.java
+
+    /**
+     * Adds an IMS registration status callback for the subscription id specified.
+     */
+    oneway void addImsRegistrationCallback(int subId, IImsRegistrationCallback c,
+            String callingPackage);
+     /**
+      * Removes an existing IMS registration status callback for the subscription specified.
+      */
+    oneway void removeImsRegistrationCallback(int subId, IImsRegistrationCallback c,
+            String callingPackage);
+
+    /**
+     * Adds an IMS MmTel capabilities callback for the subscription specified.
+     */
+    oneway void addMmTelCapabilityCallback(int subId, IImsCapabilityCallback c,
+            String callingPackage);
+
+    /**
+     * Removes an existing IMS MmTel capabilities callback for the subscription specified.
+     */
+    oneway void removeMmTelCapabilityCallback(int subId, IImsCapabilityCallback c,
+            String callingPackage);
+
+    /**
+     * return true if the IMS MmTel capability for the given registration tech is capable.
+     */
+    boolean isCapable(int subId, int capability, int regTech, String callingPackage);
+
+    /**
+     * return true if the IMS MmTel capability for the given registration tech is available.
+     */
+    boolean isAvailable(int subId, int capability, int regTech, String callingPackage);
+
+    /**
+     * Returns true if the user's setting for 4G LTE is enabled, for the subscription specified.
+     */
+    boolean isAdvancedCallingSettingEnabled(int subId);
+
+    /**
+     * Modify the user's setting for whether or not 4G LTE is enabled.
+     */
+    void setAdvancedCallingSetting(int subId, boolean isEnabled);
+
+    /**
+     * return true if the user's setting for VT is enabled for the subscription.
+     */
+    boolean isVtSettingEnabled(int subId, String callingPackage);
+
+    /**
+     * Modify the user's setting for whether or not VT is available for the subscrption specified.
+     */
+    void setVtSetting(int subId, boolean isEnabled);
+
+    /**
+     * return true if the user's setting for whether or not Voice over WiFi is currently enabled.
+     */
+    boolean isVoWiFiSettingEnabled(int subId);
+
+    /**
+     * sets the user's setting for Voice over WiFi enabled state.
+     */
+    void setVoWiFiSetting(int subId, boolean isEnabled);
+
+    /**
+     * return true if the user's setting for Voice over WiFi while roaming is enabled.
+     */
+    boolean isVoWiFiRoamingSettingEnabled(int subId);
+
+    /**
+     * Sets the user's preference for whether or not Voice over WiFi is enabled for the current
+     * subscription while roaming.
+     */
+    void setVoWiFiRoamingSetting(int subId, boolean isEnabled);
+
+    /**
+     * Set the Voice over WiFi enabled state, but do not persist the setting.
+     */
+    void setVoWiFiNonPersistent(int subId, boolean isCapable, int mode);
+
+    /**
+     * return the Voice over WiFi mode preference set by the user for the subscription specified.
+     */
+    int getVoWiFiModeSetting(int subId);
+
+    /**
+     * sets the user's preference for the Voice over WiFi mode for the subscription specified.
+     */
+    void setVoWiFiModeSetting(int subId, int mode);
+
+    /**
+     * return the Voice over WiFi mode preference set by the user for the subscription specified
+     * while roaming.
+     */
+    int getVoWiFiRoamingModeSetting(int subId);
+
+    /**
+     * sets the user's preference for the Voice over WiFi mode for the subscription specified
+     * while roaming.
+     */
+    void setVoWiFiRoamingModeSetting(int subId, int mode);
+
+    /**
+     * Modify the user's setting for whether or not RTT is enabled for the subscrption specified.
+     */
+    void setRttCapabilitySetting(int subId, boolean isEnabled);
+
+    /**
+     * return true if TTY over VoLTE is enabled for the subscription specified.
+     */
+    boolean isTtyOverVolteEnabled(int subId);
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index c03065c..0baf860 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -80,4 +80,5 @@
     void notifyUserMobileDataStateChangedForPhoneId(in int phoneId, in int subId, in boolean state);
     void notifyPhoneCapabilityChanged(in PhoneCapability capability);
     void notifyPreferredDataSubIdChanged(int preferredSubId);
+    void notifyRadioPowerStateChanged(in int state);
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 3a26350..cb8269e 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -420,6 +420,7 @@
     int RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING = 201;
     int RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA = 202;
     int RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA = 203;
+    int RIL_REQUEST_SET_PREFERRED_DATA_MODEM = 204;
 
     /* Responses begin */
     int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java
index 39722c6..5b8028b 100644
--- a/telephony/java/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/java/com/android/internal/telephony/SmsApplication.java
@@ -69,6 +69,15 @@
     private static final String SCHEME_MMSTO = "mmsto";
     private static final boolean DEBUG_MULTIUSER = false;
 
+    private static final int[] DEFAULT_APP_EXCLUSIVE_APPOPS = {
+            AppOpsManager.OP_READ_SMS,
+            AppOpsManager.OP_WRITE_SMS,
+            AppOpsManager.OP_RECEIVE_SMS,
+            AppOpsManager.OP_RECEIVE_WAP_PUSH,
+            AppOpsManager.OP_SEND_SMS,
+            AppOpsManager.OP_READ_CELL_BROADCASTS
+    };
+
     private static SmsPackageMonitor sSmsPackageMonitor = null;
 
     public static class SmsApplicationData {
@@ -396,6 +405,8 @@
             final SmsApplicationData smsApplicationData = receivers.get(packageName);
             if (smsApplicationData != null) {
                 if (!smsApplicationData.isComplete()) {
+                    Log.w(LOG_TAG, "Package " + packageName
+                            + " lacks required manifest declarations to be a default sms app");
                     receivers.remove(packageName);
                 }
             }
@@ -482,53 +493,27 @@
 
         // If we found a package, make sure AppOps permissions are set up correctly
         if (applicationData != null) {
-            AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
-
             // We can only call checkOp if we are privileged (updateIfNeeded) or if the app we
             // are checking is for our current uid. Doing this check from the unprivileged current
             // SMS app allows us to tell the current SMS app that it is not in a good state and
             // needs to ask to be the current SMS app again to work properly.
             if (updateIfNeeded || applicationData.mUid == android.os.Process.myUid()) {
                 // Verify that the SMS app has permissions
-                int mode = appOps.checkOp(AppOpsManager.OP_WRITE_SMS, applicationData.mUid,
-                        applicationData.mPackageName);
-                if (mode != AppOpsManager.MODE_ALLOWED) {
-                    Rlog.e(LOG_TAG, applicationData.mPackageName + " lost OP_WRITE_SMS: " +
-                            (updateIfNeeded ? " (fixing)" : " (no permission to fix)"));
-                    if (updateIfNeeded) {
-                        appOps.setMode(AppOpsManager.OP_WRITE_SMS, applicationData.mUid,
-                                applicationData.mPackageName, AppOpsManager.MODE_ALLOWED);
-                    } else {
-                        // We can not return a package if permissions are not set up correctly
-                        applicationData = null;
-                    }
+                boolean appOpsFixed =
+                        tryFixExclusiveSmsAppops(context, applicationData, updateIfNeeded);
+                if (!appOpsFixed) {
+                    // We can not return a package if permissions are not set up correctly
+                    applicationData = null;
                 }
             }
 
             // We can only verify the phone and BT app's permissions from a privileged caller
-            if (updateIfNeeded) {
+            if (applicationData != null && updateIfNeeded) {
                 // Ensure this component is still configured as the preferred activity. Usually the
                 // current SMS app will already be the preferred activity - but checking whether or
                 // not this is true is just as expensive as reconfiguring the preferred activity so
                 // we just reconfigure every time.
-                PackageManager packageManager = context.getPackageManager();
-                configurePreferredActivity(packageManager, new ComponentName(
-                        applicationData.mPackageName, applicationData.mSendToClass),
-                        userId);
-                // Assign permission to special system apps
-                assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
-                        PHONE_PACKAGE_NAME);
-                assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
-                        BLUETOOTH_PACKAGE_NAME);
-                assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
-                        MMS_SERVICE_PACKAGE_NAME);
-                assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
-                        TELEPHONY_PROVIDER_PACKAGE_NAME);
-                // Give WRITE_SMS AppOps permission to UID 1001 which contains multiple
-                // apps, all of them should be able to write to telephony provider.
-                // This is to allow the proxy package permission check in telephony provider
-                // to pass.
-                assignWriteSmsPermissionToSystemUid(appOps, Process.PHONE_UID);
+                updateDefaultSmsApp(context, userId, applicationData);
             }
         }
         if (DEBUG_MULTIUSER) {
@@ -537,6 +522,56 @@
         return applicationData;
     }
 
+    private static void updateDefaultSmsApp(Context context, int userId,
+            SmsApplicationData applicationData) {
+        PackageManager packageManager = context.getPackageManager();
+        AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+
+        // Configure this as the preferred activity for SENDTO sms/mms intents
+        configurePreferredActivity(packageManager, new ComponentName(
+                        applicationData.mPackageName, applicationData.mSendToClass),
+                userId);
+
+        // Assign permission to special system apps
+        assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps,
+                PHONE_PACKAGE_NAME);
+        assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps,
+                BLUETOOTH_PACKAGE_NAME);
+        assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps,
+                MMS_SERVICE_PACKAGE_NAME);
+        assignExclusiveSmsPermissionsToSystemApp(context, packageManager, appOps,
+                TELEPHONY_PROVIDER_PACKAGE_NAME);
+
+        // Give AppOps permission to UID 1001 which contains multiple
+        // apps, all of them should be able to write to telephony provider.
+        // This is to allow the proxy package permission check in telephony provider
+        // to pass.
+        for (int appop : DEFAULT_APP_EXCLUSIVE_APPOPS) {
+            appOps.setUidMode(appop, Process.PHONE_UID, AppOpsManager.MODE_ALLOWED);
+        }
+    }
+
+    private static boolean tryFixExclusiveSmsAppops(Context context,
+            SmsApplicationData applicationData, boolean updateIfNeeded) {
+        AppOpsManager appOps = context.getSystemService(AppOpsManager.class);
+        for (int appOp : DEFAULT_APP_EXCLUSIVE_APPOPS) {
+            int mode = appOps.checkOp(appOp, applicationData.mUid,
+                    applicationData.mPackageName);
+            if (mode != AppOpsManager.MODE_ALLOWED) {
+                Rlog.e(LOG_TAG, applicationData.mPackageName + " lost "
+                        + AppOpsManager.modeToName(appOp) + ": "
+                        + (updateIfNeeded ? " (fixing)" : " (no permission to fix)"));
+                if (updateIfNeeded) {
+                    setExclusiveAppop(applicationData.mPackageName, appOps, appOp,
+                            AppOpsManager.MODE_ALLOWED, applicationData.mUid);
+                } else {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
     /**
      * Sets the specified package as the default SMS/MMS application. The caller of this method
      * needs to have permission to set AppOps and write to secure settings.
@@ -584,19 +619,19 @@
 
         // We only make the change if the new package is valid
         PackageManager packageManager = context.getPackageManager();
-        Collection<SmsApplicationData> applications = getApplicationCollection(context);
+        Collection<SmsApplicationData> applications = getApplicationCollectionInternal(
+                context, userId);
         SmsApplicationData oldAppData = oldPackageName != null ?
                 getApplicationForPackage(applications, oldPackageName) : null;
         SmsApplicationData applicationData = getApplicationForPackage(applications, packageName);
         if (applicationData != null) {
-            // Ignore OP_WRITE_SMS for the previously configured default SMS app.
+            // Ignore relevant appops for the previously configured default SMS app.
             AppOpsManager appOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE);
             if (oldPackageName != null) {
                 try {
-                    PackageInfo info = packageManager.getPackageInfoAsUser(oldPackageName,
-                            0, userId);
-                    appOps.setMode(AppOpsManager.OP_WRITE_SMS, info.applicationInfo.uid,
-                            oldPackageName, AppOpsManager.MODE_IGNORED);
+                    int uid = packageManager.getPackageInfoAsUser(
+                            oldPackageName, 0, userId).applicationInfo.uid;
+                    setExclusiveAppops(oldPackageName, appOps, uid, AppOpsManager.MODE_DEFAULT);
                 } catch (NameNotFoundException e) {
                     Rlog.w(LOG_TAG, "Old SMS package not found: " + oldPackageName);
                 }
@@ -607,28 +642,11 @@
                     Settings.Secure.SMS_DEFAULT_APPLICATION, applicationData.mPackageName,
                     userId);
 
-            // Configure this as the preferred activity for SENDTO sms/mms intents
-            configurePreferredActivity(packageManager, new ComponentName(
-                    applicationData.mPackageName, applicationData.mSendToClass), userId);
+            // Allow relevant appops for the newly configured default SMS app.
+            setExclusiveAppops(applicationData.mPackageName, appOps, applicationData.mUid,
+                    AppOpsManager.MODE_ALLOWED);
 
-            // Allow OP_WRITE_SMS for the newly configured default SMS app.
-            appOps.setMode(AppOpsManager.OP_WRITE_SMS, applicationData.mUid,
-                    applicationData.mPackageName, AppOpsManager.MODE_ALLOWED);
-
-            // Assign permission to special system apps
-            assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
-                    PHONE_PACKAGE_NAME);
-            assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
-                    BLUETOOTH_PACKAGE_NAME);
-            assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
-                    MMS_SERVICE_PACKAGE_NAME);
-            assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
-                    TELEPHONY_PROVIDER_PACKAGE_NAME);
-            // Give WRITE_SMS AppOps permission to UID 1001 which contains multiple
-            // apps, all of them should be able to write to telephony provider.
-            // This is to allow the proxy package permission check in telephony provider
-            // to pass.
-            assignWriteSmsPermissionToSystemUid(appOps, Process.PHONE_UID);
+            updateDefaultSmsApp(context, userId, applicationData);
 
             if (DEBUG_MULTIUSER) {
                 Log.i(LOG_TAG, "setDefaultApplicationInternal oldAppData=" + oldAppData);
@@ -685,7 +703,7 @@
      * @param appOps The AppOps manager instance
      * @param packageName The package name of the system app
      */
-    private static void assignWriteSmsPermissionToSystemApp(Context context,
+    private static void assignExclusiveSmsPermissionsToSystemApp(Context context,
             PackageManager packageManager, AppOpsManager appOps, String packageName) {
         // First check package signature matches the caller's package signature.
         // Since this class is only used internally by the system, this check makes sure
@@ -701,8 +719,8 @@
                     packageName);
             if (mode != AppOpsManager.MODE_ALLOWED) {
                 Rlog.w(LOG_TAG, packageName + " does not have OP_WRITE_SMS:  (fixing)");
-                appOps.setMode(AppOpsManager.OP_WRITE_SMS, info.applicationInfo.uid,
-                        packageName, AppOpsManager.MODE_ALLOWED);
+                setExclusiveAppops(packageName, appOps, info.applicationInfo.uid,
+                        AppOpsManager.MODE_ALLOWED);
             }
         } catch (NameNotFoundException e) {
             // No whitelisted system app on this device
@@ -711,8 +729,19 @@
 
     }
 
-    private static void assignWriteSmsPermissionToSystemUid(AppOpsManager appOps, int uid) {
-        appOps.setUidMode(AppOpsManager.OP_WRITE_SMS, uid, AppOpsManager.MODE_ALLOWED);
+    private static void setExclusiveAppops(String pkg, AppOpsManager appOpsManager, int uid,
+            int mode) {
+        for (int appop : DEFAULT_APP_EXCLUSIVE_APPOPS) {
+            setExclusiveAppop(pkg, appOpsManager, appop, mode, uid);
+        }
+    }
+
+    private static void setExclusiveAppop(String pkg, AppOpsManager appOpsManager, int appop,
+            int mode, int uid) {
+        // IGNORED means user explicitly revoked permission in settings, so avoid overriding it.
+        if (appOpsManager.checkOpNoThrow(appop, uid, pkg) != AppOpsManager.MODE_IGNORED) {
+            appOpsManager.setUidMode(appop, uid, mode);
+        }
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 23ea237..eda8e77 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -19,14 +19,21 @@
 
 import android.Manifest;
 import android.app.AppOpsManager;
+import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.telephony.Rlog;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 
@@ -135,6 +142,185 @@
     }
 
     /**
+     * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
+     *
+     * <p>This method behaves in one of the following ways:
+     * <ul>
+     *   <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the
+     *       calling package passes a DevicePolicyManager Device Owner / Profile Owner device
+     *       identifier access check,
+     *   <li>throw SecurityException: if the caller does not meet any of the requirements and is
+     *       targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
+     *   <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
+     *       permission. In this case the caller would expect to have access to the device
+     *       identifiers so false is returned instead of throwing a SecurityException to indicate
+     *       the calling function should return dummy data.
+     * </ul>
+     */
+    public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context,
+            String callingPackage, String message) {
+        return checkCallingOrSelfReadDeviceIdentifiers(context,
+                SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage, message);
+    }
+
+    /**
+     * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
+     *
+     * <p>This method behaves in one of the following ways:
+     * <ul>
+     *   <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the
+     *       calling package passes a DevicePolicyManager Device Owner / Profile Owner device
+     *       identifier access check,
+     *   <li>throw SecurityException: if the caller does not meet any of the requirements and is
+     *       targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission
+     *       or carrier privileges.
+     *   <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
+     *       permission or carrier privileges. In this case the caller would expect to have access
+     *       to the device identifiers so false is returned instead of throwing a SecurityException
+     *       to indicate the calling function should return dummy data.
+     * </ul>
+     */
+    public static boolean checkCallingOrSelfReadDeviceIdentifiers(Context context, int subId,
+            String callingPackage, String message) {
+        int pid = Binder.getCallingPid();
+        int uid = Binder.getCallingUid();
+        // if the device identifier check completes successfully then grant access.
+        if (checkReadDeviceIdentifiers(context, pid, uid, callingPackage)) {
+            return true;
+        }
+        // else the calling package is not authorized to access the device identifiers; call
+        // a central method to report the failure based on the target SDK and if the calling package
+        // has the READ_PHONE_STATE permission or carrier privileges that were previously required
+        // to access the identifiers.
+        return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
+                message);
+    }
+
+    /**
+     * Check whether the caller (or self, if not processing an IPC) can read subscriber identifiers.
+     *
+     * <p>This method behaves in one of the following ways:
+     * <ul>
+     *   <li>return true: if the caller has the READ_PRIVILEGED_PHONE_STATE permission, the calling
+     *       package passes a DevicePolicyManager Device Owner / Profile Owner device identifier
+     *       access check, or the calling package has carrier privleges.
+     *   <li>throw SecurityException: if the caller does not meet any of the requirements and is
+     *       targeting Q or is targeting pre-Q and does not have the READ_PHONE_STATE permission.
+     *   <li>return false: if the caller is targeting pre-Q and does have the READ_PHONE_STATE
+     *       permission. In this case the caller would expect to have access to the device
+     *       identifiers so false is returned instead of throwing a SecurityException to indicate
+     *       the calling function should return dummy data.
+     * </ul>
+     */
+    public static boolean checkCallingOrSelfReadSubscriberIdentifiers(Context context, int subId,
+            String callingPackage, String message) {
+        int pid = Binder.getCallingPid();
+        int uid = Binder.getCallingUid();
+        // if the device identifiers can be read then grant access to the subscriber identifiers
+        if (checkReadDeviceIdentifiers(context, pid, uid, callingPackage)) {
+            return true;
+        }
+        // If the calling package has carrier privileges then allow access to the subscriber
+        // identifiers.
+        if (SubscriptionManager.isValidSubscriptionId(subId) && getCarrierPrivilegeStatus(
+                TELEPHONY_SUPPLIER, subId, uid)
+                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+            return true;
+        }
+        return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
+                message);
+    }
+
+    /**
+     * Checks whether the app with the given pid/uid can read device identifiers.
+     *
+     * @returns true if the caller has the READ_PRIVILEGED_PHONE_STATE permission or the calling
+     * package passes a DevicePolicyManager Device Owner / Profile Owner device identifier access
+     * check.
+     */
+    private static boolean checkReadDeviceIdentifiers(Context context, int pid, int uid,
+            String callingPackage) {
+        // Allow system and root access to the device identifiers.
+        final int appId = UserHandle.getAppId(uid);
+        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
+            return true;
+        }
+        // Allow access to packages that have the READ_PRIVILEGED_PHONE_STATE permission.
+        if (context.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid,
+                uid) == PackageManager.PERMISSION_GRANTED) {
+            return true;
+        }
+        // if the calling package is null then return now as there's no way to perform the
+        // DevicePolicyManager device / profile owner checks.
+        if (callingPackage == null) {
+            return false;
+        }
+        // Allow access to a device / profile owner app.
+        DevicePolicyManager devicePolicyManager = (DevicePolicyManager) context.getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        if (devicePolicyManager != null && devicePolicyManager.checkDeviceIdentifierAccessAsUser(
+                callingPackage, Binder.getCallingUserHandle().getIdentifier())) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Reports a failure when the app with the given pid/uid cannot access the requested identifier.
+     *
+     * @returns false if the caller is targeting pre-Q and does have the READ_PHONE_STATE
+     * permission or carrier privileges.
+     * @throws SecurityException if the caller does not meet any of the requirements for the
+     *                           requested identifier and is targeting Q or is targeting pre-Q
+     *                           and does not have the READ_PHONE_STATE permission or carrier
+     *                           privileges.
+     */
+    private static boolean reportAccessDeniedToReadIdentifiers(Context context, int subId, int pid,
+            int uid, String callingPackage, String message) {
+        Log.wtf(LOG_TAG,
+                "reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message);
+        // if the device identifier check is relaxed then revert to the READ_PHONE_STATE permission
+        // check that was previously required to access device identifiers.
+        boolean relaxDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(),
+                Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED, 0) == 0;
+        if (relaxDeviceIdentifierCheck) {
+            return checkReadPhoneState(context, subId, pid, uid, callingPackage, message);
+        } else {
+            boolean targetQBehaviorDisabled = Settings.Global.getInt(context.getContentResolver(),
+                    Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED, 0) == 0;
+            if (callingPackage != null) {
+                try {
+                    // if the target SDK is pre-Q or the target Q behavior is disabled then check if
+                    // the calling package would have previously had access to device identifiers.
+                    ApplicationInfo callingPackageInfo =
+                            context.getPackageManager().getApplicationInfo(
+                                    callingPackage, 0);
+                    if (callingPackageInfo != null && (
+                            callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q
+                                    || targetQBehaviorDisabled)) {
+                        if (context.checkPermission(
+                                android.Manifest.permission.READ_PHONE_STATE,
+                                pid,
+                                uid) == PackageManager.PERMISSION_GRANTED) {
+                            return false;
+                        }
+                        if (SubscriptionManager.isValidSubscriptionId(subId)
+                                && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, uid)
+                                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                            return false;
+                        }
+                    }
+                } catch (PackageManager.NameNotFoundException e) {
+                    // If the application info for the calling package could not be found then
+                    // default to throwing the SecurityException.
+                }
+            }
+            throw new SecurityException(message + ": The user " + uid
+                    + " does not meet the requirements to access device identifiers.");
+        }
+    }
+
+    /**
      * Check whether the app with the given pid/uid can read the call log.
      * @return {@code true} if the specified app has the read call log permission and AppOpp granted
      *      to it, {@code false} otherwise.
diff --git a/test-mock/api/system-current.txt b/test-mock/api/system-current.txt
index 3bd3d68..2b968ae 100644
--- a/test-mock/api/system-current.txt
+++ b/test-mock/api/system-current.txt
@@ -29,6 +29,7 @@
     method public void removeOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener);
     method public void revokeRuntimePermission(java.lang.String, java.lang.String, android.os.UserHandle);
     method public boolean setDefaultBrowserPackageNameAsUser(java.lang.String, int);
+    method public java.lang.String[] setPackagesSuspended(java.lang.String[], boolean, android.os.PersistableBundle, android.os.PersistableBundle, java.lang.String);
     method public void setUpdateAvailable(java.lang.String, boolean);
     method public boolean updateIntentVerificationStatusAsUser(java.lang.String, int, int);
     method public void updatePermissionFlags(java.lang.String, java.lang.String, int, int, android.os.UserHandle);
diff --git a/test-mock/src/android/test/mock/MockContext.java b/test-mock/src/android/test/mock/MockContext.java
index 9d260eb..fa5b896 100644
--- a/test-mock/src/android/test/mock/MockContext.java
+++ b/test-mock/src/android/test/mock/MockContext.java
@@ -774,6 +774,12 @@
 
     /** @hide */
     @Override
+    public int getDisplayId() {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
     public void updateDisplay(int displayId) {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/ActivityTests/Android.mk b/tests/ActivityTests/Android.mk
index 4c68c8b..94294f6 100644
--- a/tests/ActivityTests/Android.mk
+++ b/tests/ActivityTests/Android.mk
@@ -10,9 +10,5 @@
 LOCAL_CERTIFICATE := platform
 
 LOCAL_USE_AAPT2 := true
-# Disable AAPT2 manifest checks to fix:
-# frameworks/base/tests/ActivityTests/AndroidManifest.xml:42: error: unexpected element <preferred> found in <manifest><application><activity>.
-# TODO(b/79755007): Remove when AAPT2 recognizes the manifest elements.
-LOCAL_AAPT_FLAGS += --warn-manifest-validation
 
 include $(BUILD_PACKAGE)
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 976848c..eed8ae7 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -92,7 +92,9 @@
             "com.google.android.wearable.action.GOOGLE";
     private static final int INITIAL_LAUNCH_IDLE_TIMEOUT = 5000; // 5s to allow app to idle
     private static final int POST_LAUNCH_IDLE_TIMEOUT = 750; // 750ms idle for non initial launches
-    private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 5000; // 5s between launching apps
+    private static final int BEFORE_FORCE_STOP_SLEEP_TIMEOUT = 1000; // 1s before force stopping
+    private static final int BEFORE_KILL_APP_SLEEP_TIMEOUT = 1000; // 1s before killing
+    private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 3000; // 3s between launching apps
     private static final int PROFILE_SAVE_SLEEP_TIMEOUT = 1000; // Allow 1s for the profile to save
     private static final String LAUNCH_SUB_DIRECTORY = "launch_logs";
     private static final String LAUNCH_FILE = "applaunch.txt";
@@ -327,7 +329,14 @@
                     }
                 }
                 if(mForceStopApp) {
-                    closeApp(launch.getApp());
+                    sleep(BEFORE_FORCE_STOP_SLEEP_TIMEOUT);
+                    forceStopApp(launch.getApp());
+                    sleep(BEFORE_KILL_APP_SLEEP_TIMEOUT);
+                    // Close again for good measure (just in case).
+                    forceStopApp(launch.getApp());
+                    // Kill the backgrounded process in the case forceStopApp only sent it to
+                    // background.
+                    killBackgroundApp(launch.getApp());
                 } else {
                     startHomeIntent();
                 }
@@ -638,7 +647,7 @@
         // Kill all the apps
         for (String appName : mNameToIntent.keySet()) {
             Log.w(TAG, String.format("killing %s", appName));
-            closeApp(appName);
+            forceStopApp(appName);
         }
         // Drop all the cache.
         assertNotNull("Issue in dropping the cache",
@@ -646,7 +655,7 @@
                         .executeShellCommand(DROP_CACHE_SCRIPT));
     }
 
-    private void closeApp(String appName) {
+    private void forceStopApp(String appName) {
         Intent startIntent = mNameToIntent.get(appName);
         if (startIntent != null) {
             String packageName = startIntent.getComponent().getPackageName();
@@ -658,6 +667,18 @@
         }
     }
 
+    private void killBackgroundApp(String appName) {
+        Intent startIntent = mNameToIntent.get(appName);
+        if (startIntent != null) {
+            String packageName = startIntent.getComponent().getPackageName();
+            try {
+                mAm.killBackgroundProcesses(packageName, UserHandle.USER_CURRENT);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Error closing app", e);
+            }
+        }
+    }
+
     private void sleep(int time) {
         try {
             Thread.sleep(time);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java
index 5bc8934..571f623 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/CirclePropActivity.java
@@ -22,9 +22,9 @@
 import android.graphics.CanvasProperty;
 import android.graphics.Paint;
 import android.graphics.Paint.Style;
+import android.graphics.RecordingCanvas;
 import android.os.Bundle;
 import android.os.Trace;
-import android.view.DisplayListCanvas;
 import android.view.RenderNodeAnimator;
 import android.view.View;
 import android.widget.LinearLayout;
@@ -88,8 +88,8 @@
             super.onDraw(canvas);
 
             if (canvas.isHardwareAccelerated()) {
-                DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas;
-                displayListCanvas.drawCircle(mX, mY, mRadius, mPaint);
+                RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
+                recordingCanvas.drawCircle(mX, mY, mRadius, mPaint);
             }
         }
 
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
index af8e10b..220016a 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/DrawIntoHwBitmapActivity.java
@@ -16,25 +16,13 @@
 
 package com.android.test.hwui;
 
-import static android.graphics.GraphicBuffer.USAGE_HW_TEXTURE;
-import static android.graphics.GraphicBuffer.USAGE_SW_READ_NEVER;
-import static android.graphics.GraphicBuffer.USAGE_SW_WRITE_NEVER;
-import static android.graphics.GraphicBuffer.USAGE_SW_WRITE_RARELY;
-
 import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.GraphicBuffer;
 import android.graphics.Paint;
 import android.graphics.Picture;
-import android.graphics.PixelFormat;
-import android.graphics.SurfaceTexture;
 import android.os.Bundle;
-import android.view.DisplayListCanvas;
-import android.view.RenderNode;
-import android.view.Surface;
-import android.view.ThreadedRenderer;
 import android.widget.ImageView;
 
 public class DrawIntoHwBitmapActivity extends Activity {
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java
index 7713f5d..e7d7f2b 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/MultiProducerActivity.java
@@ -21,12 +21,12 @@
 import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.PixelFormat;
+import android.graphics.RecordingCanvas;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
-import android.view.DisplayListCanvas;
 import android.view.ThreadedRenderer;
-import android.view.RenderNode;
+import android.graphics.RenderNode;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.AbsoluteLayout;
@@ -206,7 +206,7 @@
                     }
 
                     // Draw frame
-                    DisplayListCanvas canvas = nodeFrame.start(currentFrameBounds.width(),
+                    RecordingCanvas canvas = nodeFrame.start(currentFrameBounds.width(),
                             currentFrameBounds.height());
                     mFrameContent.draw(canvas);
                     nodeFrame.end(canvas);
@@ -228,7 +228,7 @@
                     }
 
                     // Draw Backdrop
-                    DisplayListCanvas canvas = nodeBack.start(currentBackBounds.width(),
+                    RecordingCanvas canvas = nodeBack.start(currentBackBounds.width(),
                             currentBackBounds.height());
                     mBackContent.draw(canvas);
                     nodeBack.end(canvas);
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
index be5d7f9..4eb4072 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionActivity.java
@@ -8,9 +8,8 @@
 
 import android.app.Activity;
 import android.util.AttributeSet;
-import android.view.RenderNode;
+import android.graphics.RenderNode;
 import android.view.View;
-import android.widget.LinearLayout;
 
 public class ProjectionActivity extends Activity {
     /**
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java
index 2ae960b..9abd7ea 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ProjectionClippingActivity.java
@@ -1,13 +1,7 @@
 package com.android.test.hwui;
 
 import android.app.Activity;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.RectF;
 import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.RenderNode;
 import android.view.View;
 
 public class ProjectionClippingActivity extends Activity {
diff --git a/tests/Internal/res/xml/livewallpaper.xml b/tests/Internal/res/xml/livewallpaper.xml
index 6b5e84e..36e7e41 100644
--- a/tests/Internal/res/xml/livewallpaper.xml
+++ b/tests/Internal/res/xml/livewallpaper.xml
@@ -16,4 +16,5 @@
   -->
 <wallpaper
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:supportsAmbientMode="true"/>
\ No newline at end of file
+    android:settingsSliceUri="content://com.android.internal.tests/slice"
+    android:supportsAmbientMode="true"/>
diff --git a/tests/Internal/src/android/app/WallpaperInfoTest.java b/tests/Internal/src/android/app/WallpaperInfoTest.java
index 98045ae..7f06f2c 100644
--- a/tests/Internal/src/android/app/WallpaperInfoTest.java
+++ b/tests/Internal/src/android/app/WallpaperInfoTest.java
@@ -23,6 +23,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.net.Uri;
 import android.os.Parcel;
 import android.service.wallpaper.WallpaperService;
 import android.support.test.InstrumentationRegistry;
@@ -64,5 +65,31 @@
                 fromParcel.supportsAmbientMode());
         parcel.recycle();
     }
+
+    @Test
+    public void testGetSettingsSliceUri() throws Exception {
+        Context context = InstrumentationRegistry.getTargetContext();
+
+        Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
+        intent.setPackage("com.android.internal.tests");
+        PackageManager pm = context.getPackageManager();
+        List<ResolveInfo> result = pm.queryIntentServices(intent, PackageManager.GET_META_DATA);
+        assertEquals(1, result.size());
+        ResolveInfo info = result.get(0);
+        WallpaperInfo wallpaperInfo = new WallpaperInfo(context, info);
+
+        // This expected Uri must be the same as that in livewallpaper.xml
+        Uri expectedUri = Uri.parse("content://com.android.internal.tests/slice");
+        Uri settingsUri = wallpaperInfo.getSettingsSliceUri();
+        assertEquals("The loaded URI should equal to the string in livewallpaper.xml",
+                0, expectedUri.compareTo(settingsUri));
+        Parcel parcel = Parcel.obtain();
+        wallpaperInfo.writeToParcel(parcel, 0 /* flags */);
+        parcel.setDataPosition(0);
+        WallpaperInfo fromParcel = WallpaperInfo.CREATOR.createFromParcel(parcel);
+        assertEquals("settingsSliceUri should be restorable from parcelable",
+                0, expectedUri.compareTo(fromParcel.getSettingsSliceUri()));
+        parcel.recycle();
+    }
 }
 
diff --git a/tests/NativeProcessesMemoryTest/src/com/android/tests/nativeprocesses/NativeProcessesMemoryTest.java b/tests/NativeProcessesMemoryTest/src/com/android/tests/nativeprocesses/NativeProcessesMemoryTest.java
index c86f06e..51302ce 100644
--- a/tests/NativeProcessesMemoryTest/src/com/android/tests/nativeprocesses/NativeProcessesMemoryTest.java
+++ b/tests/NativeProcessesMemoryTest/src/com/android/tests/nativeprocesses/NativeProcessesMemoryTest.java
@@ -19,11 +19,15 @@
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.result.ByteArrayInputStreamSource;
-import com.android.tradefed.result.ITestInvocationListener;
 import com.android.tradefed.result.LogDataType;
-import com.android.tradefed.result.TestDescription;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestLogData;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestMetrics;
 import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -58,7 +62,12 @@
  *   - memory usage of each native process (one measurement for each process)
  * </pre>
  */
-public class NativeProcessesMemoryTest implements IDeviceTest, IRemoteTest {
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class NativeProcessesMemoryTest implements IDeviceTest {
+
+    @Rule public TestMetrics metrics = new TestMetrics();
+    @Rule public TestLogData logs = new TestLogData();
+
     // the dumpsys process comes and go as we run this test, changing pids, so ignore it
     private static final List<String> PROCESSES_TO_IGNORE = Arrays.asList("dumpsys");
 
@@ -68,38 +77,25 @@
     private static final String SEPARATOR = ",";
     private static final String LINE_SEPARATOR = "\\n";
 
-    // name of this test run, used for reporting
-    private static final String RUN_NAME = "NativeProcessesTest";
     // key used to report the number of native processes
     private static final String NUM_NATIVE_PROCESSES_KEY = "Num_native_processes";
 
-    private final Map<String, String> mNativeProcessToMemory = new HashMap<String, String>();
     // identity for summing over MemoryMetric
     private final MemoryMetric mZero = new MemoryMetric(0, 0, 0);
 
     private ITestDevice mTestDevice;
-    private ITestInvocationListener mListener;
 
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        mListener = listener;
+    @Test
+    public void run() throws DeviceNotAvailableException {
         // showmap requires root, we enable it here for the rest of the test
-        mTestDevice.enableAdbRoot();
-
-        listener.testRunStarted(RUN_NAME, 1 /* testCount */);
-
-        TestDescription testDescription = new TestDescription(getClass().getName(), "run");
-        listener.testStarted(testDescription);
-
+        getDevice().enableAdbRoot();
         // process name -> list of pids with that name
         Map<String, List<String>> nativeProcesses = collectNativeProcesses();
         sampleAndLogAllProcesses(nativeProcesses);
 
         // want to also record the number of native processes
-        mNativeProcessToMemory.put(
+        metrics.addTestMetric(
                 NUM_NATIVE_PROCESSES_KEY, Integer.toString(nativeProcesses.size()));
-
-        listener.testEnded(testDescription, mNativeProcessToMemory);
-        listener.testRunEnded(0, new HashMap<String, String>());
     }
 
     /** Samples memory of all processes and logs the memory use. */
@@ -148,7 +144,7 @@
      */
     private Map<String, List<String>> collectNativeProcesses() throws DeviceNotAvailableException {
         HashMap<String, List<String>> nativeProcesses = new HashMap<>();
-        String memInfo = mTestDevice.executeShellCommand(DUMPSYS_MEMINFO_OOM_CMD);
+        String memInfo = getDevice().executeShellCommand(DUMPSYS_MEMINFO_OOM_CMD);
 
         for (String line : memInfo.split(LINE_SEPARATOR)) {
             String[] splits = line.split(SEPARATOR);
@@ -172,7 +168,7 @@
     private void logShowmap(String label, String showmap) {
         try (ByteArrayInputStreamSource source =
                 new ByteArrayInputStreamSource(showmap.getBytes())) {
-            mListener.testLog(label + "_showmap", LogDataType.TEXT, source);
+            logs.addTestLog(label + "_showmap", LogDataType.TEXT, source);
         }
     }
 
@@ -183,7 +179,7 @@
     private Optional<MemoryMetric> snapMemoryUsage(String processName, String pid)
             throws DeviceNotAvailableException {
         // TODO(zhin): copied from com.android.tests.sysmem.host.Metrics#sample(), extract?
-        String showmap = mTestDevice.executeShellCommand("showmap " + pid);
+        String showmap = getDevice().executeShellCommand("showmap " + pid);
         logShowmap(processName + "_" + pid, showmap);
 
         // CHECKSTYLE:OFF Generated code
@@ -214,9 +210,9 @@
 
     /** Logs a MemoryMetric of a process. */
     private void logMemoryMetric(String processName, MemoryMetric memoryMetric) {
-        mNativeProcessToMemory.put(processName + "_pss", Long.toString(memoryMetric.pss));
-        mNativeProcessToMemory.put(processName + "_rss", Long.toString(memoryMetric.rss));
-        mNativeProcessToMemory.put(processName + "_vss", Long.toString(memoryMetric.vss));
+        metrics.addTestMetric(processName + "_pss", Long.toString(memoryMetric.pss));
+        metrics.addTestMetric(processName + "_rss", Long.toString(memoryMetric.rss));
+        metrics.addTestMetric(processName + "_vss", Long.toString(memoryMetric.vss));
     }
 
     /** Container of memory numbers we want to log. */
diff --git a/tests/NetworkSecurityConfigTest/Android.mk b/tests/NetworkSecurityConfigTest/Android.mk
index fe65ecc..a6c21db 100644
--- a/tests/NetworkSecurityConfigTest/Android.mk
+++ b/tests/NetworkSecurityConfigTest/Android.mk
@@ -7,8 +7,6 @@
 
 LOCAL_JAVA_LIBRARIES := \
     android.test.runner \
-    bouncycastle \
-    conscrypt \
     android.test.base \
 
 LOCAL_STATIC_JAVA_LIBRARIES := junit
diff --git a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java
index 6500428..18cdf96 100644
--- a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java
+++ b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Cujs.java
@@ -34,7 +34,7 @@
         // Do an explicit GC in the system server process as part of the test
         // case to reduce GC-related sources of noise.
         // SIGUSR1 = 10 is the magic signal to trigger the GC.
-        int pid = mDevice.getPidForProcess("system_server");
+        int pid = mDevice.getProcessPid("system_server");
         mDevice.executeShellCommand("kill -10 " + pid);
 
         // Invoke the Device Cujs instrumentation to run the cujs.
diff --git a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java
index 03503ce..26146ca 100644
--- a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java
+++ b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Device.java
@@ -19,9 +19,6 @@
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 
-import java.util.InputMismatchException;
-import java.util.Scanner;
-
 /**
  * Wrapper around ITestDevice exposing useful device functions.
  */
@@ -58,29 +55,15 @@
     /**
      * Returns the pid for the process with the given name.
      */
-    public int getPidForProcess(String name) throws TestException {
-        String psout = executeShellCommand("ps -A -o PID,CMD");
-        Scanner sc = new Scanner(psout);
+    public int getProcessPid(String name) throws TestException {
         try {
-            // ps output is of the form:
-            //  PID CMD
-            //    1 init
-            //    2 kthreadd
-            //    ...
-            // 9693 ps
-            sc.nextLine();
-            while (sc.hasNextLine()) {
-                int pid = sc.nextInt();
-                String cmd = sc.next();
-
-                if (name.equals(cmd)) {
-                    return pid;
-                }
+            String pid = mDevice.getProcessPid(name);
+            if (pid == null) {
+                throw new TestException("failed to get pid for " + name);
             }
-        } catch (InputMismatchException e) {
-            throw new TestException("unexpected ps output format: " + psout, e);
+            return Integer.parseInt(pid);
+        } catch (DeviceNotAvailableException e) {
+            throw new TestException(e);
         }
-
-        throw new TestException("failed to get pid for process " + name);
     }
 }
diff --git a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java
index b408a81..b46e642 100644
--- a/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java
+++ b/tests/SystemMemoryTest/host/src/com/android/tests/sysmem/host/Metrics.java
@@ -79,7 +79,7 @@
         // adb root access is required to get showmap
         mDevice.enableAdbRoot();
 
-        int pid = mDevice.getPidForProcess("system_server");
+        int pid = mDevice.getProcessPid("system_server");
 
         // Read showmap for system server and add it as a test log
         String showmap = mDevice.executeShellCommand("showmap " + pid);
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
index e529b93..132135d 100644
--- a/tests/net/Android.mk
+++ b/tests/net/Android.mk
@@ -38,6 +38,7 @@
     libbacktrace \
     libbase \
     libbinder \
+    libbinderthreadstate \
     libc++ \
     libcrypto \
     libcutils \
@@ -62,7 +63,8 @@
     libunwindstack \
     libutilscallstack \
     libziparchive \
-    libz
+    libz \
+    netd_aidl_interface-cpp
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
@@ -91,7 +93,8 @@
   liblog \
   libcutils \
   libnativehelper \
-  libnetdaidl
+  libnetdaidl \
+  netd_aidl_interface-cpp
 
 LOCAL_STATIC_LIBRARIES := \
   libpcap \
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index 03a617c..6174c6c 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -219,7 +219,7 @@
         // callback triggers
         captor.getValue().send(makeMessage(request, ConnectivityManager.CALLBACK_AVAILABLE));
         verify(callback, timeout(500).times(1)).onAvailable(any(Network.class),
-                any(NetworkCapabilities.class), any(LinkProperties.class));
+                any(NetworkCapabilities.class), any(LinkProperties.class), anyBoolean());
 
         // unregister callback
         manager.unregisterNetworkCallback(callback);
@@ -247,7 +247,7 @@
         // callback triggers
         captor.getValue().send(makeMessage(req1, ConnectivityManager.CALLBACK_AVAILABLE));
         verify(callback, timeout(100).times(1)).onAvailable(any(Network.class),
-                any(NetworkCapabilities.class), any(LinkProperties.class));
+                any(NetworkCapabilities.class), any(LinkProperties.class), anyBoolean());
 
         // unregister callback
         manager.unregisterNetworkCallback(callback);
diff --git a/tests/net/java/android/net/dhcp/DhcpPacketTest.java b/tests/net/java/android/net/dhcp/DhcpPacketTest.java
index 312b3d1..a592809 100644
--- a/tests/net/java/android/net/dhcp/DhcpPacketTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpPacketTest.java
@@ -25,6 +25,7 @@
 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;
@@ -37,6 +38,7 @@
 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;
@@ -56,6 +58,8 @@
     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 Inet4Address.ANY or INADDR_ANY to ensure that the code
     // doesn't use == instead of equals when comparing addresses.
     private static final Inet4Address ANY = (Inet4Address) v4Address("0.0.0.0");
@@ -960,7 +964,8 @@
         assertTrue(msg, Arrays.equals(expected, actual));
     }
 
-    public void checkBuildOfferPacket(int leaseTimeSecs) throws Exception {
+    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;
@@ -971,7 +976,8 @@
                 CLIENT_MAC, leaseTimeSecs, NETMASK /* netMask */,
                 BROADCAST_ADDR /* bcAddr */, Collections.singletonList(SERVER_ADDR) /* gateways */,
                 Collections.singletonList(SERVER_ADDR) /* dnsServers */,
-                SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, false /* metered */);
+                SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, hostname,
+                false /* metered */, MTU);
 
         ByteArrayOutputStream bos = new ByteArrayOutputStream();
         // BOOTP headers
@@ -1027,12 +1033,22 @@
         // 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);
 
-        final byte[] expected = bos.toByteArray();
-        assertTrue((expected.length & 1) == 0);
+        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) +
@@ -1042,13 +1058,18 @@
 
     @Test
     public void testOfferPacket() throws Exception {
-        checkBuildOfferPacket(3600);
-        checkBuildOfferPacket(Integer.MAX_VALUE);
-        checkBuildOfferPacket(0x80000000);
-        checkBuildOfferPacket(INFINITE_LEASE);
+        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/tests/net/java/android/net/dhcp/DhcpServerTest.java b/tests/net/java/android/net/dhcp/DhcpServerTest.java
index 45a50d9..df34c73 100644
--- a/tests/net/java/android/net/dhcp/DhcpServerTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpServerTest.java
@@ -17,6 +17,7 @@
 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.ENCAP_BOOTP;
 import static android.net.dhcp.DhcpPacket.INADDR_ANY;
 import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST;
@@ -87,6 +88,7 @@
             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 };
@@ -96,7 +98,10 @@
     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 */);
+            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;
@@ -217,15 +222,17 @@
     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 */, isNull() /* hostname */))
-                .thenReturn(TEST_LEASE);
+                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);
+        assertMatchesTestLease(packet, TEST_HOSTNAME);
     }
 
     @Test
@@ -270,14 +277,18 @@
      *  - other request states (init-reboot/renewing/rebinding)
      */
 
-    private void assertMatchesTestLease(@NonNull DhcpPacket packet) {
+    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);
-        assertNull(packet.mHostName);
+        assertEquals(hostname, packet.mHostName);
+    }
+
+    private void assertMatchesTestLease(@NonNull DhcpPacket packet) {
+        assertMatchesTestLease(packet, null);
     }
 
     private void assertMatchesClient(@NonNull DhcpPacket packet) {
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1c77fcc..17bcea0 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -51,6 +51,10 @@
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
 import static android.net.NetworkCapabilities.TRANSPORT_WIFI_AWARE;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
+import static android.net.NetworkPolicyManager.RULE_NONE;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 
 import static com.android.internal.util.TestUtils.waitForIdleHandler;
 import static com.android.internal.util.TestUtils.waitForIdleLooper;
@@ -92,6 +96,7 @@
 import android.net.ConnectivityManager.PacketKeepaliveCallback;
 import android.net.ConnectivityManager.TooManyRequestsException;
 import android.net.ConnectivityThread;
+import android.net.INetworkPolicyListener;
 import android.net.INetworkPolicyManager;
 import android.net.INetworkStatsService;
 import android.net.InterfaceConfiguration;
@@ -148,6 +153,7 @@
 import com.android.server.connectivity.Nat464Xlat;
 import com.android.server.connectivity.NetworkAgentInfo;
 import com.android.server.connectivity.NetworkMonitor;
+import com.android.server.connectivity.Tethering;
 import com.android.server.connectivity.Vpn;
 import com.android.server.net.NetworkPinner;
 import com.android.server.net.NetworkPolicyManagerInternal;
@@ -215,11 +221,13 @@
     private MockNetworkAgent mEthernetNetworkAgent;
     private MockVpn mMockVpn;
     private Context mContext;
+    private INetworkPolicyListener mPolicyListener;
 
     @Mock IpConnectivityMetrics.Logger mMetricsService;
     @Mock DefaultNetworkMetrics mDefaultNetworkMetrics;
     @Mock INetworkManagementService mNetworkManagementService;
     @Mock INetworkStatsService mStatsService;
+    @Mock INetworkPolicyManager mNpm;
 
     private ArgumentCaptor<String[]> mStringArrayCaptor = ArgumentCaptor.forClass(String[].class);
 
@@ -934,6 +942,11 @@
         }
 
         @Override
+        protected Tethering makeTethering() {
+            return mock(Tethering.class);
+        }
+
+        @Override
         protected int reserveNetId() {
             while (true) {
                 final int netId = super.reserveNetId();
@@ -1023,6 +1036,20 @@
         public void waitForIdle() {
             waitForIdle(TIMEOUT_MS);
         }
+
+        public void setUidRulesChanged(int uidRules) {
+            try {
+                mPolicyListener.onUidRulesChanged(Process.myUid(), uidRules);
+            } catch (RemoteException ignored) {
+            }
+        }
+
+        public void setRestrictBackgroundChanged(boolean restrictBackground) {
+            try {
+                mPolicyListener.onRestrictBackgroundChanged(restrictBackground);
+            } catch (RemoteException ignored) {
+            }
+        }
     }
 
     /**
@@ -1055,12 +1082,18 @@
         LocalServices.removeServiceForTest(NetworkPolicyManagerInternal.class);
         LocalServices.addService(
                 NetworkPolicyManagerInternal.class, mock(NetworkPolicyManagerInternal.class));
+
         mService = new WrappedConnectivityService(mServiceContext,
                 mNetworkManagementService,
                 mStatsService,
-                mock(INetworkPolicyManager.class),
+                mNpm,
                 mock(IpConnectivityLog.class));
 
+        final ArgumentCaptor<INetworkPolicyListener> policyListenerCaptor =
+                ArgumentCaptor.forClass(INetworkPolicyListener.class);
+        verify(mNpm).registerListener(policyListenerCaptor.capture());
+        mPolicyListener = policyListenerCaptor.getValue();
+
         // Create local CM before sending system ready so that we can answer
         // getSystemService() correctly.
         mCm = new WrappedConnectivityManager(InstrumentationRegistry.getContext(), mService);
@@ -1441,7 +1474,8 @@
         RESUMED,
         LOSING,
         LOST,
-        UNAVAILABLE
+        UNAVAILABLE,
+        BLOCKED_STATUS
     }
 
     private static class CallbackInfo {
@@ -1522,6 +1556,11 @@
             setLastCallback(CallbackState.LOST, network, null);
         }
 
+        @Override
+        public void onBlockedStatusChanged(Network network, boolean blocked) {
+            setLastCallback(CallbackState.BLOCKED_STATUS, network, blocked);
+        }
+
         public Network getLastAvailableNetwork() {
             return mLastAvailableNetwork;
         }
@@ -1582,6 +1621,7 @@
         // - 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.
@@ -1589,7 +1629,7 @@
         //        onCapabilitiesChanged callback.
         // @param timeoutMs how long to wait for the callbacks.
         void expectAvailableCallbacks(MockNetworkAgent agent, boolean expectSuspended,
-                boolean expectValidated, int timeoutMs) {
+                boolean expectValidated, boolean expectBlocked, int timeoutMs) {
             expectCallback(CallbackState.AVAILABLE, agent, timeoutMs);
             if (expectSuspended) {
                 expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
@@ -1600,19 +1640,28 @@
                 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, TEST_CALLBACK_TIMEOUT_MS);
+            expectAvailableCallbacks(agent, true, expectValidated, false, TEST_CALLBACK_TIMEOUT_MS);
         }
 
         void expectAvailableCallbacksValidated(MockNetworkAgent agent) {
-            expectAvailableCallbacks(agent, false, true, TEST_CALLBACK_TIMEOUT_MS);
+            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, TEST_CALLBACK_TIMEOUT_MS);
+            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
@@ -1623,6 +1672,9 @@
             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);
         }
@@ -1665,6 +1717,12 @@
                     fn.test((NetworkCapabilities) 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();
@@ -3223,7 +3281,7 @@
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
-        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false,
+        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
                 TEST_CALLBACK_TIMEOUT_MS);
 
         // pass timeout and validate that UNAVAILABLE is not called
@@ -3243,7 +3301,7 @@
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
-        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false,
+        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, false, false,
                 TEST_CALLBACK_TIMEOUT_MS);
         mWiFiNetworkAgent.disconnect();
         networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
@@ -3802,6 +3860,7 @@
         networkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, networkAgent);
         CallbackInfo cbi = networkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
                 networkAgent);
+        networkCallback.expectCallback(CallbackState.BLOCKED_STATUS, networkAgent);
         networkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, networkAgent);
         networkCallback.assertNoCallback();
         checkDirectlyConnectedRoutes(cbi.arg, Arrays.asList(myIpv4Address),
@@ -4010,6 +4069,7 @@
                 mCellNetworkAgent);
         CallbackInfo cbi = cellNetworkCallback.expectCallback(
                 CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackState.BLOCKED_STATUS, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
         assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
         assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
@@ -4068,6 +4128,7 @@
                 mCellNetworkAgent);
         CallbackInfo cbi = cellNetworkCallback.expectCallback(
                 CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackState.BLOCKED_STATUS, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
         assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
         assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
@@ -4444,6 +4505,101 @@
         mMockVpn.disconnect();
     }
 
+    @Test
+    public void testNetworkBlockedStatus() {
+        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
+        final NetworkRequest cellRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR)
+                .build();
+        mCm.registerNetworkCallback(cellRequest, cellNetworkCallback);
+
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.connect(true);
+        cellNetworkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
+
+        mService.setUidRulesChanged(RULE_REJECT_ALL);
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+
+        // ConnectivityService should cache it not to invoke the callback again.
+        mService.setUidRulesChanged(RULE_REJECT_METERED);
+        cellNetworkCallback.assertNoCallback();
+
+        mService.setUidRulesChanged(RULE_NONE);
+        cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+        mService.setUidRulesChanged(RULE_REJECT_METERED);
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+
+        // Restrict the network based on UID rule and NOT_METERED capability change.
+        mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        cellNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
+        cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+        mCellNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+        cellNetworkCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED,
+                mCellNetworkAgent);
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        mService.setUidRulesChanged(RULE_ALLOW_METERED);
+        cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+        mService.setUidRulesChanged(RULE_NONE);
+        cellNetworkCallback.assertNoCallback();
+
+        // Restrict the network based on BackgroundRestricted.
+        mService.setRestrictBackgroundChanged(true);
+        cellNetworkCallback.expectBlockedStatusCallback(true, mCellNetworkAgent);
+        mService.setRestrictBackgroundChanged(true);
+        cellNetworkCallback.assertNoCallback();
+        mService.setRestrictBackgroundChanged(false);
+        cellNetworkCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+
+        mCm.unregisterNetworkCallback(cellNetworkCallback);
+    }
+
+    @Test
+    public void testNetworkBlockedStatusBeforeAndAfterConnect() {
+        final TestNetworkCallback defaultCallback = new TestNetworkCallback();
+        mCm.registerDefaultNetworkCallback(defaultCallback);
+
+        // No Networkcallbacks invoked before any network is active.
+        mService.setUidRulesChanged(RULE_REJECT_ALL);
+        mService.setUidRulesChanged(RULE_NONE);
+        mService.setUidRulesChanged(RULE_REJECT_METERED);
+        defaultCallback.assertNoCallback();
+
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        mCellNetworkAgent.connect(true);
+        defaultCallback.expectAvailableCallbacksUnvalidatedAndBlocked(mCellNetworkAgent);
+        defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mCellNetworkAgent);
+
+        // Allow to use the network after switching to NOT_METERED network.
+        mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+        mWiFiNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        mWiFiNetworkAgent.connect(true);
+        defaultCallback.expectAvailableDoubleValidatedCallbacks(mWiFiNetworkAgent);
+
+        // Switch to METERED network. Restrict the use of the network.
+        mWiFiNetworkAgent.disconnect();
+        defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacksValidatedAndBlocked(mCellNetworkAgent);
+
+        // Network becomes NOT_METERED.
+        mCellNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
+        defaultCallback.expectCapabilitiesWith(NET_CAPABILITY_NOT_METERED, mCellNetworkAgent);
+        defaultCallback.expectBlockedStatusCallback(false, mCellNetworkAgent);
+
+        // Verify there's no Networkcallbacks invoked after data saver on/off.
+        mService.setRestrictBackgroundChanged(true);
+        mService.setRestrictBackgroundChanged(false);
+        defaultCallback.assertNoCallback();
+
+        mCellNetworkAgent.disconnect();
+        defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
+        defaultCallback.assertNoCallback();
+
+        mCm.unregisterNetworkCallback(defaultCallback);
+    }
+
     /**
      * Make simulated InterfaceConfig for Nat464Xlat to query clat lower layer info.
      */
diff --git a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
index 99a5a69..9b919abf 100644
--- a/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
+++ b/tests/net/java/com/android/server/IpSecServiceParameterizedTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server;
 
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
@@ -34,8 +36,10 @@
 import android.net.IpSecConfig;
 import android.net.IpSecManager;
 import android.net.IpSecSpiResponse;
+import android.net.IpSecTransform;
 import android.net.IpSecTransformResponse;
 import android.net.IpSecTunnelInterfaceResponse;
+import android.net.IpSecUdpEncapResponse;
 import android.net.LinkAddress;
 import android.net.Network;
 import android.net.NetworkUtils;
@@ -62,16 +66,17 @@
 
     private static final int TEST_SPI = 0xD1201D;
 
-    private final String mDestinationAddr;
     private final String mSourceAddr;
+    private final String mDestinationAddr;
     private final LinkAddress mLocalInnerAddress;
+    private final int mFamily;
 
     @Parameterized.Parameters
     public static Collection ipSecConfigs() {
         return Arrays.asList(
                 new Object[][] {
-                {"1.2.3.4", "8.8.4.4", "10.0.1.1/24"},
-                {"2601::2", "2601::10", "2001:db8::1/64"}
+                {"1.2.3.4", "8.8.4.4", "10.0.1.1/24", AF_INET},
+                {"2601::2", "2601::10", "2001:db8::1/64", AF_INET6}
         });
     }
 
@@ -129,12 +134,14 @@
             new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY);
     private static final IpSecAlgorithm AEAD_ALGO =
             new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, AEAD_KEY, 128);
+    private static final int REMOTE_ENCAP_PORT = 4500;
 
     public IpSecServiceParameterizedTest(
-            String sourceAddr, String destAddr, String localInnerAddr) {
+            String sourceAddr, String destAddr, String localInnerAddr, int family) {
         mSourceAddr = sourceAddr;
         mDestinationAddr = destAddr;
         mLocalInnerAddress = new LinkAddress(localInnerAddr);
+        mFamily = family;
     }
 
     @Before
@@ -157,6 +164,8 @@
             .thenReturn(AppOpsManager.MODE_IGNORED);
     }
 
+    //TODO: Add a test to verify SPI.
+
     @Test
     public void testIpSecServiceReserveSpi() throws Exception {
         when(mMockNetd.ipSecAllocateSpi(anyInt(), anyString(), eq(mDestinationAddr), eq(TEST_SPI)))
@@ -257,6 +266,47 @@
         config.setAuthentication(AUTH_ALGO);
     }
 
+    private void addEncapSocketToIpSecConfig(int resourceId, IpSecConfig config) throws Exception {
+        config.setEncapType(IpSecTransform.ENCAP_ESPINUDP);
+        config.setEncapSocketResourceId(resourceId);
+        config.setEncapRemotePort(REMOTE_ENCAP_PORT);
+    }
+
+    private void verifyTransformNetdCalledForCreatingSA(
+            IpSecConfig config, IpSecTransformResponse resp) throws Exception {
+        verifyTransformNetdCalledForCreatingSA(config, resp, 0);
+    }
+
+    private void verifyTransformNetdCalledForCreatingSA(
+            IpSecConfig config, IpSecTransformResponse resp, int encapSocketPort) throws Exception {
+        IpSecAlgorithm auth = config.getAuthentication();
+        IpSecAlgorithm crypt = config.getEncryption();
+        IpSecAlgorithm authCrypt = config.getAuthenticatedEncryption();
+
+        verify(mMockNetd, times(1))
+                .ipSecAddSecurityAssociation(
+                        eq(mUid),
+                        eq(config.getMode()),
+                        eq(config.getSourceAddress()),
+                        eq(config.getDestinationAddress()),
+                        eq((config.getNetwork() != null) ? config.getNetwork().netId : 0),
+                        eq(TEST_SPI),
+                        eq(0),
+                        eq(0),
+                        eq((auth != null) ? auth.getName() : ""),
+                        eq((auth != null) ? auth.getKey() : new byte[] {}),
+                        eq((auth != null) ? auth.getTruncationLengthBits() : 0),
+                        eq((crypt != null) ? crypt.getName() : ""),
+                        eq((crypt != null) ? crypt.getKey() : new byte[] {}),
+                        eq((crypt != null) ? crypt.getTruncationLengthBits() : 0),
+                        eq((authCrypt != null) ? authCrypt.getName() : ""),
+                        eq((authCrypt != null) ? authCrypt.getKey() : new byte[] {}),
+                        eq((authCrypt != null) ? authCrypt.getTruncationLengthBits() : 0),
+                        eq(config.getEncapType()),
+                        eq(encapSocketPort),
+                        eq(config.getEncapRemotePort()));
+    }
+
     @Test
     public void testCreateTransform() throws Exception {
         IpSecConfig ipSecConfig = new IpSecConfig();
@@ -267,28 +317,7 @@
                 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
         assertEquals(IpSecManager.Status.OK, createTransformResp.status);
 
-        verify(mMockNetd)
-                .ipSecAddSecurityAssociation(
-                        eq(mUid),
-                        anyInt(),
-                        anyString(),
-                        anyString(),
-                        anyInt(),
-                        eq(TEST_SPI),
-                        anyInt(),
-                        anyInt(),
-                        eq(IpSecAlgorithm.AUTH_HMAC_SHA256),
-                        eq(AUTH_KEY),
-                        anyInt(),
-                        eq(IpSecAlgorithm.CRYPT_AES_CBC),
-                        eq(CRYPT_KEY),
-                        anyInt(),
-                        eq(""),
-                        eq(new byte[] {}),
-                        eq(0),
-                        anyInt(),
-                        anyInt(),
-                        anyInt());
+        verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
     }
 
     @Test
@@ -302,28 +331,59 @@
                 mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
         assertEquals(IpSecManager.Status.OK, createTransformResp.status);
 
-        verify(mMockNetd)
-                .ipSecAddSecurityAssociation(
-                        eq(mUid),
-                        anyInt(),
-                        anyString(),
-                        anyString(),
-                        anyInt(),
-                        eq(TEST_SPI),
-                        anyInt(),
-                        anyInt(),
-                        eq(""),
-                        eq(new byte[] {}),
-                        eq(0),
-                        eq(""),
-                        eq(new byte[] {}),
-                        eq(0),
-                        eq(IpSecAlgorithm.AUTH_CRYPT_AES_GCM),
-                        eq(AEAD_KEY),
-                        anyInt(),
-                        anyInt(),
-                        anyInt(),
-                        anyInt());
+        verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp);
+    }
+
+    @Test
+    public void testCreateTransportModeTransformWithEncap() throws Exception {
+        IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        ipSecConfig.setMode(IpSecTransform.MODE_TRANSPORT);
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+        addAuthAndCryptToIpSecConfig(ipSecConfig);
+        addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig);
+
+        if (mFamily == AF_INET) {
+            IpSecTransformResponse createTransformResp =
+                    mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+            assertEquals(IpSecManager.Status.OK, createTransformResp.status);
+
+            verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
+        } else {
+            try {
+                IpSecTransformResponse createTransformResp =
+                        mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+                fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
+            } catch (IllegalArgumentException expected) {
+            }
+        }
+    }
+
+    @Test
+    public void testCreateTunnelModeTransformWithEncap() throws Exception {
+        IpSecUdpEncapResponse udpSock = mIpSecService.openUdpEncapsulationSocket(0, new Binder());
+
+        IpSecConfig ipSecConfig = new IpSecConfig();
+        ipSecConfig.setMode(IpSecTransform.MODE_TUNNEL);
+        addDefaultSpisAndRemoteAddrToIpSecConfig(ipSecConfig);
+        addAuthAndCryptToIpSecConfig(ipSecConfig);
+        addEncapSocketToIpSecConfig(udpSock.resourceId, ipSecConfig);
+
+        if (mFamily == AF_INET) {
+            IpSecTransformResponse createTransformResp =
+                    mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+            assertEquals(IpSecManager.Status.OK, createTransformResp.status);
+
+            verifyTransformNetdCalledForCreatingSA(ipSecConfig, createTransformResp, udpSock.port);
+        } else {
+            try {
+                IpSecTransformResponse createTransformResp =
+                        mIpSecService.createTransform(ipSecConfig, new Binder(), "blessedPackage");
+                fail("Expected IllegalArgumentException on attempt to use UDP Encap in IPv6");
+            } catch (IllegalArgumentException expected) {
+            }
+        }
     }
 
     @Test
diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
index 9c4da1f..14312cf 100644
--- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
+++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java
@@ -83,16 +83,6 @@
         }
 
         try {
-            mWm.setFocusedApp(null, false);
-            fail("IWindowManager.setFocusedApp did not throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        } catch (RemoteException e) {
-            fail("Unexpected remote exception");
-        }
-
-        try {
             mWm.prepareAppTransition(0, false);
             fail("IWindowManager.prepareAppTransition did not throw SecurityException as"
                     + " expected");
diff --git a/tests/testables/src/android/testing/TestableContext.java b/tests/testables/src/android/testing/TestableContext.java
index cf84c79..fff9635 100644
--- a/tests/testables/src/android/testing/TestableContext.java
+++ b/tests/testables/src/android/testing/TestableContext.java
@@ -53,7 +53,7 @@
  * Like the following:</p>
  * <pre class="prettyprint">
  * &#064;Rule
- * private final TestableContext mContext = new TestableContext(InstrumentationRegister.getContext());
+ * public final TestableContext mContext = new TestableContext(InstrumentationRegister.getContext());
  * </pre>
  */
 public class TestableContext extends ContextWrapper implements TestRule {
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index d631f35..f06643d 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -28,7 +28,7 @@
 
 /* these formats are already compressed, or don't compress well */
 static const char* kNoCompressExt[] = {
-    ".jpg", ".jpeg", ".png", ".gif",
+    ".jpg", ".jpeg", ".png", ".gif", ".opus",
     ".wav", ".mp2", ".mp3", ".ogg", ".aac",
     ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
     ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index c02ca21..ba498e1 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -123,7 +123,6 @@
         "util/BigBuffer.cpp",
         "util/Files.cpp",
         "util/Util.cpp",
-        "ConfigDescription.cpp",
         "Debug.cpp",
         "DominatorTree.cpp",
         "java/AnnotationProcessor.cpp",
@@ -132,7 +131,6 @@
         "java/ManifestClassGenerator.cpp",
         "java/ProguardRules.cpp",
         "LoadedApk.cpp",
-        "Locale.cpp",
         "Resource.cpp",
         "ResourceParser.cpp",
         "ResourceTable.cpp",
diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk
index c9987b8..b165c6b 100644
--- a/tools/aapt2/Android.mk
+++ b/tools/aapt2/Android.mk
@@ -2,10 +2,19 @@
 
 include $(CLEAR_VARS)
 
+aapt2_results := $(call intermediates-dir-for,PACKAGING,aapt2_run_host_unit_tests)/result.xml
+
 # Target for running host unit tests on post/pre-submit.
 .PHONY: aapt2_run_host_unit_tests
-aapt2_run_host_unit_tests: PRIVATE_GTEST_OPTIONS := --gtest_output=xml:$(DIST_DIR)/gtest/aapt2_host_unit_tests_result.xml
-aapt2_run_host_unit_tests: $(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests
-	-$(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests $(PRIVATE_GTEST_OPTIONS) > /dev/null 2>&1
+aapt2_run_host_unit_tests: $(aapt2_results)
+
+$(call dist-for-goals,aapt2_run_host_unit_tests,$(aapt2_results):gtest/aapt2_host_unit_tests_result.xml)
+
+# Always run the tests again, even if they haven't changed
+$(aapt2_results): .KATI_IMPLICIT_OUTPUTS := $(aapt2_results)-nocache
+$(aapt2_results): $(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests
+	-$(HOST_OUT_NATIVE_TESTS)/aapt2_tests/aapt2_tests --gtest_output=xml:$@ > /dev/null 2>&1
+
+aapt2_results :=
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/aapt2/DominatorTree.cpp b/tools/aapt2/DominatorTree.cpp
index 118a385..ff18033 100644
--- a/tools/aapt2/DominatorTree.cpp
+++ b/tools/aapt2/DominatorTree.cpp
@@ -19,8 +19,9 @@
 #include <algorithm>
 
 #include "android-base/logging.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
+using ::android::ConfigDescription;
 
 namespace aapt {
 
diff --git a/tools/aapt2/DominatorTree_test.cpp b/tools/aapt2/DominatorTree_test.cpp
index efc523f..fe4f951 100644
--- a/tools/aapt2/DominatorTree_test.cpp
+++ b/tools/aapt2/DominatorTree_test.cpp
@@ -23,6 +23,8 @@
 #include "test/Test.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 namespace {
diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp
index a20b9b7..b353ff0 100644
--- a/tools/aapt2/LoadedApk.cpp
+++ b/tools/aapt2/LoadedApk.cpp
@@ -35,6 +35,43 @@
 
 namespace aapt {
 
+static ApkFormat DetermineApkFormat(io::IFileCollection* apk) {
+  if (apk->FindFile(kApkResourceTablePath) != nullptr) {
+    return ApkFormat::kBinary;
+  } else if (apk->FindFile(kProtoResourceTablePath) != nullptr) {
+    return ApkFormat::kProto;
+  } else {
+    // If the resource table is not present, attempt to read the manifest.
+    io::IFile* manifest_file = apk->FindFile(kAndroidManifestPath);
+    if (manifest_file == nullptr) {
+      return ApkFormat::kUnknown;
+    }
+
+    // First try in proto format.
+    std::unique_ptr<io::InputStream> manifest_in = manifest_file->OpenInputStream();
+    if (manifest_in != nullptr) {
+      pb::XmlNode pb_node;
+      io::ProtoInputStreamReader proto_reader(manifest_in.get());
+      if (proto_reader.ReadMessage(&pb_node)) {
+        return ApkFormat::kProto;
+      }
+    }
+
+    // If it didn't work, try in binary format.
+    std::unique_ptr<io::IData> manifest_data = manifest_file->OpenAsData();
+    if (manifest_data != nullptr) {
+      std::string error;
+      std::unique_ptr<xml::XmlResource> manifest =
+          xml::Inflate(manifest_data->data(), manifest_data->size(), &error);
+      if (manifest != nullptr) {
+        return ApkFormat::kBinary;
+      }
+    }
+
+    return ApkFormat::kUnknown;
+  }
+}
+
 std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(const StringPiece& path, IDiagnostics* diag) {
   Source source(path);
   std::string error;
@@ -301,41 +338,4 @@
   return doc;
 }
 
-ApkFormat LoadedApk::DetermineApkFormat(io::IFileCollection* apk) {
-  if (apk->FindFile(kApkResourceTablePath) != nullptr) {
-    return ApkFormat::kBinary;
-  } else if (apk->FindFile(kProtoResourceTablePath) != nullptr) {
-    return ApkFormat::kProto;
-  } else {
-    // If the resource table is not present, attempt to read the manifest.
-    io::IFile* manifest_file = apk->FindFile(kAndroidManifestPath);
-    if (manifest_file == nullptr) {
-      return ApkFormat::kUnknown;
-    }
-
-    // First try in proto format.
-    std::unique_ptr<io::InputStream> manifest_in = manifest_file->OpenInputStream();
-    if (manifest_in != nullptr) {
-      pb::XmlNode pb_node;
-      io::ProtoInputStreamReader proto_reader(manifest_in.get());
-      if (!proto_reader.ReadMessage(&pb_node)) {
-        return ApkFormat::kProto;
-      }
-    }
-
-    // If it didn't work, try in binary format.
-    std::unique_ptr<io::IData> manifest_data = manifest_file->OpenAsData();
-    if (manifest_data != nullptr) {
-      std::string error;
-      std::unique_ptr<xml::XmlResource> manifest =
-          xml::Inflate(manifest_data->data(), manifest_data->size(), &error);
-      if (manifest != nullptr) {
-        return ApkFormat::kBinary;
-      }
-    }
-
-    return ApkFormat::kUnknown;
-  }
-}
-
 }  // namespace aapt
diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h
index 84c57c1..5b6f45e 100644
--- a/tools/aapt2/LoadedApk.h
+++ b/tools/aapt2/LoadedApk.h
@@ -121,8 +121,6 @@
   std::unique_ptr<ResourceTable> table_;
   std::unique_ptr<xml::XmlResource> manifest_;
   ApkFormat format_;
-
-  static ApkFormat DetermineApkFormat(io::IFileCollection* apk);
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 37013c0..adf85b0 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -36,6 +36,7 @@
 #include "cmd/Dump.h"
 #include "cmd/Link.h"
 #include "cmd/Optimize.h"
+#include "io/FileStream.h"
 #include "util/Files.h"
 #include "util/Util.h"
 
@@ -68,10 +69,11 @@
 /** The main entry point of AAPT. */
 class MainCommand : public Command {
  public:
-  explicit MainCommand(IDiagnostics* diagnostics) : Command("aapt2"), diagnostics_(diagnostics) {
+  explicit MainCommand(text::Printer* printer, IDiagnostics* diagnostics)
+      : Command("aapt2"), diagnostics_(diagnostics) {
     AddOptionalSubcommand(util::make_unique<CompileCommand>(diagnostics));
     AddOptionalSubcommand(util::make_unique<LinkCommand>(diagnostics));
-    AddOptionalSubcommand(util::make_unique<DumpCommand>(diagnostics));
+    AddOptionalSubcommand(util::make_unique<DumpCommand>(printer, diagnostics));
     AddOptionalSubcommand(util::make_unique<DiffCommand>());
     AddOptionalSubcommand(util::make_unique<OptimizeCommand>());
     AddOptionalSubcommand(util::make_unique<ConvertCommand>());
@@ -101,13 +103,14 @@
  */
 class DaemonCommand : public Command {
  public:
-  explicit DaemonCommand(IDiagnostics* diagnostics) : Command("daemon", "m"),
-                                                      diagnostics_(diagnostics) {
+  explicit DaemonCommand(io::FileOutputStream* out, IDiagnostics* diagnostics)
+      : Command("daemon", "m"), out_(out), diagnostics_(diagnostics) {
     SetDescription("Runs aapt in daemon mode. Each subsequent line is a single parameter to the\n"
         "command. The end of an invocation is signaled by providing an empty line.");
   }
 
   int Action(const std::vector<std::string>& /* args */) override {
+    text::Printer printer(out_);
     std::cout << "Ready" << std::endl;
 
     while (true) {
@@ -132,7 +135,9 @@
 
       std::vector<StringPiece> args;
       args.insert(args.end(), raw_args.begin(), raw_args.end());
-      if (MainCommand(diagnostics_).Execute(args, &std::cerr) != 0) {
+      int result = MainCommand(&printer, diagnostics_).Execute(args, &std::cerr);
+      out_->Flush();
+      if (result != 0) {
         std::cerr << "Error" << std::endl;
       }
       std::cerr << "Done" << std::endl;
@@ -143,6 +148,7 @@
   }
 
  private:
+  io::FileOutputStream* out_;
   IDiagnostics* diagnostics_;
 };
 
@@ -159,11 +165,17 @@
     args.push_back(argv[i]);
   }
 
-  // Add the daemon subcommand here so it cannot be called while executing the daemon
-  aapt::StdErrDiagnostics diagnostics;
-  auto main_command = new aapt::MainCommand(&diagnostics);
-  main_command->AddOptionalSubcommand(aapt::util::make_unique<aapt::DaemonCommand>(&diagnostics));
+  // Use a smaller buffer so that there is less latency for printing to stdout.
+  constexpr size_t kStdOutBufferSize = 1024u;
+  aapt::io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
+  aapt::text::Printer printer(&fout);
 
+  aapt::StdErrDiagnostics diagnostics;
+  auto main_command = new aapt::MainCommand(&printer, &diagnostics);
+
+  // Add the daemon subcommand here so it cannot be called while executing the daemon
+  main_command->AddOptionalSubcommand(
+      aapt::util::make_unique<aapt::DaemonCommand>(&fout, &diagnostics));
   return main_command->Execute(args, &std::cerr);
 }
 
diff --git a/tools/aapt2/OWNERS b/tools/aapt2/OWNERS
index 23ec5ab..f1903a5 100644
--- a/tools/aapt2/OWNERS
+++ b/tools/aapt2/OWNERS
@@ -1,2 +1,3 @@
 set noparent
 toddke@google.com
+rtmitchell@google.com
\ No newline at end of file
diff --git a/tools/aapt2/Resource.h b/tools/aapt2/Resource.h
index 879d0bd..dd5c751 100644
--- a/tools/aapt2/Resource.h
+++ b/tools/aapt2/Resource.h
@@ -24,10 +24,10 @@
 #include <tuple>
 #include <vector>
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 #include "utils/JenkinsHash.h"
 
-#include "ConfigDescription.h"
 #include "Source.h"
 
 namespace aapt {
@@ -176,7 +176,7 @@
   ResourceName name;
 
   // Configuration
-  ConfigDescription config;
+  android::ConfigDescription config;
 
   // Type
   Type type;
@@ -194,7 +194,7 @@
  */
 struct ResourceKey {
   ResourceName name;
-  ConfigDescription config;
+  android::ConfigDescription config;
 };
 
 bool operator<(const ResourceKey& a, const ResourceKey& b);
@@ -206,16 +206,16 @@
  */
 struct ResourceKeyRef {
   ResourceNameRef name;
-  ConfigDescription config;
+  android::ConfigDescription config;
 
   ResourceKeyRef() = default;
-  ResourceKeyRef(const ResourceNameRef& n, const ConfigDescription& c)
+  ResourceKeyRef(const ResourceNameRef& n, const android::ConfigDescription& c)
       : name(n), config(c) {}
 
   /**
    * Prevent taking a reference to a temporary. This is bad.
    */
-  ResourceKeyRef(ResourceName&& n, const ConfigDescription& c) = delete;
+  ResourceKeyRef(ResourceName&& n, const android::ConfigDescription& c) = delete;
 };
 
 bool operator<(const ResourceKeyRef& a, const ResourceKeyRef& b);
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 8719a23..9a3f14c 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -34,6 +34,7 @@
 
 using ::aapt::ResourceUtils::StringBuilder;
 using ::aapt::text::Utf8Iterator;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 
 namespace aapt {
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index 68130c2..06bb0c9 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -20,9 +20,9 @@
 #include <memory>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -57,7 +57,7 @@
 class ResourceParser {
  public:
   ResourceParser(IDiagnostics* diag, ResourceTable* table, const Source& source,
-                 const ConfigDescription& config,
+                 const android::ConfigDescription& config,
                  const ResourceParserOptions& options = {});
   bool Parse(xml::XmlPullParser* parser);
 
@@ -114,7 +114,7 @@
   IDiagnostics* diag_;
   ResourceTable* table_;
   Source source_;
-  ConfigDescription config_;
+  android::ConfigDescription config_;
   ResourceParserOptions options_;
 };
 
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index ee496d5..0dff664 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -29,6 +29,7 @@
 using ::aapt::io::StringInputStream;
 using ::aapt::test::StrValueEq;
 using ::aapt::test::ValueEq;
+using ::android::ConfigDescription;
 using ::android::Res_value;
 using ::android::ResTable_map;
 using ::android::StringPiece;
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 23322ab..056a27b 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -23,9 +23,9 @@
 
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "ConfigDescription.h"
 #include "Debug.h"
 #include "NameMangler.h"
 #include "ResourceValues.h"
@@ -34,6 +34,7 @@
 #include "util/Util.h"
 
 using ::aapt::text::IsValidResourceEntryName;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::base::StringPrintf;
 
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 5a43a2d..1917d7e 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -17,7 +17,6 @@
 #ifndef AAPT_RESOURCE_TABLE_H
 #define AAPT_RESOURCE_TABLE_H
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "Resource.h"
 #include "ResourceValues.h"
@@ -26,6 +25,7 @@
 #include "io/File.h"
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
 #include <functional>
@@ -66,7 +66,7 @@
 class ResourceConfigValue {
  public:
   // The configuration for which this value is defined.
-  const ConfigDescription config;
+  const android::ConfigDescription config;
 
   // The product for which this value is defined.
   const std::string product;
@@ -74,7 +74,7 @@
   // The actual Value.
   std::unique_ptr<Value> value;
 
-  ResourceConfigValue(const ConfigDescription& config, const android::StringPiece& product)
+  ResourceConfigValue(const android::ConfigDescription& config, const android::StringPiece& product)
       : config(config), product(product.to_string()) {}
 
  private:
@@ -103,14 +103,14 @@
 
   explicit ResourceEntry(const android::StringPiece& name) : name(name.to_string()) {}
 
-  ResourceConfigValue* FindValue(const ConfigDescription& config);
+  ResourceConfigValue* FindValue(const android::ConfigDescription& config);
 
-  ResourceConfigValue* FindValue(const ConfigDescription& config,
+  ResourceConfigValue* FindValue(const android::ConfigDescription& config,
                                  const android::StringPiece& product);
 
-  ResourceConfigValue* FindOrCreateValue(const ConfigDescription& config,
+  ResourceConfigValue* FindOrCreateValue(const android::ConfigDescription& config,
                                          const android::StringPiece& product);
-  std::vector<ResourceConfigValue*> FindAllValues(const ConfigDescription& config);
+  std::vector<ResourceConfigValue*> FindAllValues(const android::ConfigDescription& config);
 
   template <typename Func>
   std::vector<ResourceConfigValue*> FindValuesIf(Func f) {
@@ -189,29 +189,30 @@
   // When a collision of resources occurs, this method keeps both values
   static CollisionResult IgnoreCollision(Value* existing, Value* incoming);
 
-  bool AddResource(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddResource(const ResourceNameRef& name, const android::ConfigDescription& config,
                    const android::StringPiece& product, std::unique_ptr<Value> value,
                    IDiagnostics* diag);
 
   bool AddResourceWithId(const ResourceNameRef& name, const ResourceId& res_id,
-                         const ConfigDescription& config, const android::StringPiece& product,
-                         std::unique_ptr<Value> value, IDiagnostics* diag);
+                         const android::ConfigDescription& config,
+                         const android::StringPiece& product, std::unique_ptr<Value> value,
+                         IDiagnostics* diag);
 
-  bool AddFileReference(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddFileReference(const ResourceNameRef& name, const android::ConfigDescription& config,
                         const Source& source, const android::StringPiece& path, IDiagnostics* diag);
 
-  bool AddFileReferenceMangled(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddFileReferenceMangled(const ResourceNameRef& name, const android::ConfigDescription& config,
                                const Source& source, const android::StringPiece& path,
                                io::IFile* file, IDiagnostics* diag);
 
   // Same as AddResource, but doesn't verify the validity of the name. This is used
   // when loading resources from an existing binary resource table that may have mangled names.
-  bool AddResourceMangled(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddResourceMangled(const ResourceNameRef& name, const android::ConfigDescription& config,
                           const android::StringPiece& product, std::unique_ptr<Value> value,
                           IDiagnostics* diag);
 
   bool AddResourceWithIdMangled(const ResourceNameRef& name, const ResourceId& id,
-                                const ConfigDescription& config,
+                                const android::ConfigDescription& config,
                                 const android::StringPiece& product, std::unique_ptr<Value> value,
                                 IDiagnostics* diag);
 
@@ -286,11 +287,12 @@
                     IDiagnostics* diag);
 
   bool AddResourceImpl(const ResourceNameRef& name, const ResourceId& res_id,
-                       const ConfigDescription& config, const android::StringPiece& product,
-                       std::unique_ptr<Value> value, NameValidator name_validator,
-                       const CollisionResolverFunc& conflict_resolver, IDiagnostics* diag);
+                       const android::ConfigDescription& config,
+                       const android::StringPiece& product, std::unique_ptr<Value> value,
+                       NameValidator name_validator, const CollisionResolverFunc& conflict_resolver,
+                       IDiagnostics* diag);
 
-  bool AddFileReferenceImpl(const ResourceNameRef& name, const ConfigDescription& config,
+  bool AddFileReferenceImpl(const ResourceNameRef& name, const android::ConfigDescription& config,
                             const Source& source, const android::StringPiece& path, io::IFile* file,
                             NameValidator name_validator, IDiagnostics* diag);
 
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
index 1aa9751..05c6f15 100644
--- a/tools/aapt2/ResourceTable_test.cpp
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -24,6 +24,7 @@
 #include <ostream>
 #include <string>
 
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::testing::Eq;
 using ::testing::NotNull;
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index c48765b..dbe5ac5 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -31,6 +31,7 @@
 #include "util/Util.h"
 
 using ::aapt::text::Utf8Iterator;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::StringPiece16;
 using ::android::base::StringPrintf;
@@ -38,6 +39,8 @@
 namespace aapt {
 namespace ResourceUtils {
 
+constexpr int32_t kNonBreakingSpace = 0xa0;
+
 Maybe<ResourceName> ToResourceName(
     const android::ResTable::resource_name& name_in) {
   ResourceName name_out;
@@ -810,7 +813,7 @@
   Utf8Iterator iter(text);
   while (iter.HasNext()) {
     char32_t codepoint = iter.Next();
-    if (!preserve_spaces && !quote_ && iswspace(codepoint)) {
+    if (!preserve_spaces && !quote_ && codepoint != kNonBreakingSpace && iswspace(codepoint)) {
       if (!last_codepoint_was_space_) {
         // Emit a space if it's the first.
         xml_string_.text += ' ';
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index 410ef28..e282fd58 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -20,6 +20,7 @@
 #include <functional>
 #include <memory>
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
 
@@ -219,7 +220,8 @@
 
 // Parses the binary form of a resource value. `type` is used as a hint to know when a value is
 // an ID versus a False boolean value, etc. `config` is for sorting strings in the string pool.
-std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type, const ConfigDescription& config,
+std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type,
+                                          const android::ConfigDescription& config,
                                           const android::ResStringPool& src_pool,
                                           const android::Res_value& res_value,
                                           StringPool* dst_pool);
diff --git a/tools/aapt2/StringPool.h b/tools/aapt2/StringPool.h
index f5b464d..1006ca9 100644
--- a/tools/aapt2/StringPool.h
+++ b/tools/aapt2/StringPool.h
@@ -24,9 +24,9 @@
 #include <vector>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "util/BigBuffer.h"
 
@@ -60,12 +60,12 @@
       kLowPriority = 0xffffffffu,
     };
     uint32_t priority = kNormalPriority;
-    ConfigDescription config;
+    android::ConfigDescription config;
 
     Context() = default;
-    Context(uint32_t p, const ConfigDescription& c) : priority(p), config(c) {}
+    Context(uint32_t p, const android::ConfigDescription& c) : priority(p), config(c) {}
     explicit Context(uint32_t p) : priority(p) {}
-    explicit Context(const ConfigDescription& c) : priority(kNormalPriority), config(c) {
+    explicit Context(const android::ConfigDescription& c) : priority(kNormalPriority), config(c) {
     }
   };
 
diff --git a/tools/aapt2/cmd/Command.cpp b/tools/aapt2/cmd/Command.cpp
index 09411b9..bdee5c9 100644
--- a/tools/aapt2/cmd/Command.cpp
+++ b/tools/aapt2/cmd/Command.cpp
@@ -93,9 +93,13 @@
   flags_.push_back(Flag{name.to_string(), description.to_string(), func, false, 0, false});
 }
 
-void Command::AddOptionalSubcommand(std::unique_ptr<Command>&& subcommand) {
+void Command::AddOptionalSubcommand(std::unique_ptr<Command>&& subcommand, bool experimental) {
   subcommand->fullname_ = name_ + " " + subcommand->name_;
-  subcommands_.push_back(std::move(subcommand));
+  if (experimental) {
+    experimental_subcommands_.push_back(std::move(subcommand));
+  } else {
+    subcommands_.push_back(std::move(subcommand));
+  }
 }
 
 void Command::SetDescription(const android::StringPiece& description) {
@@ -162,7 +166,7 @@
   for (size_t i = 0; i < args.size(); i++) {
     StringPiece arg = args[i];
     if (*(arg.data()) != '-') {
-      // Continue parsing as the sub command if the first argument matches one of the subcommands
+      // Continue parsing as the subcommand if the first argument matches one of the subcommands
       if (i == 0) {
         for (auto& subcommand : subcommands_) {
           if (arg == subcommand->name_ || arg==subcommand->short_name_) {
@@ -170,6 +174,12 @@
                 std::vector<android::StringPiece>(args.begin() + 1, args.end()), out_error);
           }
         }
+        for (auto& subcommand : experimental_subcommands_) {
+          if (arg == subcommand->name_ || arg==subcommand->short_name_) {
+            return subcommand->Execute(
+              std::vector<android::StringPiece>(args.begin() + 1, args.end()), out_error);
+          }
+        }
       }
 
       file_args.push_back(arg.to_string());
diff --git a/tools/aapt2/cmd/Command.h b/tools/aapt2/cmd/Command.h
index 71dc6fe..1694988 100644
--- a/tools/aapt2/cmd/Command.h
+++ b/tools/aapt2/cmd/Command.h
@@ -49,7 +49,7 @@
       const android::StringPiece& description, std::unordered_set<std::string>* value);
   void AddOptionalSwitch(const android::StringPiece& name, const android::StringPiece& description,
       bool* value);
-  void AddOptionalSubcommand(std::unique_ptr<Command>&& subcommand);
+  void AddOptionalSubcommand(std::unique_ptr<Command>&& subcommand, bool experimental = false);
 
   void SetDescription(const android::StringPiece& name);
 
@@ -83,6 +83,7 @@
   std::string fullname_;
   std::vector<Flag> flags_;
   std::vector<std::unique_ptr<Command>> subcommands_;
+  std::vector<std::unique_ptr<Command>> experimental_subcommands_;
 };
 
 }  // namespace aapt
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 62c19fb..fc9514a 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -22,11 +22,11 @@
 #include "android-base/errors.h"
 #include "android-base/file.h"
 #include "android-base/utf8.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 #include "google/protobuf/io/coded_stream.h"
 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "ResourceParser.h"
 #include "ResourceTable.h"
@@ -53,6 +53,7 @@
 
 using ::aapt::io::FileInputStream;
 using ::aapt::text::Printer;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::base::SystemErrorCodeToString;
 using ::google::protobuf::io::CopyingOutputStreamAdaptor;
@@ -73,9 +74,9 @@
 };
 
 // Resource file paths are expected to look like: [--/res/]type[-config]/name
-static Maybe<ResourcePathData> ExtractResourcePathData(const std::string& path,
+static Maybe<ResourcePathData> ExtractResourcePathData(const std::string& path, const char dir_sep,
                                                        std::string* out_error) {
-  std::vector<std::string> parts = util::Split(path, file::sDirSep);
+  std::vector<std::string> parts = util::Split(path, dir_sep);
   if (parts.size() < 2) {
     if (out_error) *out_error = "bad resource path";
     return {};
@@ -656,7 +657,7 @@
     // Extract resource type information from the full path
     std::string err_str;
     ResourcePathData path_data;
-    if (auto maybe_path_data = ExtractResourcePathData(path, &err_str)) {
+    if (auto maybe_path_data = ExtractResourcePathData(path, inputs->GetDirSeparator(), &err_str)) {
       path_data = maybe_path_data.value();
     } else {
       context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << err_str);
@@ -731,7 +732,7 @@
   // Collect the resources files to compile
   if (options_.res_dir && options_.res_zip) {
     context.GetDiagnostics()->Error(DiagMessage()
-                                        << "only one of --dir and --zip can be specified");
+                                      << "only one of --dir and --zip can be specified");
     return 1;
   } else if (options_.res_dir) {
     if (!args.empty()) {
diff --git a/tools/aapt2/cmd/Compile_test.cpp b/tools/aapt2/cmd/Compile_test.cpp
index dd5198c..c0c05cd 100644
--- a/tools/aapt2/cmd/Compile_test.cpp
+++ b/tools/aapt2/cmd/Compile_test.cpp
@@ -17,6 +17,9 @@
 #include "Compile.h"
 
 #include "android-base/file.h"
+#include "android-base/stringprintf.h"
+#include "android-base/utf8.h"
+
 #include "io/StringStream.h"
 #include "io/ZipArchive.h"
 #include "java/AnnotationProcessor.h"
@@ -24,8 +27,20 @@
 
 namespace aapt {
 
+std::string BuildPath(std::vector<std::string> args) {
+  std::string out;
+  if (args.empty()) {
+    return out;
+  }
+  out = args[0];
+  for (int i = 1; i < args.size(); i++) {
+    file::AppendPath(&out, args[i]);
+  }
+  return out;
+}
+
 int TestCompile(const std::string& path, const std::string& outDir, bool legacy,
-    StdErrDiagnostics& diag) {
+                StdErrDiagnostics& diag) {
   std::vector<android::StringPiece> args;
   args.push_back(path);
   args.push_back("-o");
@@ -39,95 +54,101 @@
 TEST(CompilerTest, MultiplePeriods) {
   StdErrDiagnostics diag;
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
-  const std::string kResDir = android::base::Dirname(android::base::GetExecutablePath())
-      + "/integration-tests/CompileTest/res";
+  const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()),
+                                         "integration-tests", "CompileTest", "res"});
 
   // Resource files without periods in the file name should not throw errors
-  const std::string path0 = kResDir + "/values/values.xml";
-  const std::string path0_out = kResDir + "/values_values.arsc.flat";
-
-  remove(path0_out.c_str());
+  const std::string path0 = BuildPath({kResDir, "values", "values.xml"});
+  const std::string path0_out = BuildPath({kResDir, "values_values.arsc.flat"});
+  ::android::base::utf8::unlink(path0_out.c_str());
   ASSERT_EQ(TestCompile(path0, kResDir, /** legacy */ false, diag), 0);
-  ASSERT_EQ(remove(path0_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path0_out.c_str()), 0);
   ASSERT_EQ(TestCompile(path0, kResDir, /** legacy */ true, diag), 0);
-  ASSERT_EQ(remove(path0_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path0_out.c_str()), 0);
 
-  const std::string path1 = kResDir + "/drawable/image.png";
-  const std::string path1_out = kResDir + "/drawable_image.png.flat";
-  remove(path1_out.c_str());
+  const std::string path1 = BuildPath({kResDir, "drawable", "image.png"});
+  const std::string path1_out = BuildPath({kResDir, "drawable_image.png.flat"});
+  ::android::base::utf8::unlink(path1_out.c_str());
   ASSERT_EQ(TestCompile(path1, kResDir, /** legacy */ false, diag), 0);
-  ASSERT_EQ(remove(path1_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path1_out.c_str()), 0);
   ASSERT_EQ(TestCompile(path1, kResDir, /** legacy */ true, diag), 0);
-  ASSERT_EQ(remove(path1_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path1_out.c_str()), 0);
 
-  const std::string path2 = kResDir + "/drawable/image.9.png";
-  const std::string path2_out = kResDir + "/drawable_image.9.png.flat";
-  remove(path2_out.c_str());
+  const std::string path2 = BuildPath({kResDir, "drawable", "image.9.png"});
+  const std::string path2_out = BuildPath({kResDir, "drawable_image.9.png.flat"});
+  ::android::base::utf8::unlink(path2_out.c_str());
   ASSERT_EQ(TestCompile(path2, kResDir, /** legacy */ false, diag), 0);
-  ASSERT_EQ(remove(path2_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path2_out.c_str()), 0);
   ASSERT_EQ(TestCompile(path2, kResDir, /** legacy */ true, diag), 0);
-  ASSERT_EQ(remove(path2_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path2_out.c_str()), 0);
 
   // Resource files with periods in the file name should fail on non-legacy compilations
-  const std::string path3 = kResDir + "/values/values.all.xml";
-  const std::string path3_out = kResDir + "/values_values.all.arsc.flat";
-  remove(path3_out.c_str());
+  const std::string path3 = BuildPath({kResDir, "values", "values.all.xml"});
+  const std::string path3_out = BuildPath({kResDir, "values_values.all.arsc.flat"});
+  ::android::base::utf8::unlink(path3_out.c_str());
   ASSERT_NE(TestCompile(path3, kResDir, /** legacy */ false, diag), 0);
-  ASSERT_NE(remove(path3_out.c_str()), 0);
+  ASSERT_NE(::android::base::utf8::unlink(path3_out.c_str()), 0);
   ASSERT_EQ(TestCompile(path3, kResDir, /** legacy */ true, diag), 0);
-  ASSERT_EQ(remove(path3_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path3_out.c_str()), 0);
 
-  const std::string path4 = kResDir + "/drawable/image.small.png";
-  const std::string path4_out = (kResDir + std::string("/drawable_image.small.png.flat")).c_str();
-  remove(path4_out.c_str());
+  const std::string path4 = BuildPath({kResDir, "drawable", "image.small.png"});
+  const std::string path4_out = BuildPath({kResDir, "drawable_image.small.png.flat"});
+  ::android::base::utf8::unlink(path4_out.c_str());
   ASSERT_NE(TestCompile(path4, kResDir, /** legacy */ false, diag), 0);
-  ASSERT_NE(remove(path4_out.c_str()), 0);
+  ASSERT_NE(::android::base::utf8::unlink(path4_out.c_str()), 0);
   ASSERT_EQ(TestCompile(path4, kResDir, /** legacy */ true, diag), 0);
-  ASSERT_EQ(remove(path4_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path4_out.c_str()), 0);
 
-  const std::string path5 = kResDir + "/drawable/image.small.9.png";
-  const std::string path5_out = (kResDir + std::string("/drawable_image.small.9.png.flat")).c_str();
-  remove(path5_out.c_str());
+  const std::string path5 = BuildPath({kResDir, "drawable", "image.small.9.png"});
+  const std::string path5_out = BuildPath({kResDir, "drawable_image.small.9.png.flat"});
+  ::android::base::utf8::unlink(path5_out.c_str());
   ASSERT_NE(TestCompile(path5, kResDir, /** legacy */ false, diag), 0);
-  ASSERT_NE(remove(path5_out.c_str()), 0);
+  ASSERT_NE(::android::base::utf8::unlink(path5_out.c_str()), 0);
   ASSERT_EQ(TestCompile(path5, kResDir, /** legacy */ true, diag), 0);
-  ASSERT_EQ(remove(path5_out.c_str()), 0);
+  ASSERT_EQ(::android::base::utf8::unlink(path5_out.c_str()), 0);
 }
 
 TEST(CompilerTest, DirInput) {
   StdErrDiagnostics diag;
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
-  const std::string kResDir = android::base::Dirname(android::base::GetExecutablePath())
-                            + "/integration-tests/CompileTest/DirInput/res";
-  const std::string kOutputFlata = android::base::Dirname(android::base::GetExecutablePath())
-                                 + "/integration-tests/CompileTest/DirInput/compiled.flata";
-  remove(kOutputFlata.c_str());
+  const std::string kResDir = BuildPath({android::base::Dirname(android::base::GetExecutablePath()),
+                                         "integration-tests", "CompileTest", "DirInput", "res"});
+  const std::string kOutputFlata =
+      BuildPath({android::base::Dirname(android::base::GetExecutablePath()), "integration-tests",
+                 "CompileTest", "DirInput", "compiled.flata"});
+  ::android::base::utf8::unlink(kOutputFlata.c_str());
 
   std::vector<android::StringPiece> args;
   args.push_back("--dir");
   args.push_back(kResDir);
   args.push_back("-o");
   args.push_back(kOutputFlata);
+  args.push_back("-v");
   ASSERT_EQ(CompileCommand(&diag).Execute(args, &std::cerr), 0);
 
-  // Check for the presence of the compiled files
-  std::string err;
-  std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
-  ASSERT_NE(zip, nullptr) << err;
-  ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
-  ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
-  ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
-  ASSERT_EQ(remove(kOutputFlata.c_str()), 0);
+  {
+    // Check for the presence of the compiled files
+    std::string err;
+    std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
+    ASSERT_NE(zip, nullptr) << err;
+    ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
+    ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
+    ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
+  }
+  ASSERT_EQ(::android::base::utf8::unlink(kOutputFlata.c_str()), 0);
 }
 
 TEST(CompilerTest, ZipInput) {
   StdErrDiagnostics diag;
   std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
-  const std::string kResZip = android::base::Dirname(android::base::GetExecutablePath())
-                            + "/integration-tests/CompileTest/ZipInput/res.zip";
-  const std::string kOutputFlata = android::base::Dirname(android::base::GetExecutablePath())
-                                 + "/integration-tests/CompileTest/ZipInput/compiled.flata";
-  remove(kOutputFlata.c_str());
+  const std::string kResZip =
+      BuildPath({android::base::Dirname(android::base::GetExecutablePath()), "integration-tests",
+                 "CompileTest", "ZipInput", "res.zip"});
+  const std::string kOutputFlata =
+      BuildPath({android::base::Dirname(android::base::GetExecutablePath()), "integration-tests",
+                 "CompileTest", "ZipInput", "compiled.flata"});
+
+  ::android::base::utf8::unlink(kOutputFlata.c_str());
 
   std::vector<android::StringPiece> args;
   args.push_back("--zip");
@@ -136,14 +157,16 @@
   args.push_back(kOutputFlata);
   ASSERT_EQ(CompileCommand(&diag).Execute(args, &std::cerr), 0);
 
-  // Check for the presence of the compiled files
-  std::string err;
-  std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
-  ASSERT_NE(zip, nullptr) << err;
-  ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
-  ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
-  ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
-  ASSERT_EQ(remove(kOutputFlata.c_str()), 0);
+  {
+    // Check for the presence of the compiled files
+    std::string err;
+    std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(kOutputFlata, &err);
+    ASSERT_NE(zip, nullptr) << err;
+    ASSERT_NE(zip->FindFile("drawable_image.png.flat"), nullptr);
+    ASSERT_NE(zip->FindFile("layout_layout.xml.flat"), nullptr);
+    ASSERT_NE(zip->FindFile("values_values.arsc.flat"), nullptr);
+  }
+  ASSERT_EQ(::android::base::utf8::unlink(kOutputFlata.c_str()), 0);
 }
 
-} // namespace aapt
\ No newline at end of file
+}  // namespace aapt
\ No newline at end of file
diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp
index 954f1ed..3ea1755 100644
--- a/tools/aapt2/cmd/Convert.cpp
+++ b/tools/aapt2/cmd/Convert.cpp
@@ -46,7 +46,7 @@
   IApkSerializer(IAaptContext* context, const Source& source) : context_(context), source_(source) {}
 
   virtual bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
-                            IArchiveWriter* writer) = 0;
+                            IArchiveWriter* writer, uint32_t compression_flags) = 0;
   virtual bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) = 0;
   virtual bool SerializeFile(FileReference* file, IArchiveWriter* writer) = 0;
 
@@ -59,7 +59,10 @@
 
 bool ConvertApk(IAaptContext* context, unique_ptr<LoadedApk> apk, IApkSerializer* serializer,
                 IArchiveWriter* writer) {
-  if (!serializer->SerializeXml(apk->GetManifest(), kAndroidManifestPath, true /*utf16*/, writer)) {
+  io::IFile* manifest = apk->GetFileCollection()->FindFile(kAndroidManifestPath);
+  if (!serializer->SerializeXml(apk->GetManifest(), kAndroidManifestPath, true /*utf16*/, writer,
+                                (manifest != nullptr && manifest->WasCompressed())
+                                    ? ArchiveEntry::kCompress : 0u)) {
     context->GetDiagnostics()->Error(DiagMessage(apk->GetSource())
                                      << "failed to serialize AndroidManifest.xml");
     return false;
@@ -133,7 +136,7 @@
       : IApkSerializer(context, source), tableFlattenerOptions_(options) {}
 
   bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
-                    IArchiveWriter* writer) override {
+                    IArchiveWriter* writer, uint32_t compression_flags) override {
     BigBuffer buffer(4096);
     XmlFlattenerOptions options = {};
     options.use_utf16 = utf16;
@@ -144,8 +147,7 @@
     }
 
     io::BigBufferInputStream input_stream(&buffer);
-    return io::CopyInputStreamToArchive(context_, &input_stream, path, ArchiveEntry::kCompress,
-                                        writer);
+    return io::CopyInputStreamToArchive(context_, &input_stream, path, compression_flags, writer);
   }
 
   bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) override {
@@ -186,7 +188,8 @@
         return false;
       }
 
-      if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer)) {
+      if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer,
+                        file->file->WasCompressed() ? ArchiveEntry::kCompress : 0u)) {
         context_->GetDiagnostics()->Error(DiagMessage(source_)
                                           << "failed to serialize to binary XML: " << *file->path);
         return false;
@@ -216,10 +219,10 @@
       : IApkSerializer(context, source) {}
 
   bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
-                    IArchiveWriter* writer) override {
+                    IArchiveWriter* writer, uint32_t compression_flags) override {
     pb::XmlNode pb_node;
     SerializeXmlResourceToPb(*xml, &pb_node);
-    return io::CopyProtoToArchive(context_, &pb_node, path, ArchiveEntry::kCompress, writer);
+    return io::CopyProtoToArchive(context_, &pb_node, path, compression_flags, writer);
   }
 
   bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) override {
@@ -246,7 +249,8 @@
         return false;
       }
 
-      if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer)) {
+      if (!SerializeXml(xml.get(), *file->path, false /*utf16*/, writer,
+                        file->file->WasCompressed() ? ArchiveEntry::kCompress : 0u)) {
         context_->GetDiagnostics()->Error(DiagMessage(source_)
                                           << "failed to serialize to proto XML: " << *file->path);
         return false;
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index 91e3977..a23a6a4 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -20,6 +20,7 @@
 #include <vector>
 
 #include "android-base/stringprintf.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
 #include "Debug.h"
@@ -124,9 +125,6 @@
 
 }  // namespace
 
-// Use a smaller buffer so that there is less latency for dumping to stdout.
-constexpr size_t kStdOutBufferSize = 1024u;
-
 int DumpAPCCommand::Action(const std::vector<std::string>& args) {
   DumpContext context;
   DebugPrintTableOptions print_options;
@@ -134,41 +132,41 @@
   print_options.show_values = !no_values_;
 
   if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump container specified.");
+    diag_->Error(DiagMessage() << "No dump container specified");
     return 1;
   }
 
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  Printer printer(&fout);
-
+  bool error = false;
   for (auto container : args) {
     io::FileInputStream input(container);
     if (input.HadError()) {
       context.GetDiagnostics()->Error(DiagMessage(container)
-                                          << "failed to open file: " << input.GetError());
-      return false;
+                                      << "failed to open file: " << input.GetError());
+      error = true;
+      continue;
     }
 
     // Try as a compiled file.
     ContainerReader reader(&input);
     if (reader.HadError()) {
       context.GetDiagnostics()->Error(DiagMessage(container)
-                                           << "failed to read container: " << reader.GetError());
-      return false;
+                                      << "failed to read container: " << reader.GetError());
+      error = true;
+      continue;
     }
 
-    printer.Println("AAPT2 Container (APC)");
+    printer_->Println("AAPT2 Container (APC)");
     ContainerReaderEntry* entry;
     std::string error;
     while ((entry = reader.Next()) != nullptr) {
       if (entry->Type() == ContainerEntryType::kResTable) {
-        printer.Println("kResTable");
+        printer_->Println("kResTable");
 
         pb::ResourceTable pb_table;
         if (!entry->GetResTable(&pb_table)) {
           context.GetDiagnostics()->Error(DiagMessage(container)
-                                               << "failed to parse proto table: "
-                                               << entry->GetError());
+                                          << "failed to parse proto table: " << entry->GetError());
+          error = true;
           continue;
         }
 
@@ -176,69 +174,65 @@
         error.clear();
         if (!DeserializeTableFromPb(pb_table, nullptr /*files*/, &table, &error)) {
           context.GetDiagnostics()->Error(DiagMessage(container)
-                                               << "failed to parse table: " << error);
+                                          << "failed to parse table: " << error);
+          error = true;
           continue;
         }
 
-        printer.Indent();
-        Debug::PrintTable(table, print_options, &printer);
-        printer.Undent();
+        printer_->Indent();
+        Debug::PrintTable(table, print_options, printer_);
+        printer_->Undent();
       } else if (entry->Type() == ContainerEntryType::kResFile) {
-        printer.Println("kResFile");
+        printer_->Println("kResFile");
         pb::internal::CompiledFile pb_compiled_file;
         off64_t offset;
         size_t length;
         if (!entry->GetResFileOffsets(&pb_compiled_file, &offset, &length)) {
-          context.GetDiagnostics()->Error(
-              DiagMessage(container) << "failed to parse compiled proto file: "
-                                     << entry->GetError());
+          context.GetDiagnostics()->Error(DiagMessage(container)
+                                          << "failed to parse compiled proto file: "
+                                          << entry->GetError());
+          error = true;
           continue;
         }
 
         ResourceFile file;
         if (!DeserializeCompiledFileFromPb(pb_compiled_file, &file, &error)) {
           context.GetDiagnostics()->Warn(DiagMessage(container)
-                                              << "failed to parse compiled file: " << error);
+                                         << "failed to parse compiled file: " << error);
+          error = true;
           continue;
         }
 
-        printer.Indent();
-        DumpCompiledFile(file, Source(container), offset, length, &printer);
-        printer.Undent();
+        printer_->Indent();
+        DumpCompiledFile(file, Source(container), offset, length, printer_);
+        printer_->Undent();
       }
     }
   }
 
-  return 0;
+  return (error) ? 1 : 0;
 }
 
-int DumpConfigsCommand::Action(const std::vector<std::string>& args) {
-  if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump apk specified.");
-    return 1;
-  }
+int DumpBadgerCommand::Action(const std::vector<std::string>& args) {
+  printer_->Print(StringPrintf("%s", kBadgerData));
+  printer_->Print("Did you mean \"aapt2 dump badging\"?\n");
+  return 1;
+}
 
-  auto loaded_apk = LoadedApk::LoadApkFromPath(args[0], diag_);
-  if (!loaded_apk) {
-    return 1;
-  }
-
-  ResourceTable* table = loaded_apk->GetResourceTable();
+int DumpConfigsCommand::Dump(LoadedApk* apk) {
+  ResourceTable* table = apk->GetResourceTable();
   if (!table) {
-    diag_->Error(DiagMessage() << "Failed to retrieve resource table.");
+    GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
     return 1;
   }
 
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  Printer printer(&fout);
-
   // Comparison function used to order configurations
-  auto compare = [](ConfigDescription c1, ConfigDescription c2) -> bool {
-      return c1.compare(c2) < 0;
+  auto compare = [](android::ConfigDescription c1, android::ConfigDescription c2) -> bool {
+    return c1.compare(c2) < 0;
   };
 
   // Insert the configurations into a set in order to keep every configuarion seen
-  std::set<ConfigDescription, decltype(compare)> configs(compare);
+  std::set<android::ConfigDescription, decltype(compare)> configs(compare);
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
@@ -251,132 +245,93 @@
 
   // Print the configurations in order
   for (auto& config : configs) {
-    printer.Print(StringPrintf("%s\n", config.to_string().data()));
+    GetPrinter()->Print(StringPrintf("%s\n", config.to_string().data()));
   }
-
   return 0;
 }
 
-int DumpStringsCommand::Action(const std::vector<std::string>& args) {
-  DumpContext context;
-  if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump apk specified.");
+int DumpPackageNameCommand::Dump(LoadedApk* apk) {
+  Maybe<std::string> package_name = GetPackageName(apk);
+  if (!package_name) {
     return 1;
   }
 
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  Printer printer(&fout);
-
-  for (auto apk : args) {
-    auto loaded_apk = LoadedApk::LoadApkFromPath(apk, diag_);
-    if (!loaded_apk) {
-      return 1;
-    }
-
-    ResourceTable* table = loaded_apk->GetResourceTable();
-    if (!table) {
-      diag_->Error(DiagMessage() << "Failed to retrieve resource table.");
-      return 1;
-    }
-
-    // Load the run-time xml string pool using the flattened data
-    BigBuffer buffer(4096);
-    StringPool::FlattenUtf8(&buffer, table->string_pool, context.GetDiagnostics());
-    auto data = buffer.to_string();
-    android::ResStringPool pool(data.data(), data.size(), false);
-    Debug::DumpResStringPool(&pool, &printer);
-  }
-
+  GetPrinter()->Println(package_name.value());
   return 0;
 }
 
-int DumpTableCommand::Action(const std::vector<std::string>& args) {
-  if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump apk specified.");
+int DumpStringsCommand::Dump(LoadedApk* apk) {
+  ResourceTable* table = apk->GetResourceTable();
+  if (!table) {
+    GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
     return 1;
   }
 
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  Printer printer(&fout);
+  // Load the run-time xml string pool using the flattened data
+  BigBuffer buffer(4096);
+  StringPool::FlattenUtf8(&buffer, table->string_pool, GetDiagnostics());
+  auto data = buffer.to_string();
+  android::ResStringPool pool(data.data(), data.size(), false);
+  Debug::DumpResStringPool(&pool, GetPrinter());
+  return 0;
+}
+
+int DumpStyleParentCommand::Dump(LoadedApk* apk) {
+  Maybe<std::string> package_name = GetPackageName(apk);
+  if (!package_name) {
+    return 1;
+  }
+
+  const auto target_style = ResourceName(package_name.value(), ResourceType::kStyle, style_);
+  const auto table = apk->GetResourceTable();
+
+  if (!table) {
+    GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
+    return 1;
+  }
+
+  Maybe<ResourceTable::SearchResult> target = table->FindResource(target_style);
+  if (!target) {
+    GetDiagnostics()->Error(
+        DiagMessage() << "Target style \"" << target_style.entry << "\" does not exist");
+    return 1;
+  }
+
+  Debug::PrintStyleGraph(table, target_style);
+  return 0;
+}
+
+int DumpTableCommand::Dump(LoadedApk* apk) {
+  if (apk->GetApkFormat() == ApkFormat::kProto) {
+    GetPrinter()->Println("Proto APK");
+  } else {
+    GetPrinter()->Println("Binary APK");
+  }
+
+  ResourceTable* table = apk->GetResourceTable();
+  if (!table) {
+    GetDiagnostics()->Error(DiagMessage() << "Failed to retrieve resource table");
+    return 1;
+  }
 
   DebugPrintTableOptions print_options;
   print_options.show_sources = true;
   print_options.show_values = !no_values_;
-
-  for (auto apk : args) {
-    auto loaded_apk = LoadedApk::LoadApkFromPath(apk, diag_);
-    if (!loaded_apk) {
-      return 1;
-    }
-
-    if (loaded_apk->GetApkFormat() == ApkFormat::kProto) {
-      printer.Println("Proto APK");
-    } else {
-      printer.Println("Binary APK");
-    }
-
-    ResourceTable* table = loaded_apk->GetResourceTable();
-    if (!table) {
-      diag_->Error(DiagMessage() << "Failed to retrieve resource table.");
-      return 1;
-    }
-
-    Debug::PrintTable(*table, print_options, &printer);
-  }
-
+  Debug::PrintTable(*table, print_options, GetPrinter());
   return 0;
 }
 
-int DumpXmlTreeCommand::Action(const std::vector<std::string>& args) {
-  if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump apk specified");
-    return 1;
-  }
-
-  auto loaded_apk = LoadedApk::LoadApkFromPath(args[0], diag_);
-  if (!loaded_apk) {
-    return 1;
-  }
-
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  Printer printer(&fout);
-
-  // Dump the xml tree of every passed in file
-  for (auto file : files_) {
-    auto xml = loaded_apk->LoadXml(file, diag_);
-    if (!xml) {
-      return 1;
-    }
-
-    Debug::DumpXml(*xml, &printer);
-  }
-
-  return 0;
-}
-
-int DumpXmlStringsCommand::Action(const std::vector<std::string>& args) {
+int DumpXmlStringsCommand::Dump(LoadedApk* apk) {
   DumpContext context;
-  if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump apk specified.");
-    return 1;
-  }
-
-  auto loaded_apk = LoadedApk::LoadApkFromPath(args[0], diag_);
-  if (!loaded_apk) {
-    return 1;
-  }
-
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  Printer printer(&fout);
-
-  // Dump the xml strings of every passed in file
+  bool error = false;
   for (auto xml_file : files_) {
     android::ResXMLTree tree;
 
-    if (loaded_apk->GetApkFormat() == ApkFormat::kProto) {
-      auto xml = loaded_apk->LoadXml(xml_file, diag_);
+    if (apk->GetApkFormat() == ApkFormat::kProto) {
+      auto xml = apk->LoadXml(xml_file, GetDiagnostics());
       if (!xml) {
-        return 1;
+        error = true;
+        continue;
       }
 
       // Flatten the xml document to get a binary representation of the proto xml file
@@ -385,76 +340,208 @@
       options.keep_raw_values = true;
       XmlFlattener flattener(&buffer, options);
       if (!flattener.Consume(&context, xml.get())) {
-        return 1;
+        error = true;
+        continue;
       }
 
       // Load the run-time xml tree using the flattened data
       std::string data = buffer.to_string();
       tree.setTo(data.data(), data.size(), /** copyData */ true);
 
-    } else if (loaded_apk->GetApkFormat() == ApkFormat::kBinary) {
-      io::IFile* file = loaded_apk->GetFileCollection()->FindFile(xml_file);
+    } else if (apk->GetApkFormat() == ApkFormat::kBinary) {
+      io::IFile* file = apk->GetFileCollection()->FindFile(xml_file);
       if (!file) {
-        diag_->Error(DiagMessage(xml_file) << "file '" << xml_file << "' not found in APK");
-        return 1;
+        GetDiagnostics()->Error(DiagMessage(xml_file)
+                                << "File '" << xml_file << "' not found in APK");
+        error = true;
+        continue;
       }
 
       std::unique_ptr<io::IData> data = file->OpenAsData();
       if (!data) {
-        diag_->Error(DiagMessage() << "failed to open file");
-        return 1;
+        GetDiagnostics()->Error(DiagMessage() << "Failed to open " << xml_file);
+        error = true;
+        continue;
       }
 
       // Load the run-time xml tree from the file data
       tree.setTo(data->data(), data->size(), /** copyData */ true);
+    } else {
+      GetDiagnostics()->Error(DiagMessage(apk->GetSource()) << "Unknown APK format");
+      error = true;
+      continue;
     }
 
-    Debug::DumpResStringPool(&tree.getStrings(), &printer);
+    Debug::DumpResStringPool(&tree.getStrings(), GetPrinter());
   }
+  return (error) ? 1 : 0;
+}
 
+int DumpXmlTreeCommand::Dump(LoadedApk* apk) {
+  for (auto file : files_) {
+    auto xml = apk->LoadXml(file, GetDiagnostics());
+    if (!xml) {
+      return 1;
+    }
+    Debug::DumpXml(*xml, GetPrinter());
+  }
   return 0;
 }
 
-int DumpPackageNameCommand::Action(const std::vector<std::string>& args) {
-  if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump apk specified.");
-    return 1;
-  }
-
-  auto loaded_apk = LoadedApk::LoadApkFromPath(args[0], diag_);
-  if (!loaded_apk) {
-    return 1;
-  }
-
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  Printer printer(&fout);
-
-  xml::Element* manifest_el = loaded_apk->GetManifest()->root.get();
-  if (!manifest_el) {
-    diag_->Error(DiagMessage() << "No AndroidManifest.");
-    return 1;
-  }
-
-  xml::Attribute* attr = manifest_el->FindAttribute({}, "package");
-  if (!attr) {
-    diag_->Error(DiagMessage() << "No package name.");
-    return 1;
-  }
-  printer.Println(StringPrintf("%s", attr->value.c_str()));
-
-  return 0;
-}
-
-/** Preform no action because a subcommand is required. */
-int DumpCommand::Action(const std::vector<std::string>& args) {
-  if (args.size() == 0) {
-    diag_->Error(DiagMessage() << "no subcommand specified");
-  } else {
-    diag_->Error(DiagMessage() << "unknown subcommand '" << args[0] << "'");
-  }
-
-  Usage(&std::cerr);
-  return 1;
-}
+const char DumpBadgerCommand::kBadgerData[2925] = {
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  95,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  61,  63,  86,  35,  40,  46,  46,
+    95,  95,  95,  95,  97,  97,  44,  32,  46,  124, 42,  33,  83,  62,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  58,  46,  58,  59,  61,  59,  61,  81,  81,  81,  81,  66,  96,  61,  61,  58,  46,
+    46,  46,  58,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  46,  61,  59,  59,  59,  58,  106, 81,  81,
+    81,  81,  102, 59,  61,  59,  59,  61,  61,  61,  58,  46,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    61,  59,  59,  59,  58,  109, 81,  81,  81,  81,  61,  59,  59,  59,  59,  59,  58,  59,  59,
+    46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  46,  61,  59,  59,  59,  60,  81,  81,  81,  81,  87,  58,
+    59,  59,  59,  59,  59,  59,  61,  119, 44,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  46,  47,  61,  59,  59,
+    58,  100, 81,  81,  81,  81,  35,  58,  59,  59,  59,  59,  59,  58,  121, 81,  91,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  46,  109, 58,  59,  59,  61,  81,  81,  81,  81,  81,  109, 58,  59,  59,  59,
+    59,  61,  109, 81,  81,  76,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  41,  87,  59,  61,  59,  41,  81,  81,
+    81,  81,  81,  81,  59,  61,  59,  59,  58,  109, 81,  81,  87,  39,  46,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    60,  81,  91,  59,  59,  61,  81,  81,  81,  81,  81,  87,  43,  59,  58,  59,  60,  81,  81,
+    81,  76,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  52,  91,  58,  45,  59,  87,  81,  81,  81,  81,
+    70,  58,  58,  58,  59,  106, 81,  81,  81,  91,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  93,  40,
+    32,  46,  59,  100, 81,  81,  81,  81,  40,  58,  46,  46,  58,  100, 81,  81,  68,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  46,  46,  46,  32,  46,
+    46,  46,  32,  46,  32,  46,  45,  91,  59,  61,  58,  109, 81,  81,  81,  87,  46,  58,  61,
+    59,  60,  81,  81,  80,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  46,  46,
+    61,  59,  61,  61,  61,  59,  61,  61,  59,  59,  59,  58,  58,  46,  46,  41,  58,  59,  58,
+    81,  81,  81,  81,  69,  58,  59,  59,  60,  81,  81,  68,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,
+    32,  32,  32,  32,  58,  59,  61,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,
+    59,  59,  61,  61,  46,  61,  59,  93,  81,  81,  81,  81,  107, 58,  59,  58,  109, 87,  68,
+    96,  32,  32,  32,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  10,  32,  32,  32,  46,  60,  61,  61,  59,  59,  59,  59,  59,  59,
+    59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  58,  58,  58,  115, 109, 68,  41,  36,
+    81,  109, 46,  61,  61,  81,  69,  96,  46,  58,  58,  46,  58,  46,  46,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  46,  32,  95,  81,  67,
+    61,  61,  58,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,
+    59,  59,  58,  68,  39,  61,  105, 61,  63,  81,  119, 58,  106, 80,  32,  58,  61,  59,  59,
+    61,  59,  61,  59,  61,  46,  95,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  10,  32,  32,  36,  81,  109, 105, 59,  61,  59,  59,  59,  59,  59,  59,  59,  59,
+    59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  46,  58,  37,  73,  108, 108, 62,  52,  81,
+    109, 34,  32,  61,  59,  59,  59,  59,  59,  59,  59,  59,  59,  61,  59,  61,  61,  46,  46,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  46,  45,  57,  101, 43,  43,  61,
+    61,  59,  59,  59,  59,  59,  59,  61,  59,  59,  59,  59,  59,  59,  59,  59,  59,  58,  97,
+    46,  61,  108, 62,  126, 58,  106, 80,  96,  46,  61,  61,  59,  59,  59,  59,  59,  59,  59,
+    59,  59,  59,  59,  59,  59,  61,  61,  97,  103, 97,  32,  32,  32,  32,  32,  32,  32,  10,
+    32,  32,  32,  32,  45,  46,  32,  46,  32,  32,  32,  32,  32,  32,  32,  32,  45,  45,  45,
+    58,  59,  59,  59,  59,  61,  119, 81,  97,  124, 105, 124, 124, 39,  126, 95,  119, 58,  61,
+    58,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  61,  119, 81,  81,
+    99,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  58,  59,  59,  58,  106, 81,  81,  81,  109, 119,
+    119, 119, 109, 109, 81,  81,  122, 58,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,
+    59,  59,  59,  58,  115, 81,  87,  81,  102, 32,  32,  32,  32,  32,  32,  10,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  61,  58,
+    59,  61,  81,  81,  81,  81,  81,  81,  87,  87,  81,  81,  81,  81,  81,  58,  59,  59,  59,
+    59,  59,  59,  59,  59,  58,  45,  45,  45,  59,  59,  59,  41,  87,  66,  33,  32,  32,  32,
+    32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  58,  59,  59,  93,  81,  81,  81,  81,  81,  81,  81,  81,  81,
+    81,  81,  81,  81,  40,  58,  59,  59,  59,  58,  45,  32,  46,  32,  32,  32,  32,  32,  46,
+    32,  126, 96,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  58,  61,  59,  58,  81,
+    81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  40,  58,  59,  59,  59,  58,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  58,  59,  59,  58,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,
+    81,  40,  58,  59,  59,  59,  46,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  58,  61,  59,  60,  81,  81,  81,  81,
+    81,  81,  81,  81,  81,  81,  81,  81,  81,  59,  61,  59,  59,  61,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    58,  59,  59,  93,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  40,  59,
+    59,  59,  59,  32,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  58,  61,  58,  106, 81,  81,  81,  81,  81,  81,  81,
+    81,  81,  81,  81,  81,  81,  76,  58,  59,  59,  59,  32,  46,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  61,  58,  58,
+    81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  87,  58,  59,  59,  59,  59,
+    32,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  58,  59,  61,  41,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,
+    81,  81,  87,  59,  61,  58,  59,  59,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  58,  61,  58,  61,  81,  81,
+    81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  107, 58,  59,  59,  59,  59,  58,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  58,  59,  59,  58,  51,  81,  81,  81,  81,  81,  81,  81,  81,  81,  81,  102, 94,
+    59,  59,  59,  59,  59,  61,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  58,  61,  59,  59,  59,  43,  63,  36,  81,
+    81,  81,  87,  64,  86,  102, 58,  59,  59,  59,  59,  59,  59,  59,  46,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  46,  61,
+    59,  59,  59,  59,  59,  59,  59,  43,  33,  58,  126, 126, 58,  59,  59,  59,  59,  59,  59,
+    59,  59,  59,  59,  32,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  46,  61,  59,  59,  59,  58,  45,  58,  61,  59,  58,  58,  58,  61,
+    59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  59,  58,  32,  46,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  46,  61,  59,  59,  59,  59,  59,
+    58,  95,  32,  45,  61,  59,  61,  59,  59,  59,  59,  59,  59,  59,  45,  58,  59,  59,  59,
+    59,  61,  58,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  58,  61,  59,  59,  59,  59,  59,  61,  59,  61,  46,  46,  32,  45,  45,  45,  59,  58,
+    45,  45,  46,  58,  59,  59,  59,  59,  59,  59,  61,  46,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  46,  58,  59,  59,  59,  59,  59,  59,  59,  59,  59,
+    61,  59,  46,  32,  32,  46,  32,  46,  32,  58,  61,  59,  59,  59,  59,  59,  59,  59,  59,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  45,
+    59,  59,  59,  59,  59,  59,  59,  59,  58,  32,  32,  32,  32,  32,  32,  32,  32,  32,  61,
+    59,  59,  59,  59,  59,  59,  59,  58,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  46,  61,  59,  59,  59,  59,  59,  59,  59,  32,  46,  32,
+    32,  32,  32,  32,  32,  61,  46,  61,  59,  59,  59,  59,  59,  59,  58,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  61,  59,  59,  59,
+    59,  59,  59,  59,  59,  32,  46,  32,  32,  32,  32,  32,  32,  32,  46,  61,  58,  59,  59,
+    59,  59,  59,  58,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  58,  59,  59,  59,  59,  59,  59,  59,  59,  46,  46,  32,  32,  32,  32,
+    32,  32,  32,  61,  59,  59,  59,  59,  59,  59,  59,  45,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  46,  32,  45,  61,  59,  59,  59,  59,
+    59,  58,  32,  46,  32,  32,  32,  32,  32,  32,  32,  58,  59,  59,  59,  59,  59,  58,  45,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  45,  45,  45,  45,  32,  46,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  45,  61,  59,  58,  45,  45,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  10,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  46,  32,  32,  46,  32,  32,  32,  32,  32,  32,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  10};
 
 }  // namespace aapt
diff --git a/tools/aapt2/cmd/Dump.h b/tools/aapt2/cmd/Dump.h
index 9ec820d..89d19cf 100644
--- a/tools/aapt2/cmd/Dump.h
+++ b/tools/aapt2/cmd/Dump.h
@@ -19,14 +19,77 @@
 
 #include "Command.h"
 #include "Debug.h"
+#include "LoadedApk.h"
 #include "dump/DumpManifest.h"
 
 namespace aapt {
 
-/** Command the contents of files generated from the compilation stage. */
+/**
+ * The base command for dumping information about apks. When the command is executed, the command
+ * performs the DumpApkCommand::Dump() operation on each apk provided as a file argument.
+ **/
+class DumpApkCommand : public Command {
+ public:
+  explicit DumpApkCommand(const std::string&& name, text::Printer* printer, IDiagnostics* diag)
+      : Command(name), printer_(printer), diag_(diag) {
+  }
+
+  text::Printer* GetPrinter() {
+    return printer_;
+  }
+
+  IDiagnostics* GetDiagnostics() {
+    return diag_;
+  }
+
+  Maybe<std::string> GetPackageName(LoadedApk* apk) {
+    xml::Element* manifest_el = apk->GetManifest()->root.get();
+    if (!manifest_el) {
+      GetDiagnostics()->Error(DiagMessage() << "No AndroidManifest.");
+      return Maybe<std::string>();
+    }
+
+    xml::Attribute* attr = manifest_el->FindAttribute({}, "package");
+    if (!attr) {
+      GetDiagnostics()->Error(DiagMessage() << "No package name.");
+      return Maybe<std::string>();
+    }
+    return attr->value;
+  }
+
+  /** Perform the dump operation on the apk. */
+  virtual int Dump(LoadedApk* apk) = 0;
+
+  int Action(const std::vector<std::string>& args) final {
+    if (args.size() < 1) {
+      diag_->Error(DiagMessage() << "No dump apk specified.");
+      return 1;
+    }
+
+    bool error = false;
+    for (auto apk : args) {
+      auto loaded_apk = LoadedApk::LoadApkFromPath(apk, diag_);
+      if (!loaded_apk) {
+        error = true;
+        continue;
+      }
+
+      error |= Dump(loaded_apk.get());
+    }
+
+    return error;
+  }
+
+ private:
+  text::Printer* printer_;
+  IDiagnostics* diag_;
+};
+
+/** Command that prints contents of files generated from the compilation stage. */
 class DumpAPCCommand : public Command {
  public:
-  explicit DumpAPCCommand(IDiagnostics* diag) : Command("apc"), diag_(diag) {
+  explicit DumpAPCCommand(text::Printer* printer, IDiagnostics* diag)
+      : Command("apc"), printer_(printer), diag_(diag) {
     SetDescription("Print the contents of the AAPT2 Container (APC) generated fom compilation.");
     AddOptionalSwitch("--no-values", "Suppresses output of values when displaying resource tables.",
                       &no_values_);
@@ -36,120 +99,178 @@
   int Action(const std::vector<std::string>& args) override;
 
  private:
+  text::Printer* printer_;
   IDiagnostics* diag_;
-  bool verbose_ = false;
   bool no_values_ = false;
+  bool verbose_ = false;
 };
 
-/** Prints every configuration used by a resource in an APK. */
-class DumpConfigsCommand : public Command {
+/** Easter egg command shown when users enter "badger" instead of "badging". */
+class DumpBadgerCommand : public Command {
  public:
-  explicit DumpConfigsCommand(IDiagnostics* diag) : Command("configurations"), diag_(diag) {
-    SetDescription("Print every configuration used by a resource in the APK.");
+  explicit DumpBadgerCommand(text::Printer* printer) : Command("badger"), printer_(printer) {
   }
 
   int Action(const std::vector<std::string>& args) override;
 
  private:
-  IDiagnostics* diag_;
+  text::Printer* printer_;
+  const static char kBadgerData[2925];
 };
 
-/** Prints the contents of the resource table string pool in the APK. */
-class DumpStringsCommand : public Command {
-  public:
-    explicit DumpStringsCommand(IDiagnostics* diag) : Command("strings"), diag_(diag) {
-      SetDescription("Print the contents of the resource table string pool in the APK.");
-    }
-
-    int Action(const std::vector<std::string>& args) override;
-
-  private:
-    IDiagnostics* diag_;
-};
-
-/** Prints the contents of the resource table from the APK. */
-class DumpTableCommand : public Command {
+class DumpBadgingCommand : public DumpApkCommand {
  public:
-  explicit DumpTableCommand(IDiagnostics* diag) : Command("resources"), diag_(diag) {
+  explicit DumpBadgingCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("badging", printer, diag) {
+    SetDescription("Print information extracted from the manifest of the APK.");
+    AddOptionalSwitch("--include-meta-data", "Include meta-data information.",
+                      &options_.include_meta_data);
+  }
+
+  int Dump(LoadedApk* apk) override {
+    return DumpManifest(apk, options_, GetPrinter(), GetDiagnostics());
+  }
+
+ private:
+  DumpManifestOptions options_;
+};
+
+class DumpConfigsCommand : public DumpApkCommand {
+ public:
+  explicit DumpConfigsCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("configurations", printer, diag) {
+    SetDescription("Print every configuration used by a resource in the APK.");
+  }
+
+  int Dump(LoadedApk* apk) override;
+};
+
+class DumpPackageNameCommand : public DumpApkCommand {
+ public:
+  explicit DumpPackageNameCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("packagename", printer, diag) {
+    SetDescription("Print the package name of the APK.");
+  }
+
+  int Dump(LoadedApk* apk) override;
+};
+
+class DumpPermissionsCommand : public DumpApkCommand {
+ public:
+  explicit DumpPermissionsCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("permissions", printer, diag) {
+    SetDescription("Print the permissions extracted from the manifest of the APK.");
+  }
+
+  int Dump(LoadedApk* apk) override {
+    DumpManifestOptions options;
+    options.only_permissions = true;
+    return DumpManifest(apk, options, GetPrinter(), GetDiagnostics());
+  }
+};
+
+class DumpStringsCommand : public DumpApkCommand {
+ public:
+  explicit DumpStringsCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("strings", printer, diag) {
+    SetDescription("Print the contents of the resource table string pool in the APK.");
+  }
+
+  int Dump(LoadedApk* apk) override;
+};
+
+/** Prints the graph of parents of a style in an APK. */
+class DumpStyleParentCommand : public DumpApkCommand {
+ public:
+  explicit DumpStyleParentCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("styleparents", printer, diag) {
+    SetDescription("Print the parents of a style in an APK.");
+    AddRequiredFlag("--style", "The name of the style to print", &style_);
+  }
+
+  int Dump(LoadedApk* apk) override;
+
+ private:
+  std::string style_;
+};
+
+class DumpTableCommand : public DumpApkCommand {
+ public:
+  explicit DumpTableCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("resources", printer, diag) {
     SetDescription("Print the contents of the resource table from the APK.");
     AddOptionalSwitch("--no-values", "Suppresses output of values when displaying resource tables.",
                       &no_values_);
     AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
   }
 
-  int Action(const std::vector<std::string>& args) override;
+  int Dump(LoadedApk* apk) override;
 
  private:
-  IDiagnostics* diag_;
-  bool verbose_ = false;
   bool no_values_ = false;
+  bool verbose_ = false;
 };
 
-/** Prints the string pool of a compiled xml in an APK. */
-class DumpXmlStringsCommand : public Command {
-public:
-    explicit DumpXmlStringsCommand(IDiagnostics* diag) : Command("xmlstrings"), diag_(diag) {
-      SetDescription("Print the string pool of a compiled xml in an APK.");
-      AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
-    }
-
-    int Action(const std::vector<std::string>& args) override;
-
-private:
-    IDiagnostics* diag_;
-    std::vector<std::string> files_;
-};
-
-
-/** Prints the tree of a compiled xml in an APK. */
-class DumpXmlTreeCommand : public Command {
+class DumpXmlStringsCommand : public DumpApkCommand {
  public:
-  explicit DumpXmlTreeCommand(IDiagnostics* diag) : Command("xmltree"), diag_(diag) {
+  explicit DumpXmlStringsCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("xmlstrings", printer, diag) {
+    SetDescription("Print the string pool of a compiled xml in an APK.");
+    AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
+  }
+
+  int Dump(LoadedApk* apk) override;
+
+ private:
+  std::vector<std::string> files_;
+};
+
+class DumpXmlTreeCommand : public DumpApkCommand {
+ public:
+  explicit DumpXmlTreeCommand(text::Printer* printer, IDiagnostics* diag)
+      : DumpApkCommand("xmltree", printer, diag) {
     SetDescription("Print the tree of a compiled xml in an APK.");
     AddRequiredFlagList("--file", "A compiled xml file to print", &files_);
   }
 
-  int Action(const std::vector<std::string>& args) override;
+  int Dump(LoadedApk* apk) override;
 
  private:
-  IDiagnostics* diag_;
   std::vector<std::string> files_;
 };
 
-/** Prints the contents of the resource table from the APK. */
-class DumpPackageNameCommand : public Command {
- public:
-  explicit DumpPackageNameCommand(IDiagnostics* diag) : Command("packagename"), diag_(diag) {
-    SetDescription("Print the package name of the APK.");
-  }
-
-  int Action(const std::vector<std::string>& args) override;
-
- private:
-  IDiagnostics* diag_;
-};
-
 /** The default dump command. Performs no action because a subcommand is required. */
 class DumpCommand : public Command {
  public:
-  explicit DumpCommand(IDiagnostics* diag) : Command("dump", "d"), diag_(diag) {
-    AddOptionalSubcommand(util::make_unique<DumpAPCCommand>(diag_));
-    AddOptionalSubcommand(util::make_unique<DumpBadgingCommand>(diag_));
-    AddOptionalSubcommand(util::make_unique<DumpConfigsCommand>(diag_));
-    AddOptionalSubcommand(util::make_unique<DumpPackageNameCommand>(diag_));
-    AddOptionalSubcommand(util::make_unique<DumpPermissionsCommand>(diag_));
-    AddOptionalSubcommand(util::make_unique<DumpStringsCommand>(diag_));
-    AddOptionalSubcommand(util::make_unique<DumpTableCommand>(diag_));
-    AddOptionalSubcommand(util::make_unique<DumpXmlStringsCommand>(diag_));
-    AddOptionalSubcommand(util::make_unique<DumpXmlTreeCommand>(diag_));
+  explicit DumpCommand(text::Printer* printer, IDiagnostics* diag)
+      : Command("dump", "d"), diag_(diag) {
+    AddOptionalSubcommand(util::make_unique<DumpAPCCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpBadgingCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpConfigsCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpPackageNameCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpPermissionsCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpStringsCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpStyleParentCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpTableCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpXmlStringsCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpXmlTreeCommand>(printer, diag_));
+    AddOptionalSubcommand(util::make_unique<DumpBadgerCommand>(printer), /* hidden */ true);
   }
 
-  int Action(const std::vector<std::string>& args) override;
+  int Action(const std::vector<std::string>& args) override {
+    if (args.size() == 0) {
+      diag_->Error(DiagMessage() << "no subcommand specified");
+    } else {
+      diag_->Error(DiagMessage() << "unknown subcommand '" << args[0] << "'");
+    }
+    Usage(&std::cerr);
+    return 1;
+  }
 
  private:
   IDiagnostics* diag_;
 };
 
-}// namespace aapt
+}  // namespace aapt
 
-#endif //AAPT2_DUMP_H
+#endif  // AAPT2_DUMP_H
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 13c1047..6a7da0c 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -27,12 +27,12 @@
 #include "android-base/errors.h"
 #include "android-base/file.h"
 #include "android-base/stringprintf.h"
+#include "androidfw/Locale.h"
 #include "androidfw/StringPiece.h"
 
 #include "AppInfo.h"
 #include "Debug.h"
 #include "LoadedApk.h"
-#include "Locale.h"
 #include "NameMangler.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
@@ -70,6 +70,7 @@
 #include "xml/XmlDom.h"
 
 using ::aapt::io::FileInputStream;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::base::StringPrintf;
 
@@ -1260,7 +1261,7 @@
       return false;
     }
 
-    proguard::WriteKeepSet(keep_set, &fout);
+    proguard::WriteKeepSet(keep_set, &fout, options_.generate_minimal_proguard_rules);
     fout.Flush();
 
     if (fout.HadError()) {
@@ -1775,10 +1776,12 @@
 
     // Before we process anything, remove the resources whose default values don't exist.
     // We want to force any references to these to fail the build.
-    if (!NoDefaultResourceRemover{}.Consume(context_, &final_table_)) {
-      context_->GetDiagnostics()->Error(DiagMessage()
-                                        << "failed removing resources with no defaults");
-      return 1;
+    if (!options_.no_resource_removal) {
+      if (!NoDefaultResourceRemover{}.Consume(context_, &final_table_)) {
+        context_->GetDiagnostics()->Error(DiagMessage()
+                                          << "failed removing resources with no defaults");
+        return 1;
+      }
     }
 
     ReferenceLinker linker;
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index e58a93e..950dac2 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -49,6 +49,7 @@
   Maybe<std::string> generate_proguard_rules_path;
   Maybe<std::string> generate_main_dex_proguard_rules_path;
   bool generate_conditional_proguard_rules = false;
+  bool generate_minimal_proguard_rules = false;
   bool generate_non_final_ids = false;
   std::vector<std::string> javadoc_annotations;
   Maybe<std::string> private_symbols;
@@ -58,6 +59,7 @@
   bool no_version_vectors = false;
   bool no_version_transitions = false;
   bool no_resource_deduping = false;
+  bool no_resource_removal = false;
   bool no_xml_namespaces = false;
   bool do_not_compress_anything = false;
   std::unordered_set<std::string> extensions_to_not_compress;
@@ -119,6 +121,9 @@
     AddOptionalSwitch("--proguard-conditional-keep-rules",
         "Generate conditional Proguard keep rules.",
         &options_.generate_conditional_proguard_rules);
+    AddOptionalSwitch("--proguard-minimal-keep-rules",
+        "Generate a minimal set of Proguard keep rules.",
+        &options_.generate_minimal_proguard_rules);
     AddOptionalSwitch("--no-auto-version", "Disables automatic style and layout SDK versioning.",
         &options_.no_auto_version);
     AddOptionalSwitch("--no-version-vectors",
@@ -132,6 +137,9 @@
     AddOptionalSwitch("--no-resource-deduping", "Disables automatic deduping of resources with\n"
             "identical values across compatible configurations.",
         &options_.no_resource_deduping);
+    AddOptionalSwitch("--no-resource-removal", "Disables automatic removal of resources without\n"
+            "defaults. Use this only when building runtime resource overlay packages.",
+        &options_.no_resource_removal);
     AddOptionalSwitch("--enable-sparse-encoding",
         "This decreases APK size at the cost of resource retrieval performance.",
         &options_.table_flattener_options.use_sparse_entries);
@@ -276,4 +284,4 @@
 
 }// namespace aapt
 
-#endif //AAPT2_LINK_H
\ No newline at end of file
+#endif //AAPT2_LINK_H
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index 47288ec..328b0be 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -22,6 +22,7 @@
 #include "android-base/file.h"
 #include "android-base/stringprintf.h"
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 #include "androidfw/StringPiece.h"
 
@@ -47,6 +48,7 @@
 
 using ::aapt::configuration::Abi;
 using ::aapt::configuration::OutputArtifact;
+using ::android::ConfigDescription;
 using ::android::ResTable_config;
 using ::android::StringPiece;
 using ::android::base::ReadFileToString;
diff --git a/tools/aapt2/cmd/Util.cpp b/tools/aapt2/cmd/Util.cpp
index 5862d31..792120e 100644
--- a/tools/aapt2/cmd/Util.cpp
+++ b/tools/aapt2/cmd/Util.cpp
@@ -19,15 +19,17 @@
 #include <vector>
 
 #include "android-base/logging.h"
+#include "androidfw/ConfigDescription.h"
+#include "androidfw/Locale.h"
 
-#include "ConfigDescription.h"
-#include "Locale.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
 #include "split/TableSplitter.h"
 #include "util/Maybe.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
+using ::android::LocaleValue;
 using ::android::StringPiece;
 using ::android::base::StringPrintf;
 
diff --git a/tools/aapt2/cmd/Util_test.cpp b/tools/aapt2/cmd/Util_test.cpp
index 158ef29..f92f1e3 100644
--- a/tools/aapt2/cmd/Util_test.cpp
+++ b/tools/aapt2/cmd/Util_test.cpp
@@ -16,12 +16,24 @@
 
 #include "Util.h"
 
+#include "android-base/stringprintf.h"
+
 #include "AppInfo.h"
 #include "split/TableSplitter.h"
 #include "test/Builders.h"
 #include "test/Test.h"
+#include "util/Files.h"
+
+using ::android::ConfigDescription;
 
 namespace aapt {
+
+#ifdef _WIN32
+#define CREATE_PATH(path) android::base::StringPrintf(";%s", path)
+#else
+#define CREATE_PATH(path) android::base::StringPrintf(":%s", path)
+#endif
+
 #define EXPECT_CONFIG_EQ(constraints, config) \
     EXPECT_EQ(constraints.configs.size(), 1); \
     EXPECT_EQ(*constraints.configs.begin(), config); \
@@ -89,7 +101,7 @@
 }
 
 
-TEST (UtilTest, ParseSplitParameter) {
+TEST (UtilTest, ParseSplitParameters) {
   IDiagnostics* diagnostics = test::ContextBuilder().Build().get()->GetDiagnostics();
   std::string path;
   SplitConstraints constraints;
@@ -98,14 +110,14 @@
   // ========== Test IMSI ==========
   // mcc: 'mcc[0-9]{3}'
   // mnc: 'mnc[0-9]{1,3}'
-  ASSERT_TRUE(ParseSplitParameter(":mcc310",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setMcc(0x0136)
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":mcc310-mnc004",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc004"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setMcc(0x0136)
@@ -113,7 +125,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":mcc310-mnc000",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("mcc310-mnc000"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setMcc(0x0136)
@@ -124,14 +136,14 @@
   // ========== Test LOCALE ==========
   // locale: '[a-z]{2,3}(-r[a-z]{2})?'
   // locale: 'b+[a-z]{2,3}(+[a-z[0-9]]{2})?'
-  ASSERT_TRUE(ParseSplitParameter(":es",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("es"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setLanguage(0x6573)
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":fr-rCA",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("fr-rCA"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setLanguage(0x6672)
@@ -139,7 +151,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":b+es+419",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("b+es+419"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setLanguage(0x6573)
@@ -151,21 +163,21 @@
   // orientation: '(port|land|square)'
   // touchscreen: '(notouch|stylus|finger)'
   // density" '(anydpi|nodpi|ldpi|mdpi|tvdpi|hdpi|xhdpi|xxhdpi|xxxhdpi|[0-9]*dpi)'
-  ASSERT_TRUE(ParseSplitParameter(":square",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("square"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setOrientation(0x03)
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":stylus",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("stylus"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setTouchscreen(0x02)
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":xxxhdpi",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xxxhdpi"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setDensity(0x0280)
@@ -173,7 +185,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":land-xhdpi-finger",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("land-xhdpi-finger"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setOrientation(0x02)
@@ -188,28 +200,28 @@
   // navigation: '(nonav|dpad|trackball|wheel)'
   // inputFlags: '(keysexposed|keyshidden|keyssoft)'
   // inputFlags: '(navexposed|navhidden)'
-  ASSERT_TRUE(ParseSplitParameter(":qwerty",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("qwerty"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setKeyboard(0x02)
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":dpad",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("dpad"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setNavigation(0x02)
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":keyssoft-navhidden",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyssoft-navhidden"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setInputFlags(0x0B)
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":keyshidden-nokeys-navexposed-trackball",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("keyshidden-nokeys-navexposed-trackball"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setKeyboard(0x01)
@@ -220,7 +232,7 @@
 
   // ========== Test SCREEN_SIZE ==========
   // screenWidth/screenHeight: '[0-9]+x[0-9]+'
-  ASSERT_TRUE(ParseSplitParameter(":1920x1080",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("1920x1080"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setScreenWidth(0x0780)
@@ -238,14 +250,14 @@
   // uiMode [type]: '(desk|car|television|appliance|watch|vrheadset)'
   // uiMode [night]: '(night|notnight)'
   // smallestScreenWidthDp: 'sw[0-9]dp'
-  ASSERT_TRUE(ParseSplitParameter(":ldrtl",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldrtl"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setScreenLayout(0x80)
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":small",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("small"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setScreenLayout(0x01)
@@ -253,7 +265,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":notlong",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("notlong"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setScreenLayout(0x10)
@@ -261,15 +273,15 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":ldltr-normal-long",
-                                  diagnostics, &path, &constraints));
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("ldltr-normal-long"),
+                                      diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setScreenLayout(0x62)
       .setSdkVersion(0x0004) // screenLayout (size|long) requires donut
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":car",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("car"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setUiMode(0x03)
@@ -277,7 +289,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":vrheadset",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("vrheadset"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setUiMode(0x07)
@@ -285,7 +297,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":television-night",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("television-night"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setUiMode(0x24)
@@ -293,7 +305,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":sw1920dp",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("sw1920dp"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setSmallestScreenWidthDp(0x0780)
@@ -304,7 +316,7 @@
   // ========== Test SCREEN_SIZE_DP ==========
   // screenWidthDp: 'w[0-9]dp'
   // screenHeightDp: 'h[0-9]dp'
-  ASSERT_TRUE(ParseSplitParameter(":w1920dp",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("w1920dp"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setScreenWidthDp(0x0780)
@@ -312,7 +324,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":h1080dp",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("h1080dp"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setScreenHeightDp(0x0438)
@@ -324,7 +336,7 @@
   // screenLayout2: '(round|notround)'
   // colorMode: '(widecg|nowidecg)'
   // colorMode: '(highhdr|lowdr)'
-  ASSERT_TRUE(ParseSplitParameter(":round",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("round"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setScreenLayout2(0x02)
@@ -332,7 +344,7 @@
       .Build();
   EXPECT_CONFIG_EQ(constraints, expected_configuration);
 
-  ASSERT_TRUE(ParseSplitParameter(":widecg-highdr",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("widecg-highdr"),
                                   diagnostics, &path, &constraints));
   expected_configuration = test::ConfigDescriptionBuilder()
       .setColorMode(0x0A)
@@ -349,10 +361,10 @@
   std::string path;
 
   test_constraints.push_back({});
-  ASSERT_TRUE(ParseSplitParameter(":v7",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("v7"),
                                   diagnostics, &path, &test_constraints.back()));
   test_constraints.push_back({});
-  ASSERT_TRUE(ParseSplitParameter(":xhdpi",
+  ASSERT_TRUE(ParseSplitParameter(CREATE_PATH("xhdpi"),
                                   diagnostics, &path, &test_constraints.back()));
   EXPECT_EQ(test_constraints.size(), 2);
   EXPECT_EQ(test_constraints[0].name, "v7");
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index 36c24bc..c5de9e0 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -24,6 +24,7 @@
 #include "compile/Pseudolocalizer.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::StringPiece16;
 
diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
index 711558a..3135802 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
@@ -19,6 +19,8 @@
 #include "test/Test.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 TEST(PseudolocaleGeneratorTest, PseudolocalizeStyledString) {
diff --git a/tools/aapt2/configuration/ConfigurationParser.cpp b/tools/aapt2/configuration/ConfigurationParser.cpp
index 902334b..dd06b38 100644
--- a/tools/aapt2/configuration/ConfigurationParser.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser.cpp
@@ -25,8 +25,8 @@
 
 #include "android-base/file.h"
 #include "android-base/logging.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
 #include "Diagnostics.h"
 #include "ResourceUtils.h"
 #include "configuration/ConfigurationParser.internal.h"
@@ -40,6 +40,8 @@
 #include "xml/XmlDom.h"
 #include "xml/XmlUtil.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 namespace {
diff --git a/tools/aapt2/configuration/ConfigurationParser.h b/tools/aapt2/configuration/ConfigurationParser.h
index 7f1d445..b9e3be9 100644
--- a/tools/aapt2/configuration/ConfigurationParser.h
+++ b/tools/aapt2/configuration/ConfigurationParser.h
@@ -22,7 +22,8 @@
 #include <unordered_map>
 #include <vector>
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
+
 #include "Diagnostics.h"
 #include "util/Maybe.h"
 
@@ -109,8 +110,8 @@
   std::string name;
   int version;
   std::vector<Abi> abis;
-  std::vector<ConfigDescription> screen_densities;
-  std::vector<ConfigDescription> locales;
+  std::vector<android::ConfigDescription> screen_densities;
+  std::vector<android::ConfigDescription> locales;
   Maybe<AndroidSdk> android_sdk;
   std::vector<DeviceFeature> features;
   std::vector<GlTexture> textures;
diff --git a/tools/aapt2/configuration/ConfigurationParser.internal.h b/tools/aapt2/configuration/ConfigurationParser.internal.h
index f071a69..c541688 100644
--- a/tools/aapt2/configuration/ConfigurationParser.internal.h
+++ b/tools/aapt2/configuration/ConfigurationParser.internal.h
@@ -17,6 +17,8 @@
 #ifndef AAPT2_CONFIGURATIONPARSER_INTERNAL_H
 #define AAPT2_CONFIGURATIONPARSER_INTERNAL_H
 
+#include "androidfw/ConfigDescription.h"
+
 #include "configuration/ConfigurationParser.h"
 
 #include <algorithm>
@@ -148,8 +150,8 @@
   Maybe<std::string> artifact_format;
 
   Group<Abi> abi_groups;
-  Group<ConfigDescription> screen_density_groups;
-  Group<ConfigDescription> locale_groups;
+  Group<android::ConfigDescription> screen_density_groups;
+  Group<android::ConfigDescription> locale_groups;
   Group<DeviceFeature> device_feature_groups;
   Group<GlTexture> gl_texture_groups;
   Entry<AndroidSdk> android_sdks;
diff --git a/tools/aapt2/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp
index ccaea4e..3a71e83 100644
--- a/tools/aapt2/configuration/ConfigurationParser_test.cpp
+++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp
@@ -26,6 +26,8 @@
 #include "test/Test.h"
 #include "xml/XmlDom.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 namespace configuration {
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index 2c356d1..11a4074 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -16,6 +16,8 @@
 
 #include "DumpManifest.h"
 
+#include <algorithm>
+
 #include "LoadedApk.h"
 #include "SdkConstants.h"
 #include "ValueVisitor.h"
@@ -24,7 +26,10 @@
 #include "process/IResourceTableConsumer.h"
 #include "xml/XmlDom.h"
 
+#include "androidfw/ConfigDescription.h"
+
 using ::android::base::StringPrintf;
+using ::android::ConfigDescription;
 
 namespace aapt {
 
@@ -70,10 +75,14 @@
   CATEGORY_ATTR = 0x010103e8,
   BANNER_ATTR = 0x10103f2,
   ISGAME_ATTR = 0x10103f4,
+  VERSION_ATTR = 0x01010519,
+  CERT_DIGEST_ATTR = 0x01010548,
   REQUIRED_FEATURE_ATTR = 0x1010557,
   REQUIRED_NOT_FEATURE_ATTR = 0x1010558,
   COMPILE_SDK_VERSION_ATTR = 0x01010572,
   COMPILE_SDK_VERSION_CODENAME_ATTR = 0x01010573,
+  VERSION_MAJOR_ATTR = 0x01010577,
+  PACKAGE_TYPE_ATTR = 0x01010587,
 };
 
 const std::string& kAndroidNamespace = "http://schemas.android.com/apk/res/android";
@@ -100,15 +109,8 @@
 
 class ManifestExtractor {
  public:
-  struct Options {
-    /** Include meta information from <meta-data> elements in the output. */
-    bool include_meta_data = false;
 
-    /** Only output permission information. */
-    bool only_permissions = false;
-  };
-
-  explicit ManifestExtractor(LoadedApk* apk, ManifestExtractor::Options options)
+  explicit ManifestExtractor(LoadedApk* apk, DumpManifestOptions& options)
       : apk_(apk), options_(options) { }
 
   class Element {
@@ -119,7 +121,7 @@
     static std::unique_ptr<Element> Inflate(ManifestExtractor* extractor, xml::Element* el);
 
     /** Writes out the extracted contents of the element. */
-    virtual void Print(text::Printer& printer) { }
+    virtual void Print(text::Printer* printer) { }
 
     /** Adds an element to the list of children of the element. */
     void AddChild(std::unique_ptr<Element>& child) { children_.push_back(std::move(child)); }
@@ -323,7 +325,7 @@
     return config;
   }
 
-  bool Dump(text::Printer& printer, IDiagnostics* diag);
+  bool Dump(text::Printer* printer, IDiagnostics* diag);
 
   /** Recursively visit the xml element tree and return a processed badging element tree. */
   std::unique_ptr<Element> Visit(xml::Element* element);
@@ -369,7 +371,7 @@
   }
 
   LoadedApk* const apk_;
-  const Options options_;
+  DumpManifestOptions& options_;
 
  private:
   std::unique_ptr<CommonFeatureGroup> commonFeatureGroup_ = util::make_unique<CommonFeatureGroup>();
@@ -441,40 +443,40 @@
     installLocation = GetAttributeInteger(FindAttribute(manifest, INSTALL_LOCATION_ATTR));
   }
 
-  void Print(text::Printer& printer) override {
-    printer.Print(StringPrintf("package: name='%s' ", package.data()));
-    printer.Print(StringPrintf("versionCode='%s' ",
+  void Print(text::Printer* printer) override {
+    printer->Print(StringPrintf("package: name='%s' ", package.data()));
+    printer->Print(StringPrintf("versionCode='%s' ",
                                (versionCode > 0) ? std::to_string(versionCode).data() : ""));
-    printer.Print(StringPrintf("versionName='%s'", versionName.data()));
+    printer->Print(StringPrintf("versionName='%s'", versionName.data()));
 
     if (split) {
-      printer.Print(StringPrintf(" split='%s'", split->data()));
+      printer->Print(StringPrintf(" split='%s'", split->data()));
     }
     if (platformVersionName) {
-      printer.Print(StringPrintf(" platformBuildVersionName='%s'", platformVersionName->data()));
+      printer->Print(StringPrintf(" platformBuildVersionName='%s'", platformVersionName->data()));
     }
     if (platformVersionCode) {
-      printer.Print(StringPrintf(" platformBuildVersionCode='%s'", platformVersionCode->data()));
+      printer->Print(StringPrintf(" platformBuildVersionCode='%s'", platformVersionCode->data()));
     }
     if (compilesdkVersion) {
-      printer.Print(StringPrintf(" compileSdkVersion='%d'", *compilesdkVersion));
+      printer->Print(StringPrintf(" compileSdkVersion='%d'", *compilesdkVersion));
     }
     if (compilesdkVersionCodename) {
-      printer.Print(StringPrintf(" compileSdkVersionCodename='%s'",
+      printer->Print(StringPrintf(" compileSdkVersionCodename='%s'",
                                  compilesdkVersionCodename->data()));
     }
-    printer.Print("\n");
+    printer->Print("\n");
 
     if (installLocation) {
       switch (*installLocation) {
         case 0:
-          printer.Print("install-location:'auto'\n");
+          printer->Print("install-location:'auto'\n");
           break;
         case 1:
-          printer.Print("install-location:'internalOnly'\n");
+          printer->Print("install-location:'internalOnly'\n");
           break;
         case 2:
-          printer.Print("install-location:'preferExternal'\n");
+          printer->Print("install-location:'preferExternal'\n");
           break;
         default:
           break;
@@ -535,15 +537,15 @@
     }
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     // Print the labels for every locale
     for (auto p : locale_labels) {
       if (p.first.empty()) {
-        printer.Print(StringPrintf("application-label:'%s'\n",
+        printer->Print(StringPrintf("application-label:'%s'\n",
                                     android::ResTable::normalizeForOutput(p.second.data())
                                         .c_str()));
       } else {
-        printer.Print(StringPrintf("application-label-%s:'%s'\n", p.first.data(),
+        printer->Print(StringPrintf("application-label-%s:'%s'\n", p.first.data(),
                                     android::ResTable::normalizeForOutput(p.second.data())
                                         .c_str()));
       }
@@ -551,26 +553,26 @@
 
     // Print the icon paths for every density
     for (auto p : density_icons) {
-      printer.Print(StringPrintf("application-icon-%d:'%s'\n", p.first, p.second.data()));
+      printer->Print(StringPrintf("application-icon-%d:'%s'\n", p.first, p.second.data()));
     }
 
     // Print the application info
-    printer.Print(StringPrintf("application: label='%s' ",
+    printer->Print(StringPrintf("application: label='%s' ",
                                 android::ResTable::normalizeForOutput(label.data()).c_str()));
-    printer.Print(StringPrintf("icon='%s'", icon.data()));
+    printer->Print(StringPrintf("icon='%s'", icon.data()));
     if (!banner.empty()) {
-      printer.Print(StringPrintf(" banner='%s'", banner.data()));
+      printer->Print(StringPrintf(" banner='%s'", banner.data()));
     }
-    printer.Print("\n");
+    printer->Print("\n");
 
     if (test_only != 0) {
-      printer.Print(StringPrintf("testOnly='%d'\n", test_only));
+      printer->Print(StringPrintf("testOnly='%d'\n", test_only));
     }
     if (is_game != 0) {
-      printer.Print("application-isGame\n");
+      printer->Print("application-isGame\n");
     }
     if (debuggable != 0) {
-      printer.Print("application-debuggable\n");
+      printer->Print("application-debuggable\n");
     }
   }
 };
@@ -605,19 +607,19 @@
     }
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (min_sdk) {
-      printer.Print(StringPrintf("sdkVersion:'%d'\n", *min_sdk));
+      printer->Print(StringPrintf("sdkVersion:'%d'\n", *min_sdk));
     } else if (min_sdk_name) {
-      printer.Print(StringPrintf("sdkVersion:'%s'\n", min_sdk_name->data()));
+      printer->Print(StringPrintf("sdkVersion:'%s'\n", min_sdk_name->data()));
     }
     if (max_sdk) {
-      printer.Print(StringPrintf("maxSdkVersion:'%d'\n", *max_sdk));
+      printer->Print(StringPrintf("maxSdkVersion:'%d'\n", *max_sdk));
     }
     if (target_sdk) {
-      printer.Print(StringPrintf("targetSdkVersion:'%d'\n", *target_sdk));
+      printer->Print(StringPrintf("targetSdkVersion:'%d'\n", *target_sdk));
     } else if (target_sdk_name) {
-      printer.Print(StringPrintf("targetSdkVersion:'%s'\n", target_sdk_name->data()));
+      printer->Print(StringPrintf("targetSdkVersion:'%s'\n", target_sdk_name->data()));
     }
   }
 };
@@ -645,24 +647,24 @@
         FindAttribute(element, REQ_FIVE_WAY_NAV_ATTR), 0);
   }
 
-  void Print(text::Printer& printer) override {
-    printer.Print("uses-configuration:");
+  void Print(text::Printer* printer) override {
+    printer->Print("uses-configuration:");
     if (req_touch_screen != 0) {
-      printer.Print(StringPrintf(" reqTouchScreen='%d'", req_touch_screen));
+      printer->Print(StringPrintf(" reqTouchScreen='%d'", req_touch_screen));
     }
     if (req_keyboard_type != 0) {
-      printer.Print(StringPrintf(" reqKeyboardType='%d'", req_keyboard_type));
+      printer->Print(StringPrintf(" reqKeyboardType='%d'", req_keyboard_type));
     }
     if (req_hard_keyboard != 0) {
-      printer.Print(StringPrintf(" reqHardKeyboard='%d'", req_hard_keyboard));
+      printer->Print(StringPrintf(" reqHardKeyboard='%d'", req_hard_keyboard));
     }
     if (req_navigation != 0) {
-      printer.Print(StringPrintf(" reqNavigation='%d'", req_navigation));
+      printer->Print(StringPrintf(" reqNavigation='%d'", req_navigation));
     }
     if (req_five_way_nav != 0) {
-      printer.Print(StringPrintf(" reqFiveWayNav='%d'", req_five_way_nav));
+      printer->Print(StringPrintf(" reqFiveWayNav='%d'", req_five_way_nav));
     }
-    printer.Print("\n");
+    printer->Print("\n");
   }
 };
 
@@ -706,7 +708,7 @@
     }
   }
 
-  void PrintScreens(text::Printer& printer, int32_t target_sdk) {
+  void PrintScreens(text::Printer* printer, int32_t target_sdk) {
     int32_t small_screen_temp = small_screen;
     int32_t normal_screen_temp  = normal_screen;
     int32_t large_screen_temp  = large_screen;
@@ -736,30 +738,30 @@
     }
 
     // Print the formatted screen info
-    printer.Print("supports-screens:");
+    printer->Print("supports-screens:");
     if (small_screen_temp  != 0) {
-      printer.Print(" 'small'");
+      printer->Print(" 'small'");
     }
     if (normal_screen_temp  != 0) {
-      printer.Print(" 'normal'");
+      printer->Print(" 'normal'");
     }
     if (large_screen_temp   != 0) {
-      printer.Print(" 'large'");
+      printer->Print(" 'large'");
     }
     if (xlarge_screen_temp  != 0) {
-      printer.Print(" 'xlarge'");
+      printer->Print(" 'xlarge'");
     }
-    printer.Print("\n");
-    printer.Print(StringPrintf("supports-any-density: '%s'\n",
+    printer->Print("\n");
+    printer->Print(StringPrintf("supports-any-density: '%s'\n",
                                 (any_density_temp ) ? "true" : "false"));
     if (requires_smallest_width_dp > 0) {
-      printer.Print(StringPrintf("requires-smallest-width:'%d'\n", requires_smallest_width_dp));
+      printer->Print(StringPrintf("requires-smallest-width:'%d'\n", requires_smallest_width_dp));
     }
     if (compatible_width_limit_dp > 0) {
-      printer.Print(StringPrintf("compatible-width-limit:'%d'\n", compatible_width_limit_dp));
+      printer->Print(StringPrintf("compatible-width-limit:'%d'\n", compatible_width_limit_dp));
     }
     if (largest_width_limit_dp > 0) {
-      printer.Print(StringPrintf("largest-width-limit:'%d'\n", largest_width_limit_dp));
+      printer->Print(StringPrintf("largest-width-limit:'%d'\n", largest_width_limit_dp));
     }
   }
 };
@@ -775,20 +777,20 @@
     label = GetAttributeStringDefault(FindAttribute(element, LABEL_ATTR), "");
   }
 
-  virtual void PrintGroup(text::Printer& printer) {
-    printer.Print(StringPrintf("feature-group: label='%s'\n", label.data()));
+  virtual void PrintGroup(text::Printer* printer) {
+    printer->Print(StringPrintf("feature-group: label='%s'\n", label.data()));
     if (open_gles_version > 0) {
-      printer.Print(StringPrintf("  uses-gl-es: '0x%x'\n", open_gles_version));
+      printer->Print(StringPrintf("  uses-gl-es: '0x%x'\n", open_gles_version));
     }
 
     for (auto feature : features_) {
-      printer.Print(StringPrintf("  uses-feature%s: name='%s'",
+      printer->Print(StringPrintf("  uses-feature%s: name='%s'",
                                  (feature.second.required ? "" : "-not-required"),
                                  feature.first.data()));
       if (feature.second.version > 0) {
-        printer.Print(StringPrintf(" version='%d'", feature.second.version));
+        printer->Print(StringPrintf(" version='%d'", feature.second.version));
       }
-      printer.Print("\n");
+      printer->Print("\n");
     }
   }
 
@@ -854,29 +856,29 @@
 class CommonFeatureGroup : public FeatureGroup {
  public:
   CommonFeatureGroup() = default;
-  void PrintGroup(text::Printer& printer) override {
+  void PrintGroup(text::Printer* printer) override {
     FeatureGroup::PrintGroup(printer);
 
     // Also print the implied features
     for (auto feature : implied_features_) {
       if (features_.find(feature.first) == features_.end()) {
         const char* sdk23 = feature.second.implied_from_sdk_k23 ? "-sdk-23" : "";
-        printer.Print(StringPrintf("  uses-feature%s: name='%s'\n", sdk23, feature.first.data()));
-        printer.Print(StringPrintf("  uses-implied-feature%s: name='%s' reason='", sdk23,
+        printer->Print(StringPrintf("  uses-feature%s: name='%s'\n", sdk23, feature.first.data()));
+        printer->Print(StringPrintf("  uses-implied-feature%s: name='%s' reason='", sdk23,
                                     feature.first.data()));
 
         // Print the reasons as a sentence
         size_t count = 0;
         for (auto reason : feature.second.reasons) {
-          printer.Print(reason);
+          printer->Print(reason);
           if (count + 2 < feature.second.reasons.size()) {
-            printer.Print(", ");
+            printer->Print(", ");
           } else if (count + 1 < feature.second.reasons.size()) {
-            printer.Print(", and ");
+            printer->Print(", and ");
           }
           count++;
         }
-        printer.Print("'\n");
+        printer->Print("'\n");
       }
     }
   }
@@ -1061,35 +1063,35 @@
     }
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (!name.empty()) {
-      printer.Print(StringPrintf("uses-permission: name='%s'", name.data()));
+      printer->Print(StringPrintf("uses-permission: name='%s'", name.data()));
       if (maxSdkVersion >= 0) {
-        printer.Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion));
+        printer->Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion));
       }
       if (!requiredFeature.empty()) {
-        printer.Print(StringPrintf(" requiredFeature='%s'", requiredFeature.data()));
+        printer->Print(StringPrintf(" requiredFeature='%s'", requiredFeature.data()));
       }
       if (!requiredNotFeature.empty()) {
-        printer.Print(StringPrintf(" requiredNotFeature='%s'", requiredNotFeature.data()));
+        printer->Print(StringPrintf(" requiredNotFeature='%s'", requiredNotFeature.data()));
       }
-      printer.Print("\n");
+      printer->Print("\n");
       if (required == 0) {
-        printer.Print(StringPrintf("optional-permission: name='%s'", name.data()));
+        printer->Print(StringPrintf("optional-permission: name='%s'", name.data()));
         if (maxSdkVersion >= 0) {
-          printer.Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion));
+          printer->Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion));
         }
-        printer.Print("\n");
+        printer->Print("\n");
       }
     }
   }
 
-  void PrintImplied(text::Printer& printer, const std::string& reason) {
-    printer.Print(StringPrintf("uses-implied-permission: name='%s'", name.data()));
+  void PrintImplied(text::Printer* printer, const std::string& reason) {
+    printer->Print(StringPrintf("uses-implied-permission: name='%s'", name.data()));
     if (maxSdkVersion >= 0) {
-      printer.Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion));
+      printer->Print(StringPrintf(" maxSdkVersion='%d'", maxSdkVersion));
     }
-    printer.Print(StringPrintf(" reason='%s'\n", reason.data()));
+    printer->Print(StringPrintf(" reason='%s'\n", reason.data()));
   }
 };
 
@@ -1110,13 +1112,13 @@
     }
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (name) {
-      printer.Print(StringPrintf("uses-permission-sdk-23: name='%s'", name->data()));
+      printer->Print(StringPrintf("uses-permission-sdk-23: name='%s'", name->data()));
       if (maxSdkVersion) {
-        printer.Print(StringPrintf(" maxSdkVersion='%d'", *maxSdkVersion));
+        printer->Print(StringPrintf(" maxSdkVersion='%d'", *maxSdkVersion));
       }
-      printer.Print("\n");
+      printer->Print("\n");
     }
   }
 };
@@ -1131,9 +1133,9 @@
     name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), "");
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (extractor()->options_.only_permissions && !name.empty()) {
-      printer.Print(StringPrintf("permission: %s\n", name.data()));
+      printer->Print(StringPrintf("permission: %s\n", name.data()));
     }
   }
 };
@@ -1193,25 +1195,25 @@
     }
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     // Print whether the activity has the HOME category and a the MAIN action
     if (has_main_action && has_launcher_category) {
-      printer.Print("launchable-activity:");
+      printer->Print("launchable-activity:");
       if (!name.empty()) {
-        printer.Print(StringPrintf(" name='%s' ", name.data()));
+        printer->Print(StringPrintf(" name='%s' ", name.data()));
       }
-      printer.Print(StringPrintf(" label='%s' icon='%s'\n",
+      printer->Print(StringPrintf(" label='%s' icon='%s'\n",
                                   android::ResTable::normalizeForOutput(label.data()).c_str(),
                                   icon.data()));
     }
 
     // Print wether the activity has the HOME category and a the MAIN action
     if (has_leanback_launcher_category) {
-      printer.Print("leanback-launchable-activity:");
+      printer->Print("leanback-launchable-activity:");
       if (!name.empty()) {
-        printer.Print(StringPrintf(" name='%s' ", name.data()));
+        printer->Print(StringPrintf(" name='%s' ", name.data()));
       }
-      printer.Print(StringPrintf(" label='%s' icon='%s' banner='%s'\n",
+      printer->Print(StringPrintf(" label='%s' icon='%s' banner='%s'\n",
                                   android::ResTable::normalizeForOutput(label.data()).c_str(),
                                   icon.data(), banner.data()));
     }
@@ -1310,14 +1312,78 @@
     }
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (!name.empty()) {
-      printer.Print(StringPrintf("uses-library%s:'%s'\n",
+      printer->Print(StringPrintf("uses-library%s:'%s'\n",
                                  (required == 0) ? "-not-required" : "", name.data()));
     }
   }
 };
 
+/** Represents <static-library> elements. **/
+class StaticLibrary : public ManifestExtractor::Element {
+ public:
+  StaticLibrary() = default;
+  std::string name;
+  int version;
+  int versionMajor;
+
+  void Extract(xml::Element* element) override {
+    auto parent_stack = extractor()->parent_stack();
+    if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) {
+      name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), "");
+      version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0);
+      versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0);
+    }
+  }
+
+  void Print(text::Printer* printer) override {
+    printer->Print(StringPrintf(
+      "static-library: name='%s' version='%d' versionMajor='%d'\n",
+      name.data(), version, versionMajor));
+  }
+};
+
+/** Represents <uses-static-library> elements. **/
+class UsesStaticLibrary : public ManifestExtractor::Element {
+ public:
+  UsesStaticLibrary() = default;
+  std::string name;
+  int version;
+  int versionMajor;
+  std::vector<std::string> certDigests;
+
+  void Extract(xml::Element* element) override {
+    auto parent_stack = extractor()->parent_stack();
+    if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) {
+      name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), "");
+      version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0);
+      versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0);
+      AddCertDigest(element);
+    }
+  }
+
+  void AddCertDigest(xml::Element* element) {
+    std::string digest = GetAttributeStringDefault(FindAttribute(element, CERT_DIGEST_ATTR), "");
+    // We allow ":" delimiters in the SHA declaration as this is the format
+    // emitted by the certtool making it easy for developers to copy/paste.
+    digest.erase(std::remove(digest.begin(), digest.end(), ':'), digest.end());
+    if (!digest.empty()) {
+      certDigests.push_back(digest);
+    }
+  }
+
+  void Print(text::Printer* printer) override {
+    printer->Print(StringPrintf(
+      "uses-static-library: name='%s' version='%d' versionMajor='%d'",
+      name.data(), version, versionMajor));
+    for (size_t i = 0; i < certDigests.size(); i++) {
+      printer->Print(StringPrintf(" certDigest='%s'", certDigests[i].data()));
+    }
+    printer->Print("\n");
+  }
+};
+
 /**
  * Represents <meta-data> elements. These tags are only printed when a flag is passed in to
  * explicitly enable meta data printing.
@@ -1326,34 +1392,34 @@
  public:
   MetaData() = default;
   std::string name;
-  const std::string* value;
+  std::string value;
   const int* value_int;
-  const std::string* resource;
+  std::string resource;
   const int* resource_int;
 
   void Extract(xml::Element* element) override {
     name = GetAttributeStringDefault(FindAttribute(element, NAME_ATTR), "");
-    value = GetAttributeString(FindAttribute(element, VALUE_ATTR));
+    value = GetAttributeStringDefault(FindAttribute(element, VALUE_ATTR), "");
     value_int = GetAttributeInteger(FindAttribute(element, VALUE_ATTR));
-    resource = GetAttributeString(FindAttribute(element, RESOURCE_ATTR));
+    resource = GetAttributeStringDefault(FindAttribute(element, RESOURCE_ATTR), "");
     resource_int = GetAttributeInteger(FindAttribute(element, RESOURCE_ATTR));
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (extractor()->options_.include_meta_data && !name.empty()) {
-      printer.Print(StringPrintf("meta-data: name='%s' ", name.data()));
-      if (value) {
-        printer.Print(StringPrintf("value='%s' ", value->data()));
+      printer->Print(StringPrintf("meta-data: name='%s' ", name.data()));
+      if (!value.empty()) {
+        printer->Print(StringPrintf("value='%s' ", value.data()));
       } else if (value_int) {
-        printer.Print(StringPrintf("value='%d' ", *value_int));
+        printer->Print(StringPrintf("value='%d' ", *value_int));
       } else {
-        if (resource) {
-          printer.Print(StringPrintf("resource='%s' ", resource->data()));
+        if (!resource.empty()) {
+          printer->Print(StringPrintf("resource='%s' ", resource.data()));
         } else if (resource_int) {
-          printer.Print(StringPrintf("resource='%d' ", *resource_int));
+          printer->Print(StringPrintf("resource='%d' ", *resource_int));
         }
       }
-      printer.Print("\n");
+      printer->Print("\n");
     }
   }
 };
@@ -1475,14 +1541,14 @@
   SupportsInput() = default;
   std::vector<std::string> inputs;
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     const size_t size = inputs.size();
     if (size > 0) {
-      printer.Print("supports-input: '");
+      printer->Print("supports-input: '");
       for (size_t i = 0; i < size; i++) {
-        printer.Print(StringPrintf("value='%s' ", inputs[i].data()));
+        printer->Print(StringPrintf("value='%s' ", inputs[i].data()));
       }
-      printer.Print("\n");
+      printer->Print("\n");
     }
   }
 };
@@ -1513,9 +1579,9 @@
     name = GetAttributeString(FindAttribute(element, NAME_ATTR));
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (name) {
-      printer.Print(StringPrintf("original-package:'%s'\n", name->data()));
+      printer->Print(StringPrintf("original-package:'%s'\n", name->data()));
     }
   }
 };
@@ -1532,9 +1598,9 @@
     public_key = GetAttributeString(FindAttribute(element, PUBLIC_KEY_ATTR));
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (name && public_key) {
-      printer.Print(StringPrintf("package-verifier: name='%s' publicKey='%s'\n",
+      printer->Print(StringPrintf("package-verifier: name='%s' publicKey='%s'\n",
                                  name->data(), public_key->data()));
     }
   }
@@ -1544,15 +1610,65 @@
 class UsesPackage : public ManifestExtractor::Element {
  public:
   UsesPackage() = default;
+  const std::string* packageType = nullptr;
   const std::string* name = nullptr;
+  int version;
+  int versionMajor;
+  std::vector<std::string> certDigests;
 
   void Extract(xml::Element* element) override {
-    name = GetAttributeString(FindAttribute(element, NAME_ATTR));
+    auto parent_stack = extractor()->parent_stack();
+    if (parent_stack.size() > 0 && ElementCast<Application>(parent_stack[0])) {
+      packageType = GetAttributeString(FindAttribute(element, PACKAGE_TYPE_ATTR));
+      name = GetAttributeString(FindAttribute(element, NAME_ATTR));
+      version = GetAttributeIntegerDefault(FindAttribute(element, VERSION_ATTR), 0);
+      versionMajor = GetAttributeIntegerDefault(FindAttribute(element, VERSION_MAJOR_ATTR), 0);
+      AddCertDigest(element);
+    }
   }
 
-  void Print(text::Printer& printer) override {
+  void AddCertDigest(xml::Element* element) {
+    std::string digest = GetAttributeStringDefault(FindAttribute(element, CERT_DIGEST_ATTR), "");
+    // We allow ":" delimiters in the SHA declaration as this is the format
+    // emitted by the certtool making it easy for developers to copy/paste.
+    digest.erase(std::remove(digest.begin(), digest.end(), ':'), digest.end());
+    if (!digest.empty()) {
+      certDigests.push_back(digest);
+    }
+  }
+
+  void Print(text::Printer* printer) override {
     if (name) {
-      printer.Print(StringPrintf("uses-package:'%s'\n", name->data()));
+      if (packageType) {
+        printer->Print(StringPrintf(
+          "uses-typed-package: type='%s' name='%s' version='%d' versionMajor='%d'",
+          packageType->data(), name->data(), version, versionMajor));
+        for (size_t i = 0; i < certDigests.size(); i++) {
+          printer->Print(StringPrintf(" certDigest='%s'", certDigests[i].data()));
+        }
+        printer->Print("\n");
+      } else {
+        printer->Print(StringPrintf("uses-package:'%s'\n", name->data()));
+      }
+    }
+  }
+};
+
+/** Represents <additional-certificate> elements. **/
+class AdditionalCertificate : public ManifestExtractor::Element {
+ public:
+  AdditionalCertificate() = default;
+
+  void Extract(xml::Element* element) override {
+    auto parent_stack = extractor()->parent_stack();
+    if (parent_stack.size() > 0) {
+      if (ElementCast<UsesPackage>(parent_stack[0])) {
+        UsesPackage* uses = ElementCast<UsesPackage>(parent_stack[0]);
+        uses->AddCertDigest(element);
+      } else if (ElementCast<UsesStaticLibrary>(parent_stack[0])) {
+        UsesStaticLibrary* uses = ElementCast<UsesStaticLibrary>(parent_stack[0]);
+        uses->AddCertDigest(element);
+      }
     }
   }
 };
@@ -1577,8 +1693,8 @@
 class CompatibleScreens : public ManifestExtractor::Element {
  public:
   CompatibleScreens() = default;
-  void Print(text::Printer& printer) override {
-    printer.Print("compatible-screens:");
+  void Print(text::Printer* printer) override {
+    printer->Print("compatible-screens:");
 
     bool first = true;
     ForEachChild(this, [&printer, &first](ManifestExtractor::Element* el){
@@ -1586,15 +1702,15 @@
         if (first) {
           first = false;
         } else {
-          printer.Print(",");
+          printer->Print(",");
         }
 
         if (screen->size && screen->density) {
-          printer.Print(StringPrintf("'%d/%d'", *screen->size, *screen->density));
+          printer->Print(StringPrintf("'%d/%d'", *screen->size, *screen->density));
         }
       }
     });
-    printer.Print("\n");
+    printer->Print("\n");
   }
 };
 
@@ -1608,22 +1724,22 @@
     name = GetAttributeString(FindAttribute(element, NAME_ATTR));
   }
 
-  void Print(text::Printer& printer) override {
+  void Print(text::Printer* printer) override {
     if (name) {
-      printer.Print(StringPrintf("supports-gl-texture:'%s'\n", name->data()));
+      printer->Print(StringPrintf("supports-gl-texture:'%s'\n", name->data()));
     }
   }
 };
 
 /** Recursively prints the extracted badging element. */
-static void Print(ManifestExtractor::Element* el, text::Printer& printer) {
+static void Print(ManifestExtractor::Element* el, text::Printer* printer) {
   el->Print(printer);
   for (auto &child : el->children()) {
     Print(child.get(), printer);
   }
 }
 
-bool ManifestExtractor::Dump(text::Printer& printer, IDiagnostics* diag) {
+bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) {
   // Load the manifest
   std::unique_ptr<xml::XmlResource> doc = apk_->LoadXml("AndroidManifest.xml", diag);
   if (doc == nullptr) {
@@ -1652,7 +1768,7 @@
         }
       }
 
-      printer.Print(StringPrintf("package: %s\n", manifest->package.data()));
+      printer->Print(StringPrintf("package: %s\n", manifest->package.data()));
       ForEachChild(manifest, [&printer](ManifestExtractor::Element* el) -> void {
         el->Print(printer);
       });
@@ -1837,10 +1953,10 @@
                   && offhost_apdu_action)) {
 
             // Attempt to load the resource file
-            if (!meta_data->resource) {
+            if (!meta_data->resource.empty()) {
               return;
             }
-            auto resource = apk->LoadXml(*meta_data->resource, diag);
+            auto resource = apk->LoadXml(meta_data->resource, diag);
             if (!resource) {
               return;
             }
@@ -1869,7 +1985,7 @@
   // Print the components types if they are present
   auto PrintComponent = [&components, &printer](const std::string& component) -> void {
     if (components.find(component) != components.end()) {
-      printer.Print(StringPrintf("provides-component:'%s'\n", component.data()));
+      printer->Print(StringPrintf("provides-component:'%s'\n", component.data()));
     }
   };
 
@@ -1890,14 +2006,14 @@
 
   // Print presence of main activity
   if (components.find("main") != components.end()) {
-    printer.Print("main\n");
+    printer->Print("main\n");
   }
 
   // Print presence of activities, recivers, and services with no special components
   FindElement(root.get(), [&printer](ManifestExtractor::Element* el) -> bool {
     if (auto activity = ElementCast<Activity>(el)) {
       if (!activity->has_component_) {
-        printer.Print("other-activities\n");
+        printer->Print("other-activities\n");
         return true;
       }
     }
@@ -1907,7 +2023,7 @@
   FindElement(root.get(), [&printer](ManifestExtractor::Element* el) -> bool {
     if (auto receiver = ElementCast<Receiver>(el)) {
       if (!receiver->has_component) {
-        printer.Print("other-receivers\n");
+        printer->Print("other-receivers\n");
         return true;
       }
     }
@@ -1917,7 +2033,7 @@
   FindElement(root.get(), [&printer](ManifestExtractor::Element* el) -> bool {
     if (auto service = ElementCast<Service>(el)) {
       if (!service->has_component) {
-        printer.Print("other-services\n");
+        printer->Print("other-services\n");
         return true;
       }
     }
@@ -1939,22 +2055,22 @@
   }
 
   // Print all the unique locales of the apk
-  printer.Print("locales:");
+  printer->Print("locales:");
   for (auto& config : locales_) {
     if (config.first.empty()) {
-      printer.Print(" '--_--'");
+      printer->Print(" '--_--'");
     } else {
-      printer.Print(StringPrintf(" '%s'", config.first.data()));
+      printer->Print(StringPrintf(" '%s'", config.first.data()));
     }
   }
-  printer.Print("\n");
+  printer->Print("\n");
 
   // Print all the densities locales of the apk
-  printer.Print("densities:");
+  printer->Print("densities:");
   for (auto& config : densities_) {
-    printer.Print(StringPrintf(" '%d'", config.first));
+    printer->Print(StringPrintf(" '%d'", config.first));
   }
-  printer.Print("\n");
+  printer->Print("\n");
 
   // Print the supported architectures of the app
   std::set<std::string> architectures;
@@ -2008,7 +2124,7 @@
     }
 
     if (arch != architectures.end()) {
-      printer.Print(StringPrintf("native-code: '%s'\n", arch->data()));
+      printer->Print(StringPrintf("native-code: '%s'\n", arch->data()));
       architectures.erase(arch);
       output_alt_native_code = true;
     }
@@ -2016,13 +2132,13 @@
 
   if (architectures.size() > 0) {
     if (output_alt_native_code) {
-      printer.Print("alt-");
+      printer->Print("alt-");
     }
-    printer.Print("native-code:");
+    printer->Print("native-code:");
     for (auto& arch : architectures) {
-      printer.Print(StringPrintf(" '%s'", arch.data()));
+      printer->Print(StringPrintf(" '%s'", arch.data()));
     }
-    printer.Print("\n");
+    printer->Print("\n");
   }
 
   return true;
@@ -2065,6 +2181,9 @@
     {"uses-permission-sdk-23", std::is_base_of<UsesPermissionSdk23, T>::value},
     {"uses-library", std::is_base_of<UsesLibrary, T>::value},
     {"uses-package", std::is_base_of<UsesPackage, T>::value},
+    {"static-library", std::is_base_of<StaticLibrary, T>::value},
+    {"uses-static-library", std::is_base_of<UsesStaticLibrary, T>::value},
+    {"additional-certificate", std::is_base_of<AdditionalCertificate, T>::value},
     {"uses-sdk", std::is_base_of<UsesSdkBadging, T>::value},
   };
 
@@ -2110,7 +2229,10 @@
     {"uses-permission", &CreateType<UsesPermission>},
     {"uses-permission-sdk-23", &CreateType<UsesPermissionSdk23>},
     {"uses-library", &CreateType<UsesLibrary>},
+    {"static-library", &CreateType<StaticLibrary>},
+    {"uses-static-library", &CreateType<UsesStaticLibrary>},
     {"uses-package", &CreateType<UsesPackage>},
+    {"additional-certificate", &CreateType<AdditionalCertificate>},
     {"uses-sdk", &CreateType<UsesSdkBadging>},
   };
 
@@ -2143,55 +2265,11 @@
   return element;
 }
 
-// Use a smaller buffer so that there is less latency for dumping to stdout.
-constexpr size_t kStdOutBufferSize = 1024u;
 
-int DumpBadgingCommand::Action(const std::vector<std::string>& args) {
-  if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump apk specified.");
-    return 1;
-  }
-
-  ManifestExtractor::Options options;
-  options.include_meta_data = include_metadata_;
-
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  text::Printer printer(&fout);
-  for (auto apk : args) {
-    auto loaded_apk = LoadedApk::LoadApkFromPath(apk, diag_);
-    if (!loaded_apk) {
-      return 1;
-    }
-
-    ManifestExtractor extractor(loaded_apk.get(), options);
-    extractor.Dump(printer, diag_);
-  }
-
-  return 0;
+int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer,
+                 IDiagnostics* diag) {
+  ManifestExtractor extractor(apk, options);
+  return extractor.Dump(printer, diag);
 }
 
-int DumpPermissionsCommand::Action(const std::vector<std::string>& args) {
-  if (args.size() < 1) {
-    diag_->Error(DiagMessage() << "No dump apk specified.");
-    return 1;
-  }
-
-  ManifestExtractor::Options options;
-  options.only_permissions = true;
-
-  io::FileOutputStream fout(STDOUT_FILENO, kStdOutBufferSize);
-  text::Printer printer(&fout);
-  for (auto apk : args) {
-    auto loaded_apk = LoadedApk::LoadApkFromPath(apk, diag_);
-    if (!loaded_apk) {
-      return 1;
-    }
-
-    ManifestExtractor extractor(loaded_apk.get(), options);
-    extractor.Dump(printer, diag_);
-  }
-
-  return 0;
-}
-
-} // namespace aapt
\ No newline at end of file
+} // namespace aapt
diff --git a/tools/aapt2/dump/DumpManifest.h b/tools/aapt2/dump/DumpManifest.h
index a70be53..daf22ed 100644
--- a/tools/aapt2/dump/DumpManifest.h
+++ b/tools/aapt2/dump/DumpManifest.h
@@ -17,45 +17,23 @@
 #ifndef AAPT2_DUMP_MANIFEST_H
 #define AAPT2_DUMP_MANIFEST_H
 
-#include <Diagnostics.h>
-#include <ValueVisitor.h>
-#include <io/ZipArchive.h>
-
-
-#include "cmd/Command.h"
-#include "process/IResourceTableConsumer.h"
+#include "Diagnostics.h"
+#include "LoadedApk.h"
 #include "text/Printer.h"
-#include "xml/XmlDom.h"
 
 namespace aapt {
 
-class DumpBadgingCommand : public Command {
- public:
-  explicit DumpBadgingCommand(IDiagnostics* diag) : Command("badging"), diag_(diag) {
-    SetDescription("Print information extracted from the manifest of the APK.");
-    AddOptionalSwitch("--include-meta-data", "Include meta-data information.",
-                      &include_metadata_);
-  }
-
-  int Action(const std::vector<std::string>& args) override;
-
- private:
-  IDiagnostics* diag_;
-  bool include_metadata_ = false;
+struct DumpManifestOptions {
+  /** Include meta information from <meta-data> elements in the output. */
+  bool include_meta_data = false;
+  /** Only output permission information. */
+  bool only_permissions = false;
 };
 
-class DumpPermissionsCommand : public Command {
- public:
-  explicit DumpPermissionsCommand(IDiagnostics* diag) : Command("permissions"), diag_(diag) {
-    SetDescription("Print the permissions extracted from the manifest of the APK.");
-  }
+/** Print information extracted from the manifest of the APK. */
+int DumpManifest(LoadedApk* apk, DumpManifestOptions& options, text::Printer* printer,
+                 IDiagnostics* diag);
 
-  int Action(const std::vector<std::string>& args) override;
+}  // namespace aapt
 
- private:
-  IDiagnostics* diag_;
-};
-
-}// namespace aapt
-
-#endif //AAPT2_DUMP_MANIFEST_H
\ No newline at end of file
+#endif  // AAPT2_DUMP_MANIFEST_H
\ No newline at end of file
diff --git a/tools/aapt2/filter/ConfigFilter.cpp b/tools/aapt2/filter/ConfigFilter.cpp
index 5fbe77e..9d10d59 100644
--- a/tools/aapt2/filter/ConfigFilter.cpp
+++ b/tools/aapt2/filter/ConfigFilter.cpp
@@ -16,9 +16,10 @@
 
 #include "filter/ConfigFilter.h"
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "ConfigDescription.h"
+using ::android::ConfigDescription;
 
 namespace aapt {
 
diff --git a/tools/aapt2/filter/ConfigFilter.h b/tools/aapt2/filter/ConfigFilter.h
index ebb8151..c4b7e43 100644
--- a/tools/aapt2/filter/ConfigFilter.h
+++ b/tools/aapt2/filter/ConfigFilter.h
@@ -20,7 +20,7 @@
 #include <set>
 #include <utility>
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
 
 namespace aapt {
 
@@ -34,7 +34,7 @@
   /**
    * Returns true if the filter matches the configuration, false otherwise.
    */
-  virtual bool Match(const ConfigDescription& config) const = 0;
+  virtual bool Match(const android::ConfigDescription& config) const = 0;
 };
 
 /**
@@ -46,12 +46,12 @@
  */
 class AxisConfigFilter : public IConfigFilter {
  public:
-  void AddConfig(ConfigDescription config);
+  void AddConfig(android::ConfigDescription config);
 
-  bool Match(const ConfigDescription& config) const override;
+  bool Match(const android::ConfigDescription& config) const override;
 
  private:
-  std::set<std::pair<ConfigDescription, uint32_t>> configs_;
+  std::set<std::pair<android::ConfigDescription, uint32_t>> configs_;
   uint32_t config_mask_ = 0;
 };
 
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.h b/tools/aapt2/format/binary/BinaryResourceParser.h
index a1f9f83..2bdc051 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.h
+++ b/tools/aapt2/format/binary/BinaryResourceParser.h
@@ -20,6 +20,7 @@
 #include <string>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
 #include "ResourceTable.h"
@@ -54,22 +55,28 @@
   bool ParseType(const ResourceTablePackage* package, const android::ResChunk_header* chunk);
   bool ParseLibrary(const android::ResChunk_header* chunk);
 
-  std::unique_ptr<Item> ParseValue(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Item> ParseValue(const ResourceNameRef& name,
+                                   const android::ConfigDescription& config,
                                    const android::Res_value& value);
 
-  std::unique_ptr<Value> ParseMapEntry(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Value> ParseMapEntry(const ResourceNameRef& name,
+                                       const android::ConfigDescription& config,
                                        const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Style> ParseStyle(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Style> ParseStyle(const ResourceNameRef& name,
+                                    const android::ConfigDescription& config,
                                     const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Attribute> ParseAttr(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Attribute> ParseAttr(const ResourceNameRef& name,
+                                       const android::ConfigDescription& config,
                                        const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Array> ParseArray(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Array> ParseArray(const ResourceNameRef& name,
+                                    const android::ConfigDescription& config,
                                     const android::ResTable_map_entry* map);
 
-  std::unique_ptr<Plural> ParsePlural(const ResourceNameRef& name, const ConfigDescription& config,
+  std::unique_ptr<Plural> ParsePlural(const ResourceNameRef& name,
+                                      const android::ConfigDescription& config,
                                       const android::ResTable_map_entry* map);
 
   /**
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 3b101b7..d1b2fdb 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -19,13 +19,15 @@
 #include "android-base/logging.h"
 #include "android-base/macros.h"
 #include "androidfw/ResourceTypes.h"
+#include "androidfw/Locale.h"
 
-#include "Locale.h"
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
 
+using ::android::ConfigDescription;
+using ::android::LocaleValue;
 using ::android::ResStringPool;
 
 namespace aapt {
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.h b/tools/aapt2/format/proto/ProtoDeserialize.h
index 0c581a1..723a1c0 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.h
+++ b/tools/aapt2/format/proto/ProtoDeserialize.h
@@ -18,9 +18,9 @@
 #define AAPT_FORMAT_PROTO_PROTODESERIALIZE_H
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "ConfigDescription.h"
 #include "Configuration.pb.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -34,14 +34,15 @@
 
 std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
                                               const android::ResStringPool& src_pool,
-                                              const ConfigDescription& config,
+                                              const android::ConfigDescription& config,
                                               StringPool* value_pool, io::IFileCollection* files,
                                               std::string* out_error);
 
 std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
                                             const android::ResStringPool& src_pool,
-                                            const ConfigDescription& config, StringPool* value_pool,
-                                            io::IFileCollection* files, std::string* out_error);
+                                            const android::ConfigDescription& config,
+                                            StringPool* value_pool, io::IFileCollection* files,
+                                            std::string* out_error);
 
 std::unique_ptr<xml::XmlResource> DeserializeXmlResourceFromPb(const pb::XmlNode& pb_node,
                                                                std::string* out_error);
@@ -49,8 +50,8 @@
 bool DeserializeXmlFromPb(const pb::XmlNode& pb_node, xml::Element* out_el, StringPool* value_pool,
                           std::string* out_error);
 
-bool DeserializeConfigFromPb(const pb::Configuration& pb_config, ConfigDescription* out_config,
-                             std::string* out_error);
+bool DeserializeConfigFromPb(const pb::Configuration& pb_config,
+                             android::ConfigDescription* out_config, std::string* out_error);
 
 // Optional io::IFileCollection used to lookup references to files in the ResourceTable.
 bool DeserializeTableFromPb(const pb::ResourceTable& pb_table, io::IFileCollection* files,
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index 411cc29..7e35ea7 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -19,6 +19,8 @@
 #include "ValueVisitor.h"
 #include "util/BigBuffer.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
 void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool, IDiagnostics* diag) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize.h b/tools/aapt2/format/proto/ProtoSerialize.h
index 951494c..c40e5dd 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.h
+++ b/tools/aapt2/format/proto/ProtoSerialize.h
@@ -18,8 +18,8 @@
 #define AAPT_FORMAT_PROTO_PROTOSERIALIZE_H
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
 #include "Configuration.pb.h"
 #include "ResourceTable.h"
 #include "ResourceValues.h"
@@ -49,7 +49,7 @@
 void SerializeStringPoolToPb(const StringPool& pool, pb::StringPool* out_pb_pool, IDiagnostics* diag);
 
 // Serializes a ConfigDescription into its protobuf representation.
-void SerializeConfig(const ConfigDescription& config, pb::Configuration* out_pb_config);
+void SerializeConfig(const android::ConfigDescription& config, pb::Configuration* out_pb_config);
 
 // Serializes a ResourceTable into its protobuf representation.
 void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table, IDiagnostics* diag);
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index 21fdbd8..3c4d41a 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -20,6 +20,7 @@
 #include "format/proto/ProtoDeserialize.h"
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::testing::Eq;
 using ::testing::IsEmpty;
@@ -33,6 +34,7 @@
  public:
   MOCK_METHOD1(FindFile, io::IFile*(const StringPiece& path));
   MOCK_METHOD0(Iterator, std::unique_ptr<io::IFileCollectionIterator>());
+  MOCK_METHOD0(GetDirSeparator, char());
 };
 
 TEST(ProtoSerializeTest, SerializeSinglePackage) {
diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h
index f06e28c..565aad6 100644
--- a/tools/aapt2/io/File.h
+++ b/tools/aapt2/io/File.h
@@ -25,6 +25,7 @@
 
 #include "Source.h"
 #include "io/Data.h"
+#include "util/Files.h"
 #include "util/Util.h"
 
 namespace aapt {
@@ -103,6 +104,7 @@
 
   virtual IFile* FindFile(const android::StringPiece& path) = 0;
   virtual std::unique_ptr<IFileCollectionIterator> Iterator() = 0;
+  virtual char GetDirSeparator() = 0;
 };
 
 }  // namespace io
diff --git a/tools/aapt2/io/FileSystem.cpp b/tools/aapt2/io/FileSystem.cpp
index 16a20f4c..51cc903 100644
--- a/tools/aapt2/io/FileSystem.cpp
+++ b/tools/aapt2/io/FileSystem.cpp
@@ -128,5 +128,9 @@
   return util::make_unique<FileCollectionIterator>(this);
 }
 
+char FileCollection::GetDirSeparator() {
+  return file::sDirSep;
+}
+
 }  // namespace io
 }  // namespace aapt
diff --git a/tools/aapt2/io/FileSystem.h b/tools/aapt2/io/FileSystem.h
index fb6bf6e..04c6fa1 100644
--- a/tools/aapt2/io/FileSystem.h
+++ b/tools/aapt2/io/FileSystem.h
@@ -67,6 +67,7 @@
   IFile* InsertFile(const android::StringPiece& path);
   IFile* FindFile(const android::StringPiece& path) override;
   std::unique_ptr<IFileCollectionIterator> Iterator() override;
+  char GetDirSeparator() override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(FileCollection);
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index 866e96d..427dc92 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -159,6 +159,13 @@
   return util::make_unique<ZipFileCollectionIterator>(this);
 }
 
+char ZipFileCollection::GetDirSeparator() {
+  // According to the zip file specification, section  4.4.17.1:
+  // "All slashes MUST be forward slashes '/' as opposed to backwards slashes '\' for compatibility
+  // with Amiga and UNIX file systems etc."
+  return '/';
+}
+
 ZipFileCollection::~ZipFileCollection() {
   if (handle_) {
     CloseArchive(handle_);
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
index 8381259..b283e57 100644
--- a/tools/aapt2/io/ZipArchive.h
+++ b/tools/aapt2/io/ZipArchive.h
@@ -66,6 +66,7 @@
 
   io::IFile* FindFile(const android::StringPiece& path) override;
   std::unique_ptr<IFileCollectionIterator> Iterator() override;
+  char GetDirSeparator() override;
 
   ~ZipFileCollection() override;
 
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index d40795a..52e168e 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -384,7 +384,7 @@
   return true;
 }
 
-void WriteKeepSet(const KeepSet& keep_set, OutputStream* out) {
+void WriteKeepSet(const KeepSet& keep_set, OutputStream* out, bool minimal_keep) {
   Printer printer(out);
   for (const auto& entry : keep_set.manifest_class_set_) {
     for (const UsageLocation& location : entry.second) {
@@ -406,15 +406,19 @@
         printer.Print("-if class **.R$layout { int ")
             .Print(JavaClassGenerator::TransformToFieldName(location.name.entry))
             .Println("; }");
-        printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(")
-            .Print(entry.first.signature).Println("); }");
+
+        printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(");
+        printer.Print((minimal_keep) ? entry.first.signature : "...");
+        printer.Println("); }");
       }
     } else {
       for (const UsageLocation& location : entry.second) {
         printer.Print("# Referenced at ").Println(location.source.to_string());
       }
-      printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(")
-          .Print(entry.first.signature).Println("); }");
+
+      printer.Print("-keep class ").Print(entry.first.name).Print(" { <init>(");
+      printer.Print((minimal_keep) ? entry.first.signature : "...");
+      printer.Println("); }");
     }
     printer.Println();
   }
diff --git a/tools/aapt2/java/ProguardRules.h b/tools/aapt2/java/ProguardRules.h
index 01dad0b..38b4860 100644
--- a/tools/aapt2/java/ProguardRules.h
+++ b/tools/aapt2/java/ProguardRules.h
@@ -70,7 +70,7 @@
   }
 
  private:
-  friend void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out);
+  friend void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out, bool minimal_keep);
 
   friend bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set,
                                std::set<UsageLocation>* locations);
@@ -89,7 +89,7 @@
 
 bool CollectResourceReferences(IAaptContext* context, ResourceTable* table, KeepSet* keep_set);
 
-void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out);
+void WriteKeepSet(const KeepSet& keep_set, io::OutputStream* out, bool minimal_keep);
 
 bool CollectLocations(const UsageLocation& location, const KeepSet& keep_set,
                       std::set<UsageLocation>* locations);
diff --git a/tools/aapt2/java/ProguardRules_test.cpp b/tools/aapt2/java/ProguardRules_test.cpp
index 83c72d8..da24907 100644
--- a/tools/aapt2/java/ProguardRules_test.cpp
+++ b/tools/aapt2/java/ProguardRules_test.cpp
@@ -21,15 +21,16 @@
 #include "test/Test.h"
 
 using ::aapt::io::StringOutputStream;
+using ::android::ConfigDescription;
 using ::testing::HasSubstr;
 using ::testing::Not;
 
 namespace aapt {
 
-std::string GetKeepSetString(const proguard::KeepSet& set) {
+std::string GetKeepSetString(const proguard::KeepSet& set, bool minimal_rules) {
   std::string out;
   StringOutputStream sout(&out);
-  proguard::WriteKeepSet(set, &sout);
+  proguard::WriteKeepSet(set, &sout, minimal_rules);
   sout.Flush();
   return out;
 }
@@ -53,8 +54,17 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRulesForManifest(manifest.get(), &set, false));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarAppComponentFactory { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarBackupAgent { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarApplication { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarActivity { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarService { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarReceiver { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarProvider { <init>(); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarInstrumentation { <init>(); }"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarAppComponentFactory { <init>(); }"));
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarBackupAgent { <init>(); }"));
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.BarApplication { <init>(); }"));
@@ -75,8 +85,10 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
 }
 
@@ -89,8 +101,10 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
 }
 
@@ -105,8 +119,11 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(); }"));
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(); }"));
 }
@@ -133,7 +150,12 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), navigation.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.package.Foo { <init>(...); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.package.Bar { <init>(...); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.base.Nested { <init>(...); }"));
+
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr("-keep class com.package.Foo { <init>(...); }"));
   EXPECT_THAT(actual, HasSubstr("-keep class com.package.Bar { <init>(...); }"));
   EXPECT_THAT(actual, HasSubstr("-keep class com.base.Nested { <init>(...); }"));
@@ -150,8 +172,10 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr(
       "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
 }
@@ -188,11 +212,16 @@
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), bar_layout.get(), &set));
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), foo_layout.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-if class **.R$layout"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+  EXPECT_THAT(actual, HasSubstr("int foo"));
+  EXPECT_THAT(actual, HasSubstr("int bar"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr("-if class **.R$layout"));
   EXPECT_THAT(actual, HasSubstr(
-      "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
+    "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
   EXPECT_THAT(actual, HasSubstr("int foo"));
   EXPECT_THAT(actual, HasSubstr("int bar"));
 }
@@ -209,10 +238,16 @@
   set.AddReference({test::ParseNameOrDie("layout/bar"), {}}, layout->file.name);
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
-
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
   EXPECT_THAT(actual, HasSubstr(
-      "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
+      "-keep class com.foo.Bar { <init>(...); }"));
+  EXPECT_THAT(actual, HasSubstr("-if class **.R$layout"));
+  EXPECT_THAT(actual, HasSubstr("int foo"));
+  EXPECT_THAT(actual, HasSubstr("int bar"));
+
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr(
+    "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
   EXPECT_THAT(actual, HasSubstr("-if class **.R$layout"));
   EXPECT_THAT(actual, HasSubstr("int foo"));
   EXPECT_THAT(actual, HasSubstr("int bar"));
@@ -230,11 +265,14 @@
   set.AddReference({test::ParseNameOrDie("style/MyStyle"), {}}, layout->file.name);
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, Not(HasSubstr("-if")));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, Not(HasSubstr("-if")));
   EXPECT_THAT(actual, HasSubstr(
-      "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
+    "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
 }
 
 TEST(ProguardRulesTest, ViewOnClickRuleIsEmitted) {
@@ -247,10 +285,13 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), layout.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
-
+  std::string actual = GetKeepSetString(set,  /** minimal_rules */ false);
   EXPECT_THAT(actual, HasSubstr(
       "-keepclassmembers class * { *** bar_method(android.view.View); }"));
+
+  actual = GetKeepSetString(set,  /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr(
+    "-keepclassmembers class * { *** bar_method(android.view.View); }"));
 }
 
 TEST(ProguardRulesTest, MenuRulesAreEmitted) {
@@ -267,10 +308,16 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), menu.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
-
+  std::string actual = GetKeepSetString(set,  /** minimal_rules */ false);
   EXPECT_THAT(actual, HasSubstr(
-      "-keepclassmembers class * { *** on_click(android.view.MenuItem); }"));
+    "-keepclassmembers class * { *** on_click(android.view.MenuItem); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(...); }"));
+  EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat")));
+
+  actual = GetKeepSetString(set,  /** minimal_rules */ true);
+  EXPECT_THAT(actual, HasSubstr(
+    "-keepclassmembers class * { *** on_click(android.view.MenuItem); }"));
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(android.content.Context); }"));
   EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Baz { <init>(android.content.Context); }"));
   EXPECT_THAT(actual, Not(HasSubstr("com.foo.Bat")));
@@ -287,10 +334,12 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), transition.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr(
-      "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
+    "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
 }
 
 TEST(ProguardRulesTest, TransitionRulesAreEmitted) {
@@ -304,10 +353,12 @@
   proguard::KeepSet set;
   ASSERT_TRUE(proguard::CollectProguardRules(context.get(), transitionSet.get(), &set));
 
-  std::string actual = GetKeepSetString(set);
+  std::string actual = GetKeepSetString(set, /** minimal_rules */ false);
+  EXPECT_THAT(actual, HasSubstr("-keep class com.foo.Bar { <init>(...); }"));
 
+  actual = GetKeepSetString(set, /** minimal_rules */ true);
   EXPECT_THAT(actual, HasSubstr(
-      "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
+    "-keep class com.foo.Bar { <init>(android.content.Context, android.util.AttributeSet); }"));
 }
 
 }  // namespace aapt
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index f80c6e9..960c7d4 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -20,14 +20,16 @@
 
 #include "android-base/logging.h"
 
-#include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "SdkConstants.h"
 #include "ValueVisitor.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
-bool ShouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config,
+bool ShouldGenerateVersionedResource(const ResourceEntry* entry,
+                                     const ConfigDescription& config,
                                      const ApiVersion sdk_version_to_generate) {
   // We assume the caller is trying to generate a version greater than the current configuration.
   CHECK(sdk_version_to_generate > config.sdkVersion);
diff --git a/tools/aapt2/link/AutoVersioner_test.cpp b/tools/aapt2/link/AutoVersioner_test.cpp
index 49639f8..1117472 100644
--- a/tools/aapt2/link/AutoVersioner_test.cpp
+++ b/tools/aapt2/link/AutoVersioner_test.cpp
@@ -16,9 +16,11 @@
 
 #include "link/Linkers.h"
 
-#include "ConfigDescription.h"
+#include "androidfw/ConfigDescription.h"
+
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
 using ::testing::NotNull;
 
 namespace aapt {
diff --git a/tools/aapt2/link/Linkers.h b/tools/aapt2/link/Linkers.h
index 3c9c476..c9b8d39 100644
--- a/tools/aapt2/link/Linkers.h
+++ b/tools/aapt2/link/Linkers.h
@@ -21,6 +21,7 @@
 #include <unordered_set>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
 #include "Resource.h"
@@ -32,7 +33,6 @@
 
 class ResourceTable;
 class ResourceEntry;
-struct ConfigDescription;
 
 // Defines the context in which a resource value is defined. Most resources are defined with the
 // implicit package name of their compilation context. Understanding the package name of a resource
@@ -43,12 +43,14 @@
 
 // Determines whether a versioned resource should be created. If a versioned resource already
 // exists, it takes precedence.
-bool ShouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config,
+bool ShouldGenerateVersionedResource(const ResourceEntry* entry,
+                                     const android::ConfigDescription& config,
                                      const ApiVersion sdk_version_to_generate);
 
 // Finds the next largest ApiVersion of the config which is identical to the given config except
 // for sdkVersion.
-ApiVersion FindNextApiVersionForConfig(const ResourceEntry* entry, const ConfigDescription& config);
+ApiVersion FindNextApiVersionForConfig(const ResourceEntry* entry,
+                                       const android::ConfigDescription& config);
 
 class AutoVersioner : public IResourceTableConsumer {
  public:
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index fa6538d..85bf6f2 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -393,6 +393,10 @@
   uses_static_library_action.Action(RequiredAndroidAttribute("certDigest"));
   uses_static_library_action["additional-certificate"];
 
+  xml::XmlNodeAction& uses_package_action = application_action["uses-package"];
+  uses_package_action.Action(RequiredNameIsJavaPackage);
+  uses_package_action["additional-certificate"];
+
   if (options_.debug_mode) {
     application_action.Action([&](xml::Element* el) -> bool {
       xml::Attribute *attr = el->FindOrCreateAttribute(xml::kSchemaAndroid, "debuggable");
diff --git a/tools/aapt2/link/NoDefaultResourceRemover.cpp b/tools/aapt2/link/NoDefaultResourceRemover.cpp
index 5173b85..05990de 100644
--- a/tools/aapt2/link/NoDefaultResourceRemover.cpp
+++ b/tools/aapt2/link/NoDefaultResourceRemover.cpp
@@ -14,12 +14,16 @@
  * limitations under the License.
  */
 
+#include "androidfw/Locale.h"
+
 #include "link/NoDefaultResourceRemover.h"
 
 #include <algorithm>
 
 #include "ResourceTable.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
 static bool KeepResource(const std::unique_ptr<ResourceEntry>& entry, int minSdk) {
diff --git a/tools/aapt2/link/ProductFilter_test.cpp b/tools/aapt2/link/ProductFilter_test.cpp
index 86dd56a..dd47674 100644
--- a/tools/aapt2/link/ProductFilter_test.cpp
+++ b/tools/aapt2/link/ProductFilter_test.cpp
@@ -18,6 +18,8 @@
 
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 TEST(ProductFilterTest, SelectTwoProducts) {
diff --git a/tools/aapt2/optimize/MultiApkGenerator.cpp b/tools/aapt2/optimize/MultiApkGenerator.cpp
index e92c121..8c9c434 100644
--- a/tools/aapt2/optimize/MultiApkGenerator.cpp
+++ b/tools/aapt2/optimize/MultiApkGenerator.cpp
@@ -20,6 +20,7 @@
 #include <regex>
 #include <string>
 
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 
 #include "LoadedApk.h"
@@ -44,6 +45,7 @@
 using ::aapt::configuration::OutputArtifact;
 using ::aapt::xml::kSchemaAndroid;
 using ::aapt::xml::XmlResource;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 
 /**
diff --git a/tools/aapt2/optimize/MultiApkGenerator.h b/tools/aapt2/optimize/MultiApkGenerator.h
index c858879..4a5a6c3d 100644
--- a/tools/aapt2/optimize/MultiApkGenerator.h
+++ b/tools/aapt2/optimize/MultiApkGenerator.h
@@ -22,6 +22,8 @@
 #include <unordered_set>
 #include <vector>
 
+#include "androidfw/ConfigDescription.h"
+
 #include "Diagnostics.h"
 #include "LoadedApk.h"
 #include "configuration/ConfigurationParser.h"
@@ -66,7 +68,7 @@
   /**
    * Adds the <screen> elements to the parent node for the provided density configuration.
    */
-  void AddScreens(const ConfigDescription& config, xml::Element* parent);
+  void AddScreens(const android::ConfigDescription& config, xml::Element* parent);
 
   LoadedApk* apk_;
   IAaptContext* context_;
diff --git a/tools/aapt2/optimize/MultiApkGenerator_test.cpp b/tools/aapt2/optimize/MultiApkGenerator_test.cpp
index 80eb737..7d87eb8 100644
--- a/tools/aapt2/optimize/MultiApkGenerator_test.cpp
+++ b/tools/aapt2/optimize/MultiApkGenerator_test.cpp
@@ -31,6 +31,8 @@
 #include "test/Context.h"
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 namespace {
 
diff --git a/tools/aapt2/optimize/ResourceDeduper.cpp b/tools/aapt2/optimize/ResourceDeduper.cpp
index 9d16268..ee2dfbc 100644
--- a/tools/aapt2/optimize/ResourceDeduper.cpp
+++ b/tools/aapt2/optimize/ResourceDeduper.cpp
@@ -21,6 +21,8 @@
 #include "DominatorTree.h"
 #include "ResourceTable.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
 namespace {
diff --git a/tools/aapt2/optimize/ResourceDeduper_test.cpp b/tools/aapt2/optimize/ResourceDeduper_test.cpp
index d9f384c0..2e098ae 100644
--- a/tools/aapt2/optimize/ResourceDeduper_test.cpp
+++ b/tools/aapt2/optimize/ResourceDeduper_test.cpp
@@ -20,6 +20,7 @@
 #include "test/Test.h"
 
 using ::aapt::test::HasValue;
+using ::android::ConfigDescription;
 using ::testing::Not;
 
 namespace aapt {
diff --git a/tools/aapt2/optimize/ResourceFilter_test.cpp b/tools/aapt2/optimize/ResourceFilter_test.cpp
index 800b2bf..ef57f9c 100644
--- a/tools/aapt2/optimize/ResourceFilter_test.cpp
+++ b/tools/aapt2/optimize/ResourceFilter_test.cpp
@@ -20,6 +20,7 @@
 #include "test/Test.h"
 
 using ::aapt::test::HasValue;
+using ::android::ConfigDescription;
 using ::testing::Not;
 
 namespace aapt {
diff --git a/tools/aapt2/optimize/VersionCollapser.cpp b/tools/aapt2/optimize/VersionCollapser.cpp
index cc1fc1e..f985604 100644
--- a/tools/aapt2/optimize/VersionCollapser.cpp
+++ b/tools/aapt2/optimize/VersionCollapser.cpp
@@ -21,6 +21,8 @@
 
 #include "ResourceTable.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 
 template <typename Iterator, typename Pred>
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index 70efbf5..a844a43 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -21,15 +21,16 @@
 #include "android-base/logging.h"
 #include "android-base/stringprintf.h"
 #include "androidfw/AssetManager.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/ResourceTypes.h"
 
-#include "ConfigDescription.h"
 #include "NameMangler.h"
 #include "Resource.h"
 #include "ResourceUtils.h"
 #include "ValueVisitor.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 using ::android::StringPiece16;
 
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index b5c33062..414758e 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -24,11 +24,13 @@
 #include <vector>
 
 #include "android-base/logging.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "util/Util.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 using ConfigClaimedMap = std::unordered_map<ResourceConfigValue*, bool>;
diff --git a/tools/aapt2/split/TableSplitter.h b/tools/aapt2/split/TableSplitter.h
index ed24bc39..cb1395f 100644
--- a/tools/aapt2/split/TableSplitter.h
+++ b/tools/aapt2/split/TableSplitter.h
@@ -20,8 +20,8 @@
 #include <set>
 #include <vector>
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 
-#include "ConfigDescription.h"
 #include "ResourceTable.h"
 #include "filter/ConfigFilter.h"
 #include "process/IResourceTableConsumer.h"
@@ -29,7 +29,7 @@
 namespace aapt {
 
 struct SplitConstraints {
-  std::set<ConfigDescription> configs;
+  std::set<android::ConfigDescription> configs;
   std::string name;
 };
 
diff --git a/tools/aapt2/split/TableSplitter_test.cpp b/tools/aapt2/split/TableSplitter_test.cpp
index d52f4b44..cdf0738 100644
--- a/tools/aapt2/split/TableSplitter_test.cpp
+++ b/tools/aapt2/split/TableSplitter_test.cpp
@@ -18,6 +18,8 @@
 
 #include "test/Test.h"
 
+using ::android::ConfigDescription;
+
 namespace aapt {
 
 TEST(TableSplitterTest, NoSplitPreferredDensity) {
diff --git a/tools/aapt2/test/Builders.cpp b/tools/aapt2/test/Builders.cpp
index c4eab12..f33ae31 100644
--- a/tools/aapt2/test/Builders.cpp
+++ b/tools/aapt2/test/Builders.cpp
@@ -28,6 +28,7 @@
 using ::aapt::configuration::ConfiguredArtifact;
 using ::aapt::configuration::GetOrCreateGroup;
 using ::aapt::io::StringInputStream;
+using ::android::ConfigDescription;
 using ::android::StringPiece;
 
 namespace aapt {
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index be6e510..9159599 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -20,6 +20,7 @@
 #include <memory>
 
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 
 #include "Resource.h"
 #include "ResourceTable.h"
@@ -40,7 +41,8 @@
 
   ResourceTableBuilder& SetPackageId(const android::StringPiece& package_name, uint8_t id);
   ResourceTableBuilder& AddSimple(const android::StringPiece& name, const ResourceId& id = {});
-  ResourceTableBuilder& AddSimple(const android::StringPiece& name, const ConfigDescription& config,
+  ResourceTableBuilder& AddSimple(const android::StringPiece& name,
+                                  const android::ConfigDescription& config,
                                   const ResourceId& id = {});
   ResourceTableBuilder& AddReference(const android::StringPiece& name,
                                      const android::StringPiece& ref);
@@ -51,7 +53,8 @@
   ResourceTableBuilder& AddString(const android::StringPiece& name, const ResourceId& id,
                                   const android::StringPiece& str);
   ResourceTableBuilder& AddString(const android::StringPiece& name, const ResourceId& id,
-                                  const ConfigDescription& config, const android::StringPiece& str);
+                                  const android::ConfigDescription& config,
+                                  const android::StringPiece& str);
   ResourceTableBuilder& AddFileReference(const android::StringPiece& name,
                                          const android::StringPiece& path,
                                          io::IFile* file = nullptr);
@@ -60,12 +63,13 @@
                                          io::IFile* file = nullptr);
   ResourceTableBuilder& AddFileReference(const android::StringPiece& name,
                                          const android::StringPiece& path,
-                                         const ConfigDescription& config,
+                                         const android::ConfigDescription& config,
                                          io::IFile* file = nullptr);
   ResourceTableBuilder& AddValue(const android::StringPiece& name, std::unique_ptr<Value> value);
   ResourceTableBuilder& AddValue(const android::StringPiece& name, const ResourceId& id,
                                  std::unique_ptr<Value> value);
-  ResourceTableBuilder& AddValue(const android::StringPiece& name, const ConfigDescription& config,
+  ResourceTableBuilder& AddValue(const android::StringPiece& name,
+                                 const android::ConfigDescription& config,
                                  const ResourceId& id, std::unique_ptr<Value> value);
   ResourceTableBuilder& SetSymbolState(const android::StringPiece& name, const ResourceId& id,
                                        Visibility::Level level, bool allow_new = false);
@@ -163,8 +167,8 @@
   ArtifactBuilder& SetName(const std::string& name);
   ArtifactBuilder& SetVersion(int version);
   ArtifactBuilder& AddAbi(configuration::Abi abi);
-  ArtifactBuilder& AddDensity(const ConfigDescription& density);
-  ArtifactBuilder& AddLocale(const ConfigDescription& locale);
+  ArtifactBuilder& AddDensity(const android::ConfigDescription& density);
+  ArtifactBuilder& AddLocale(const android::ConfigDescription& locale);
   ArtifactBuilder& SetAndroidSdk(int min_sdk);
   configuration::OutputArtifact Build();
 
@@ -302,12 +306,12 @@
     config_.screenConfigPad2 = screenConfigPad2;
     return *this;
   }
-  ConfigDescription Build() {
+  android::ConfigDescription Build() {
     return config_;
   }
 
  private:
-  ConfigDescription config_;
+  android::ConfigDescription config_;
 };
 
 }  // namespace test
diff --git a/tools/aapt2/test/Common.cpp b/tools/aapt2/test/Common.cpp
index 0fabbc4..b54c155 100644
--- a/tools/aapt2/test/Common.cpp
+++ b/tools/aapt2/test/Common.cpp
@@ -16,6 +16,8 @@
 
 #include "test/Common.h"
 
+using android::ConfigDescription;
+
 namespace aapt {
 namespace test {
 
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index aca161a..50b41f1 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -21,11 +21,11 @@
 
 #include "android-base/logging.h"
 #include "android-base/macros.h"
+#include "androidfw/ConfigDescription.h"
 #include "androidfw/StringPiece.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-#include "ConfigDescription.h"
 #include "Debug.h"
 #include "ResourceTable.h"
 #include "ResourceUtils.h"
@@ -45,15 +45,15 @@
   return ref.ToResourceName();
 }
 
-inline ConfigDescription ParseConfigOrDie(const android::StringPiece& str) {
-  ConfigDescription config;
-  CHECK(ConfigDescription::Parse(str, &config)) << "invalid configuration: " << str;
+inline android::ConfigDescription ParseConfigOrDie(const android::StringPiece& str) {
+    android::ConfigDescription config;
+  CHECK(android::ConfigDescription::Parse(str, &config)) << "invalid configuration: " << str;
   return config;
 }
 
 template <typename T = Value>
 T* GetValueForConfigAndProduct(ResourceTable* table, const android::StringPiece& res_name,
-                               const ConfigDescription& config,
+                               const android::ConfigDescription& config,
                                const android::StringPiece& product) {
   Maybe<ResourceTable::SearchResult> result = table->FindResource(ParseNameOrDie(res_name));
   if (result) {
@@ -68,12 +68,12 @@
 template <>
 Value* GetValueForConfigAndProduct<Value>(ResourceTable* table,
                                           const android::StringPiece& res_name,
-                                          const ConfigDescription& config,
+                                          const android::ConfigDescription& config,
                                           const android::StringPiece& product);
 
 template <typename T = Value>
 T* GetValueForConfig(ResourceTable* table, const android::StringPiece& res_name,
-                     const ConfigDescription& config) {
+                     const android::ConfigDescription& config) {
   return GetValueForConfigAndProduct<T>(table, res_name, config, {});
 }
 
diff --git a/tools/aapt2/util/Files_test.cpp b/tools/aapt2/util/Files_test.cpp
index 219c183..202cc26 100644
--- a/tools/aapt2/util/Files_test.cpp
+++ b/tools/aapt2/util/Files_test.cpp
@@ -18,11 +18,21 @@
 
 #include <sstream>
 
+#include "android-base/stringprintf.h"
+
 #include "test/Test.h"
 
+using ::android::base::StringPrintf;
+
 namespace aapt {
 namespace file {
 
+#ifdef _WIN32
+constexpr const char sTestDirSep = '\\';
+#else
+constexpr const char sTestDirSep = '/';
+#endif
+
 class FilesTest : public ::testing::Test {
  public:
   void SetUp() override {
@@ -42,16 +52,16 @@
 }
 
 TEST_F(FilesTest, AppendPathWithLeadingOrTrailingSeparators) {
-  std::string base = "hello/";
+  std::string base = StringPrintf("hello%c", sTestDirSep);
   AppendPath(&base, "there");
   EXPECT_EQ(expected_path_, base);
 
   base = "hello";
-  AppendPath(&base, "/there");
+  AppendPath(&base, StringPrintf("%cthere", sTestDirSep));
   EXPECT_EQ(expected_path_, base);
 
-  base = "hello/";
-  AppendPath(&base, "/there");
+  base = StringPrintf("hello%c", sTestDirSep);
+  AppendPath(&base, StringPrintf("%cthere", sTestDirSep));
   EXPECT_EQ(expected_path_, base);
 }
 
diff --git a/tools/hiddenapi/merge_csv.py b/tools/hiddenapi/merge_csv.py
new file mode 100755
index 0000000..48c0755
--- /dev/null
+++ b/tools/hiddenapi/merge_csv.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+#
+# 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.
+"""
+Merge mutliple CSV files, possibly with different columns, writing to stdout.
+"""
+
+import csv
+import sys
+
+csv_readers = [
+    csv.DictReader(open(csv_file, 'rb'), delimiter=',', quotechar='|')
+    for csv_file in sys.argv[1:]
+]
+
+# Build union of all columns from source files:
+headers = set()
+for reader in csv_readers:
+  headers = headers.union(reader.fieldnames)
+
+# Concatenate all files to output:
+out = csv.DictWriter(sys.stdout, delimiter=',', quotechar='|', fieldnames = sorted(headers))
+out.writeheader()
+for reader in csv_readers:
+  for row in reader:
+    out.writerow(row)
+
+
diff --git a/tools/hiddenapi/sort_api.sh b/tools/hiddenapi/sort_api.sh
index 76a2f2d..710da40 100755
--- a/tools/hiddenapi/sort_api.sh
+++ b/tools/hiddenapi/sort_api.sh
@@ -21,4 +21,6 @@
 A=( ${C[*]} ${A[*]} )
 unset IFS
 # Dump array back into the file
-printf '%s\n' "${A[@]}" > "$dest_list"
+if [ ${#A[@]} -ne 0 ]; then
+  printf '%s\n' "${A[@]}" > "$dest_list"
+fi
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index 4245700..257043b 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -47,7 +47,8 @@
       fields(that.fields),
       primaryFields(that.primaryFields),
       exclusiveField(that.exclusiveField),
-      uidField(that.uidField) {}
+      uidField(that.uidField),
+      binaryFields(that.binaryFields) {}
 
 AtomDecl::AtomDecl(int c, const string& n, const string& m)
     :code(c),
@@ -119,6 +120,9 @@
             } else if (field->message_type()->full_name() ==
                        "android.os.statsd.KeyValuePair") {
               return JAVA_TYPE_KEY_VALUE_PAIR;
+            } else if (field->options().GetExtension(os::statsd::log_mode) ==
+                       os::statsd::LogMode::MODE_BYTES) {
+                return JAVA_TYPE_BYTE_ARRAY;
             } else {
                 return JAVA_TYPE_OBJECT;
             }
@@ -188,6 +192,8 @@
   for (map<int, const FieldDescriptor *>::const_iterator it = fields.begin();
        it != fields.end(); it++) {
     const FieldDescriptor *field = it->second;
+    bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
+                         os::statsd::LogMode::MODE_BYTES;
 
     java_type_t javaType = java_type(field);
 
@@ -197,17 +203,24 @@
       continue;
     } else if (javaType == JAVA_TYPE_OBJECT &&
                atomDecl->code < PULL_ATOM_START_ID) {
-      // Allow attribution chain, but only at position 1.
-      print_error(field,
-                  "Message type not allowed for field in pushed atoms: %s\n",
-                  field->name().c_str());
-      errorCount++;
-      continue;
-    } else if (javaType == JAVA_TYPE_BYTE_ARRAY) {
-      print_error(field, "Raw bytes type not allowed for field: %s\n",
-                  field->name().c_str());
-      errorCount++;
-      continue;
+        // Allow attribution chain, but only at position 1.
+        print_error(field,
+                    "Message type not allowed for field in pushed atoms: %s\n",
+                    field->name().c_str());
+        errorCount++;
+        continue;
+    } else if (javaType == JAVA_TYPE_BYTE_ARRAY && !isBinaryField) {
+        print_error(field, "Raw bytes type not allowed for field: %s\n",
+                    field->name().c_str());
+        errorCount++;
+        continue;
+    }
+
+    if (isBinaryField && javaType != JAVA_TYPE_BYTE_ARRAY) {
+        print_error(field, "Cannot mark field %s as bytes.\n",
+                    field->name().c_str());
+        errorCount++;
+        continue;
     }
   }
 
@@ -233,6 +246,8 @@
        it != fields.end(); it++) {
     const FieldDescriptor *field = it->second;
     java_type_t javaType = java_type(field);
+    bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
+                         os::statsd::LogMode::MODE_BYTES;
 
     AtomField atField(field->name(), javaType);
     // Generate signature for pushed atoms
@@ -241,8 +256,10 @@
         // All enums are treated as ints when it comes to function signatures.
         signature->push_back(JAVA_TYPE_INT);
         collate_enums(*field->enum_type(), &atField);
+      } else if (javaType == JAVA_TYPE_OBJECT && isBinaryField) {
+          signature->push_back(JAVA_TYPE_BYTE_ARRAY);
       } else {
-        signature->push_back(javaType);
+          signature->push_back(javaType);
       }
     }
     if (javaType == JAVA_TYPE_ENUM) {
@@ -251,7 +268,7 @@
     }
     atomDecl->fields.push_back(atField);
 
-    if (field->options().GetExtension(os::statsd::stateFieldOption).option() ==
+    if (field->options().GetExtension(os::statsd::state_field_option).option() ==
         os::statsd::StateField::PRIMARY) {
         if (javaType == JAVA_TYPE_UNKNOWN ||
             javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
@@ -261,7 +278,7 @@
         atomDecl->primaryFields.push_back(it->first);
     }
 
-    if (field->options().GetExtension(os::statsd::stateFieldOption).option() ==
+    if (field->options().GetExtension(os::statsd::state_field_option).option() ==
         os::statsd::StateField::EXCLUSIVE) {
         if (javaType == JAVA_TYPE_UNKNOWN ||
             javaType == JAVA_TYPE_ATTRIBUTION_CHAIN ||
@@ -287,6 +304,10 @@
             errorCount++;
         }
     }
+    // Binary field validity is already checked above.
+    if (isBinaryField) {
+        atomDecl->binaryFields.push_back(it->first);
+    }
   }
 
   return errorCount;
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 31b8b07..450b305 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -89,6 +89,8 @@
 
     int uidField = 0;
 
+    vector<int> binaryFields;
+
     AtomDecl();
     AtomDecl(const AtomDecl& that);
     AtomDecl(int code, const string& name, const string& message);
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 56c8428..1ef34b9 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -66,6 +66,8 @@
             return "double";
         case JAVA_TYPE_STRING:
             return "char const*";
+        case JAVA_TYPE_BYTE_ARRAY:
+            return "char const*";
         default:
             return "UNKNOWN";
     }
@@ -88,6 +90,8 @@
             return "double";
         case JAVA_TYPE_STRING:
             return "java.lang.String";
+        case JAVA_TYPE_BYTE_ARRAY:
+            return "byte[]";
         default:
             return "UNKNOWN";
     }
@@ -198,13 +202,40 @@
     }
 
     fprintf(out, "    return options;\n");
-    fprintf(out, "  }\n");
+    fprintf(out, "}\n");
 
     fprintf(out,
             "const std::map<int, StateAtomFieldOptions> "
             "AtomsInfo::kStateAtomsFieldOptions = "
             "getStateAtomFieldOptions();\n");
 
+    fprintf(out,
+            "static std::map<int, std::vector<int>> "
+            "getBinaryFieldAtoms() {\n");
+    fprintf(out, "    std::map<int, std::vector<int>> options;\n");
+    for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+         atom != atoms.decls.end(); atom++) {
+        if (atom->binaryFields.size() == 0) {
+            continue;
+        }
+        fprintf(out,
+                "\n    // Adding binary fields for atom "
+                "(%d)%s\n",
+                atom->code, atom->name.c_str());
+
+        for (const auto& field : atom->binaryFields) {
+            fprintf(out, "    options[static_cast<int>(%s)].push_back(%d);\n",
+                    make_constant_name(atom->name).c_str(), field);
+        }
+    }
+
+    fprintf(out, "    return options;\n");
+    fprintf(out, "}\n");
+
+    fprintf(out,
+            "const std::map<int, std::vector<int>> "
+            "AtomsInfo::kBytesFieldAtoms = "
+            "getBinaryFieldAtoms();\n");
 
     fprintf(out, "int64_t lastRetryTimestampNs = -1;\n");
     fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n");
@@ -664,6 +695,9 @@
     fprintf(out,
             "  const static std::map<int, StateAtomFieldOptions> "
             "kStateAtomsFieldOptions;\n");
+    fprintf(out,
+            "  const static std::map<int, std::vector<int>> "
+            "kBytesFieldAtoms;");
     fprintf(out, "};\n");
 
     fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
@@ -698,6 +732,8 @@
             fprintf(out, ", android.os.WorkSource workSource");
         } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
             fprintf(out, ", SparseArray<Object> value_map");
+        } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
+            fprintf(out, ", byte[] %s", field->name.c_str());
         } else {
             fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str());
         }
@@ -890,6 +926,8 @@
             return "jdouble";
         case JAVA_TYPE_STRING:
             return "jstring";
+        case JAVA_TYPE_BYTE_ARRAY:
+            return "jbyteArray";
         default:
             return "UNKNOWN";
     }
@@ -942,6 +980,9 @@
             case JAVA_TYPE_KEY_VALUE_PAIR:
               result += "_KeyValuePairs";
               break;
+            case JAVA_TYPE_BYTE_ARRAY:
+                result += "_bytes";
+                break;
             default:
                 result += "_UNKNOWN";
                 break;
@@ -967,6 +1008,8 @@
             return "D";
         case JAVA_TYPE_STRING:
             return "Ljava/lang/String;";
+        case JAVA_TYPE_BYTE_ARRAY:
+            return "[B";
         default:
             return "UNKNOWN";
     }
@@ -1081,6 +1124,25 @@
                 fprintf(out, "    } else {\n");
                 fprintf(out, "        str%d = NULL;\n", argIndex);
                 fprintf(out, "    }\n");
+            } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+                hadStringOrChain = true;
+                fprintf(out, "    jbyte* jbyte_array%d;\n", argIndex);
+                fprintf(out, "    const char* str%d;\n", argIndex);
+                fprintf(out, "    if (arg%d != NULL) {\n", argIndex);
+                fprintf(out,
+                        "        jbyte_array%d = "
+                        "env->GetByteArrayElements(arg%d, NULL);\n",
+                        argIndex, argIndex);
+                fprintf(out,
+                        "        str%d = "
+                        "reinterpret_cast<char*>(env->GetByteArrayElements(arg%"
+                        "d, NULL));\n",
+                        argIndex, argIndex);
+                fprintf(out, "    } else {\n");
+                fprintf(out, "        jbyte_array%d = NULL;\n", argIndex);
+                fprintf(out, "        str%d = NULL;\n", argIndex);
+                fprintf(out, "    }\n");
+
             } else if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 hadStringOrChain = true;
                 for (auto chainField : attributionDecl.fields) {
@@ -1154,7 +1216,10 @@
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
                 fprintf(out, ", int32_t_map, int64_t_map, string_map, float_map");
             } else {
-                const char *argName = (*arg == JAVA_TYPE_STRING) ? "str" : "arg";
+                const char* argName = (*arg == JAVA_TYPE_STRING ||
+                                       *arg == JAVA_TYPE_BYTE_ARRAY)
+                                              ? "str"
+                                              : "arg";
                 fprintf(out, ", (%s)%s%d", cpp_type_name(*arg), argName, argIndex);
             }
             argIndex++;
@@ -1171,6 +1236,13 @@
                 fprintf(out, "        env->ReleaseStringUTFChars(arg%d, str%d);\n",
                         argIndex, argIndex);
                 fprintf(out, "    }\n");
+            } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+                fprintf(out, "    if (str%d != NULL) { \n", argIndex);
+                fprintf(out,
+                        "        env->ReleaseByteArrayElements(arg%d, "
+                        "jbyte_array%d, 0);\n",
+                        argIndex, argIndex);
+                fprintf(out, "    }\n");
             } else if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
                 for (auto chainField : attributionDecl.fields) {
                     if (chainField.javaType == JAVA_TYPE_INT) {
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 264a865..3be87d9 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -109,6 +109,28 @@
   oneof event { BadAttributionNodePositionAtom bad = 1; }
 }
 
+message GoodEventWithBinaryFieldAtom {
+    oneof event { GoodBinaryFieldAtom field1 = 1; }
+}
+
+message ComplexField {
+    optional string str = 1;
+}
+
+message GoodBinaryFieldAtom {
+    optional int32 field1 = 1;
+    optional ComplexField bf = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
+}
+
+message BadEventWithBinaryFieldAtom {
+    oneof event { BadBinaryFieldAtom field1 = 1; }
+}
+
+message BadBinaryFieldAtom {
+    optional int32 field1 = 1;
+    optional ComplexField bf = 2;
+}
+
 message BadStateAtoms {
     oneof event {
         BadStateAtom1 bad1 = 1;
@@ -127,33 +149,33 @@
 // The atom has only primary field but no exclusive state field.
 message BadStateAtom1 {
     optional int32 uid = 1
-            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+            [(android.os.statsd.state_field_option).option = PRIMARY];
 }
 
 // Only primative types can be annotated.
 message BadStateAtom2 {
     repeated android.os.statsd.AttributionNode attribution = 1
-            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+            [(android.os.statsd.state_field_option).option = PRIMARY];
     optional int32 state = 2
-            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+            [(android.os.statsd.state_field_option).option = EXCLUSIVE];
 }
 
 // Having 2 exclusive state field in the atom means the atom is badly designed.
 // E.g., putting bluetooth state and wifi state in the same atom.
 message BadStateAtom3 {
     optional int32 uid = 1
-            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+            [(android.os.statsd.state_field_option).option = PRIMARY];
     optional int32 state = 2
-            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+            [(android.os.statsd.state_field_option).option = EXCLUSIVE];
     optional int32 state2 = 3
-            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+            [(android.os.statsd.state_field_option).option = EXCLUSIVE];
 }
 
 message GoodStateAtom1 {
     optional int32 uid = 1
-            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+            [(android.os.statsd.state_field_option).option = PRIMARY];
     optional int32 state = 2
-            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+            [(android.os.statsd.state_field_option).option = EXCLUSIVE];
 }
 
 // Atoms can have exclusive state field, but no primary field. That means
@@ -161,16 +183,16 @@
 message GoodStateAtom2 {
     optional int32 uid = 1;
     optional int32 state = 2
-            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+            [(android.os.statsd.state_field_option).option = EXCLUSIVE];
 }
 
 // We can have more than one primary fields. That means their combination is a
 // primary key.
 message GoodStateAtom3 {
     optional int32 uid = 1
-            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+            [(android.os.statsd.state_field_option).option = PRIMARY];
     optional int32 tid = 2
-            [(android.os.statsd.stateFieldOption).option = PRIMARY];
+            [(android.os.statsd.state_field_option).option = PRIMARY];
     optional int32 state = 3
-            [(android.os.statsd.stateFieldOption).option = EXCLUSIVE];
+            [(android.os.statsd.state_field_option).option = EXCLUSIVE];
 }
\ No newline at end of file
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index 1936d96..ad3bffac 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -212,5 +212,19 @@
     EXPECT_EQ(0, errorCount);
 }
 
+TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
+    Atoms atoms;
+    int errorCount =
+            collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), &atoms);
+    EXPECT_EQ(0, errorCount);
+}
+
+TEST(CollationTest, FailOnBadBinaryFieldAtom) {
+    Atoms atoms;
+    int errorCount =
+            collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), &atoms);
+    EXPECT_TRUE(errorCount > 0);
+}
+
 }  // namespace stats_log_api_gen
 }  // namespace android
\ No newline at end of file
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 58c1300..7472278 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -513,7 +513,7 @@
     /**
      * @hide
      * Universal name for app creating the configuration
-     *    see {#link {@link PackageManager#getNameForUid(int)}
+     *    see {@link PackageManager#getNameForUid(int)}
      */
     @SystemApi
     public String creatorName;
@@ -521,7 +521,7 @@
     /**
      * @hide
      * Universal name for app updating the configuration
-     *    see {#link {@link PackageManager#getNameForUid(int)}
+     *    see {@link PackageManager#getNameForUid(int)}
      */
     @SystemApi
     public String lastUpdateName;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 59ba8e7..9adbe67 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -3754,6 +3754,13 @@
                 mCallback.onProvisioningFailure(status);
             });
         }
+
+        @Override
+        public void onProvisioningComplete() {
+            mHandler.post(() -> {
+                mCallback.onProvisioningComplete();
+            });
+        }
     }
 
     /**
diff --git a/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java b/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java
deleted file mode 100644
index f5cad13..0000000
--- a/wifi/java/android/net/wifi/WifiWakeReasonAndCounts.java
+++ /dev/null
@@ -1,163 +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.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A class representing wifi wake reason accounting.
- */
-
-/** @hide */
-public class WifiWakeReasonAndCounts implements Parcelable {
-    private static final String TAG = "WifiWakeReasonAndCounts";
-    /**
-     * Wlan can wake host, only when it is cmd/event, local driver-fw
-     * functions(non-data, non cmd/event) and rx data.The first packet
-     * from wlan that woke up a sleep host is what is accounted here.
-     * Total wlan wake to application processor would be:
-     * [cmdEventWake + driverFwLocalWake + totalRxDataWake]
-     * A further classification is provided for identifying the reasons
-     * for wakeup.
-     */
-    public int totalCmdEventWake;
-    public int totalDriverFwLocalWake;
-    public int totalRxDataWake;
-
-    public int rxUnicast;
-    public int rxMulticast;
-    public int rxBroadcast;
-
-    public int icmp;
-    public int icmp6;
-    public int icmp6Ra;
-    public int icmp6Na;
-    public int icmp6Ns;
-
-    public int ipv4RxMulticast;
-    public int ipv6Multicast;
-    public int otherRxMulticast;
-    public int[] cmdEventWakeCntArray;
-    public int[] driverFWLocalWakeCntArray;
-
-    /* {@hide} */
-    public WifiWakeReasonAndCounts () {
-    }
-
-    @Override
-    /* {@hide} */
-    public String toString() {
-        StringBuffer sb = new StringBuffer();
-        sb.append(" totalCmdEventWake ").append(totalCmdEventWake);
-        sb.append(" totalDriverFwLocalWake ").append(totalDriverFwLocalWake);
-        sb.append(" totalRxDataWake ").append(totalRxDataWake);
-
-        sb.append(" rxUnicast ").append(rxUnicast);
-        sb.append(" rxMulticast ").append(rxMulticast);
-        sb.append(" rxBroadcast ").append(rxBroadcast);
-
-        sb.append(" icmp ").append(icmp);
-        sb.append(" icmp6 ").append(icmp6);
-        sb.append(" icmp6Ra ").append(icmp6Ra);
-        sb.append(" icmp6Na ").append(icmp6Na);
-        sb.append(" icmp6Ns ").append(icmp6Ns);
-
-        sb.append(" ipv4RxMulticast ").append(ipv4RxMulticast);
-        sb.append(" ipv6Multicast ").append(ipv6Multicast);
-        sb.append(" otherRxMulticast ").append(otherRxMulticast);
-        for (int i = 0; i < cmdEventWakeCntArray.length; i++) {
-            sb.append(" cmdEventWakeCntArray[" + i + "] " + cmdEventWakeCntArray[i]);
-        }
-        for (int i = 0; i < driverFWLocalWakeCntArray.length; i++) {
-            sb.append(" driverFWLocalWakeCntArray[" + i + "] " + driverFWLocalWakeCntArray[i]);
-        }
-
-        return sb.toString();
-    }
-
-    /* Implement the Parcelable interface
-     * {@hide}
-     */
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    /* Implement the Parcelable interface
-     * {@hide}
-     */
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(totalCmdEventWake);
-        dest.writeInt(totalDriverFwLocalWake);
-        dest.writeInt(totalRxDataWake);
-
-        dest.writeInt(rxUnicast);
-        dest.writeInt(rxMulticast);
-        dest.writeInt(rxBroadcast);
-
-        dest.writeInt(icmp);
-        dest.writeInt(icmp6);
-        dest.writeInt(icmp6Ra);
-        dest.writeInt(icmp6Na);
-        dest.writeInt(icmp6Ns);
-
-        dest.writeInt(ipv4RxMulticast);
-        dest.writeInt(ipv6Multicast);
-        dest.writeInt(otherRxMulticast);
-        dest.writeIntArray(cmdEventWakeCntArray);
-        dest.writeIntArray(driverFWLocalWakeCntArray);
-    }
-
-    /* Implement the Parcelable interface
-     * {@hide}
-     */
-    public static final Creator<WifiWakeReasonAndCounts> CREATOR =
-        new Creator<WifiWakeReasonAndCounts>() {
-            public WifiWakeReasonAndCounts createFromParcel(Parcel in) {
-                WifiWakeReasonAndCounts counts = new WifiWakeReasonAndCounts();
-                counts.totalCmdEventWake = in.readInt();
-                counts.totalDriverFwLocalWake = in.readInt();
-                counts.totalRxDataWake = in.readInt();
-
-                counts.rxUnicast = in.readInt();
-                counts.rxMulticast = in.readInt();
-                counts.rxBroadcast = in.readInt();
-
-                counts.icmp = in.readInt();
-                counts.icmp6 = in.readInt();
-                counts.icmp6Ra = in.readInt();
-                counts.icmp6Na = in.readInt();
-                counts.icmp6Ns = in.readInt();
-
-                counts.ipv4RxMulticast = in.readInt();
-                counts.ipv6Multicast = in.readInt();
-                counts.otherRxMulticast = in.readInt();
-                in.readIntArray(counts.cmdEventWakeCntArray);
-                in.readIntArray(counts.driverFWLocalWakeCntArray);
-                return counts;
-            }
-            /* Implement the Parcelable interface
-             * {@hide}
-             */
-            @Override
-            public WifiWakeReasonAndCounts[] newArray(int size) {
-                return new WifiWakeReasonAndCounts[size];
-            }
-        };
-}
diff --git a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl b/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
index c2cb16a..a6bdd5b6 100644
--- a/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
+++ b/wifi/java/android/net/wifi/hotspot2/IProvisioningCallback.aidl
@@ -32,5 +32,10 @@
      * Service to manager callback providing Provisioning status
      */
     void onProvisioningStatus(int status);
+
+    /**
+     * Service to manager callback providing completion of Provisioning/Remediation flow
+     */
+    void onProvisioningComplete();
 }
 
diff --git a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
index b4dfac6..4b76526 100644
--- a/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
+++ b/wifi/java/android/net/wifi/hotspot2/ProvisioningCallback.java
@@ -102,6 +102,54 @@
     public static final int OSU_FAILURE_NO_OSU_ACTIVITY_FOUND = 14;
 
     /**
+     * The reason code for provisioning failure when the status of a SOAP message is not the
+     * expected message status.
+     */
+    public static final int OSU_FAILURE_UNEXPECTED_SOAP_MESSAGE_STATUS = 15;
+
+    /**
+     * The reason code for provisioning failure when there is no PPS MO.
+     * MO.
+     */
+    public static final int OSU_FAILURE_NO_PPS_MO = 16;
+
+    /**
+     * The reason code for provisioning failure when there is no AAAServerTrustRoot node in a PPS
+     * MO.
+     */
+    public static final int OSU_FAILURE_NO_AAA_SERVER_TRUST_ROOT_NODE = 17;
+
+    /**
+     * The reason code for provisioning failure when there is no TrustRoot node for remediation
+     * server in a PPS MO.
+     */
+    public static final int OSU_FAILURE_NO_REMEDIATION_SERVER_TRUST_ROOT_NODE = 18;
+
+    /**
+     * The reason code for provisioning failure when there is no TrustRoot node for policy server in
+     * a PPS MO.
+     */
+    public static final int OSU_FAILURE_NO_POLICY_SERVER_TRUST_ROOT_NODE = 19;
+
+    /**
+     * The reason code for provisioning failure when failing to retrieve trust root certificates
+     * used for validating server certificate for AAA, Remediation and Policy server.
+     */
+    public static final int OSU_FAILURE_RETRIEVE_TRUST_ROOT_CERTIFICATES = 20;
+
+    /**
+     * The reason code for provisioning failure when there is no trust root certificate for AAA
+     * server.
+     */
+    public static final int OSU_FAILURE_NO_AAA_TRUST_ROOT_CERTIFICATE = 21;
+
+    /**
+     * The reason code for provisioning failure when a {@link PasspointConfiguration} is failed to
+     * install.
+     */
+    public static final int OSU_FAILURE_ADD_PASSPOINT_CONFIGURATION = 22;
+
+    /**
      * The status code for provisioning flow to indicate connecting to OSU AP
      */
     public static final int OSU_STATUS_AP_CONNECTING = 1;
@@ -147,6 +195,17 @@
     public static final int OSU_STATUS_SECOND_SOAP_EXCHANGE = 9;
 
     /**
+     * The status code for provisioning flow to indicate starting the third SOAP exchange.
+     */
+    public static final int OSU_STATUS_THIRD_SOAP_EXCHANGE = 10;
+
+    /**
+     * The status code for provisioning flow to indicate starting a step retrieving trust root
+     * certs.
+     */
+    public static final int OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS = 11;
+
+    /**
      * Provisioning status for OSU failure
      *
      * @param status indicates error condition
@@ -159,5 +218,10 @@
      * @param status indicates status of OSU flow
      */
     public abstract void onProvisioningStatus(int status);
+
+    /**
+     * Provisioning complete when provisioning/remediation flow completes
+     */
+    public abstract void onProvisioningComplete();
 }
 
diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
index 5c9df6a..c7993e3 100644
--- a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
+++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSpTest.java
@@ -189,8 +189,7 @@
         Map<String, Long> homeNetworkIds = new HashMap<>();
         byte[] rawSsidBytes = new byte[33];
         Arrays.fill(rawSsidBytes, (byte) 'a');
-        homeNetworkIds.put(
-                StringFactory.newStringFromBytes(rawSsidBytes, StandardCharsets.UTF_8), 0x1234L);
+        homeNetworkIds.put(new String(rawSsidBytes, StandardCharsets.UTF_8), 0x1234L);
         homeSp.setHomeNetworkIds(homeNetworkIds);
         assertFalse(homeSp.validate());
     }